diff --git a/Doxyfile.in b/Doxyfile.in index 8727594771..1068c9b7ba 100644 --- a/Doxyfile.in +++ b/Doxyfile.in @@ -290,6 +290,7 @@ INCLUDE_FILE_PATTERNS = PREDEFINED = WITH_ZLIB \ WITH_LZO \ WITH_LIBLZMA \ + WITH_ZSTD \ WITH_SDL \ WITH_PNG \ WITH_FONTCONFIG \ diff --git a/config.lib b/config.lib new file mode 100644 index 0000000000..0751f00185 --- /dev/null +++ b/config.lib @@ -0,0 +1,3609 @@ +# 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 . + +log() { + if [ $1 = "1" ]; then + shift + echo "$@" + else + shift + fi + echo "$@" >> $config_log +} + +set_default() { + ignore_extra_parameters="0" + # We set all kinds of defaults for params. Later on the user can override + # most of them; but if they don't, this default is used. + build="" + host="" + cc_build="" + cc_host="" + cxx_build="" + cxx_host="" + windres="" + strip="" + lipo="" + awk="awk" + pkg_config="pkg-config" + os="DETECT" + cpu_type="DETECT" + config_log="config.log" + prefix_dir="/usr/local" + binary_dir="games" + data_dir="share/games/openttd" + doc_dir="1" + icon_dir="share/pixmaps" + icon_theme_dir="1" + personal_dir="1" + shared_dir="1" + install_dir="/" + man_dir="1" + menu_dir="1" + menu_group="Game;" + menu_name="OpenTTD" + binary_name="openttd" + enable_debug="0" + enable_desync_debug="0" + enable_profiling="0" + enable_lto="0" + enable_dedicated="0" + enable_static="1" + enable_translator="0" + enable_unicode="1" + enable_console="1"; + enable_assert="0" + enable_strip="1" + enable_universal="0" + enable_osx_g5="0" + enable_cocoa_quartz="1" + enable_cocoa_quickdraw="1" + with_osx_sysroot="1" + with_application_bundle="1" + with_menu_entry="1" + with_allegro="1" + with_sdl="1" + with_cocoa="1" + with_zlib="1" + with_lzma="1" + with_zstd="1" + with_lzo2="1" + with_xdg_basedir="1" + with_png="1" + enable_builtin_depend="1" + with_makedepend="0" + with_direct_music="1" + with_xaudio2="1" + with_sort="1" + with_iconv="1" + with_midi="" + with_midi_arg="" + with_fluidsynth="1" + with_freetype="1" + with_fontconfig="1" + with_icu_layout="1" + with_icu_sort="1" + static_icu="0" + with_uniscribe="1" + with_threads="1" + with_distcc="1" + with_ccache="1" + with_nforenum="1" + with_grfcodec="1" + with_sse="1" + + save_params_array=" + build + host + cc_build + cc_host + cxx_build + cxx_host + windres + strip + lipo + awk + pkg_config + os + cpu_type + config_log + prefix_dir + binary_dir + data_dir + doc_dir + icon_dir + icon_theme_dir + man_dir + menu_dir + personal_dir + shared_dir + install_dir + menu_group + menu_name + binary_name + enable_debug + enable_desync_debug + enable_profiling + enable_lto + enable_dedicated + enable_static + enable_translator + enable_unicode + enable_console + enable_assert + enable_strip + enable_universal + enable_osx_g5 + enable_cocoa_quartz + enable_cocoa_quickdraw + with_osx_sysroot + with_application_bundle + with_allegro + with_sdl + with_cocoa + with_zlib + with_lzma + with_lzo2 + with_xdg_basedir + with_png + enable_builtin_depend + with_makedepend + with_direct_music + with_xaudio2 + with_sort + with_iconv + with_midi + with_midi_arg + with_fluidsynth + with_freetype + with_fontconfig + with_icu_layout + with_icu_sort + static_icu + with_uniscribe + with_threads + with_distcc + with_ccache + with_grfcodec + with_nforenum + with_sse + CC CXX CFLAGS CXXFLAGS LDFLAGS CFLAGS_BUILD CXXFLAGS_BUILD LDFLAGS_BUILD PKG_CONFIG_PATH PKG_CONFIG_LIBDIR" +} + +detect_params() { + # Walk over all params from the user and override any default settings if + # needed. This also handles any invalid option. + for p in "$@"; do + if [ -n "$prev_p" ]; then + eval "$prev_p=\$p" + prev_p= + continue + fi + + optarg=`expr "x$p" : 'x[^=]*=\(.*\)'` + + case "$p" in + --help | -h | -\?) showhelp; exit 0;; + + --config-log) prev_p="config_log";; + --config-log=*) config_log="$optarg";; + + --build) prev_p="build";; + --build=*) build="$optarg";; + + --host) prev_p="host";; + --host=*) host="$optarg";; + + --os) prev_p="os";; + --os=*) os="$optarg";; + + --cpu-type) prev_p="cpu_type";; + --cpu-type=*) cpu_type="$optarg";; + + --cc-build) prev_p="cc_build";; + --cc-build=*) cc_build="$optarg";; + --cc-host) prev_p="cc_host";; + --cc-host=*) cc_host="$optarg";; + --cxx-build) prev_p="cxx_build";; + --cxx-build=*) cxx_build="$optarg";; + --cxx-host) prev_p="cxx_host";; + --cxx-host=*) cxx_host="$optarg";; + --windres) prev_p="windres";; + --windres=*) windres="$optarg";; + --awk) prev_p="awk";; + --awk=*) awk="$optarg";; + --pkg-config) prev_p="pkg_config";; + --pkg-config=*) pkg_config="$optarg";; + --strip) prev_p="strip";; + --strip=*) strip="$optarg";; + --lipo) prev_p="lipo";; + --lipo=*) lipo="$optarg";; + + + + # Alias --prefix with --prefix-dir, for compatibility with GNU autotools + --prefix-dir | --prefix) prev_p="prefix_dir";; + --prefix-dir=* | --prefix=*) prefix_dir="$optarg";; + + --binary-dir) prev_p="binary_dir";; + --binary-dir=*) binary_dir="$optarg";; + + --data-dir) prev_p="data_dir";; + --data-dir=*) data_dir="$optarg";; + + --doc-dir) prev_p="doc_dir";; + --doc-dir=*) doc_dir="$optarg";; + + --icon-dir) prev_p="icon_dir";; + --icon-dir=*) icon_dir="$optarg";; + + --icon-theme-dir) prev_p="icon_theme_dir";; + --icon-theme-dir=*) icon_theme_dir="$optarg";; + --without-icon-theme) icon_theme_dir="";; + + --menu-dir) prev_p="menu_dir";; + --menu-dir=*) menu_dir="$optarg";; + --without-menu-entry) menu_dir="";; + + --menu-name) prev_p="menu_name";; + --menu-name=*) menu_name="$optarg";; + + --binary-name) prev_p="binary_name";; + --binary-name=*) binary_name="$optarg";; + + --man-dir) prev_p="man_dir";; + --man-dir=*) man_dir="$optarg";; + + --personal-dir) prev_p="personal_dir";; + --personal-dir=*) personal_dir="$optarg";; + --without-personal-dir) personal_dir="";; + + --shared-dir) prev_p="shared_dir";; + --shared-dir=*) shared_dir="$optarg";; + --without-shared-dir) shared_dir="";; + + --install-dir) prev_p="install_dir";; + --install-dir=*) install_dir="$optarg";; + + + + --menu-group) prev_p="menu_group";; + --menu-group=*) menu_group="$optarg";; + + + + --enable-debug) enable_debug="1";; + --enable-debug=*) enable_debug="$optarg";; + --enable-desync-debug) enable_desync_debug="1";; + --enable-desync-debug=*) enable_desync_debug="$optarg";; + --enable-profiling) enable_profiling="1";; + --enable-profiling=*) enable_profiling="$optarg";; + --enable-lto) enable_lto="1";; + --enable-lto=*) enable_lto="$optarg";; + --enable-ipo) enable_lto="1";; + --enable-ipo=*) enable_lto="$optarg";; + --enable-dedicated) enable_dedicated="1";; + --enable-dedicated=*) enable_dedicated="$optarg";; + --disable-static) enable_static="0";; + --enable-static) enable_static="2";; + --enable-static=*) enable_static="$optarg";; + --disable-translator) enable_translator="0";; + --enable-translator) enable_translator="2";; + --enable-translator=*) enable_translator="$optarg";; + --disable-assert) enable_assert="0";; + --enable-assert) enable_assert="2";; + --enable-assert=*) enable_assert="$optarg";; + --disable-strip) enable_strip="0";; + --enable-strip) enable_strip="2";; + --enable-strip=*) enable_strip="$optarg";; + --disable-universal) enable_universal="0";; + --enable-universal) enable_universal="i386 ppc";; + --enable-universal=*) enable_universal="$optarg";; + --disable-osx-g5) enable_osx_g5="0";; + --enable-osx-g5) enable_osx_g5="2";; + --enable-osx-g5=*) enable_osx_g5="$optarg";; + --disable-unicode) enable_unicode="0";; + --enable-unicode) enable_unicode="2";; + --enable-unicode=*) enable_unicode="$optarg";; + --disable-console) enable_console="0";; + --enable-console) enable_console="2";; + --enable-console=*) enable_console="$optarg";; + + --disable-cocoa-quartz) enable_cocoa_quartz="0";; + --enable-cocoa-quartz) enable_cocoa_quartz="2";; + --enable-cocoa-quartz=*) enable_cocoa_quartz="$optarg";; + --disable-cocoa-quickdraw) enable_cocoa_quickdraw="0";; + --enable-cocoa-quickdraw) enable_cocoa_quickdraw="2";; + --enable-cocoa-quickdraw=*) enable_cocoa_quickdraw="$optarg";; + + --with-allegro) with_allegro="2";; + --without-allegro) with_allegro="0";; + --with-allegro=*) with_allegro="$optarg";; + + --with-sdl) with_sdl="2";; + --without-sdl) with_sdl="0";; + --with-sdl=*) with_sdl="$optarg";; + + --with-cocoa) with_cocoa="2";; + --without-cocoa) with_cocoa="0";; + --with-cocoa=*) with_cocoa="$optarg";; + + --with-zlib) with_zlib="2";; + --without-zlib) with_zlib="0";; + --with-zlib=*) with_zlib="$optarg";; + + --with-lzma) with_lzma="2";; + --without-lzma) with_lzma="0";; + --with-lzma=*) with_lzma="$optarg";; + --with-liblzma) with_lzma="2";; + --without-liblzma) with_lzma="0";; + --with-liblzma=*) with_lzma="$optarg";; + + --with-zstd) with_zstd="2";; + --without-zstd) with_zstd="0";; + --with-zstd=*) with_zstd="$optarg";; + + --with-lzo2) with_lzo2="2";; + --without-lzo2) with_lzo2="0";; + --with-lzo2=*) with_lzo2="$optarg";; + --with-liblzo2) with_lzo2="2";; + --without-liblzo2) with_lzo2="0";; + --with-liblzo2=*) with_lzo2="$optarg";; + + --with-xdg-basedir) with_xdg_basedir="2";; + --without-xdg-basedir) with_xdg_basedir="0";; + --with-xdg-basedir=*) with_xdg_basedir="$optarg";; + --with-libxdg-basedir) with_xdg_basedir="2";; + --without-libxdg-basedir) with_xdg_basedir="0";; + --with-libxdg-basedir=*) with_xdg_basedir="$optarg";; + + --with-png) with_png="2";; + --without-png) with_png="0";; + --with-png=*) with_png="$optarg";; + --with-libpng) with_png="2";; + --without-libpng) with_png="0";; + --with-libpng=*) with_png="$optarg";; + + --with-fluidsynth) with_fluidsynth="2";; + --without-fluidsynth) with_fluidsynth="0";; + --with-fluidsynth=*) with_fluidsynth="$optarg";; + + --with-freetype) with_freetype="2";; + --without-freetype) with_freetype="0";; + --with-freetype=*) with_freetype="$optarg";; + --with-libfreetype) with_freetype="2";; + --without-libfreetype) with_freetype="0";; + --with-libfreetype=*) with_freetype="$optarg";; + + --with-fontconfig) with_fontconfig="2";; + --without-fontconfig) with_fontconfig="0";; + --with-fontconfig=*) with_fontconfig="$optarg";; + --with-libfontconfig) with_fontconfig="2";; + --without-libfontconfig) with_fontconfig="0";; + --with-libfontconfig=*) with_fontconfig="$optarg";; + + --with-icu) with_icu_layout="2";with_icu_sort="2";; + --without-icu) with_icu_layout="0";with_icu_sort="0";; + --with-icu=*) with_icu_layout="$optarg";with_icu_sort="$optarg";; + --with-libicu) with_icu_layout="2";with_icu_sort="2";; + --without-libicu) with_icu_layout="0";with_icu_sort="0";; + --with-libicu=*) with_icu_layout="$optarg";with_icu_sort="$optarg";; + --with-icu-layout) with_icu_layout="2";; + --without-icu-layout) with_icu_layout="0";; + --with-icu-layout=*) with_icu_layout="$optarg";; + --with-icu-sort) with_icu_sort="2";; + --without-icu-sort) with_icu_sort="0";; + --with-icu-sort=*) with_icu_sort="$optarg";; + --static-icu) static_icu="1";; + --static-icu=*) static_icu="$optarg";; + --static-libicu) static_icu="1";; + --static-libicu=*) static_icu="$optarg";; + + --with-uniscribe) with_uniscribe="2";; + --without-uniscribe) with_uniscribe="0";; + --with-uniscribe=*) with_uniscribe="$optarg";; + + --disable-builtin-depend) enable_builtin_depend="0";; + --enable-builtin-depend) enable_builtin_depend="2";; + --enable-builtin-depend=*) enable_builtin_depend="$optarg";; + + --with-makedepend) with_makedepend="2";; + --without-makedepend) with_makedepend="0";; + --with-makedepend=*) with_makedepend="$optarg";; + + --with-direct-music) with_direct_music="2";; + --without-direct-music) with_direct_music="0";; + --with-direct-music=*) with_direct_music="$optarg";; + + --with-xaudio2) with_xaudio2="2";; + --without-xaudio2) with_xaudio2="0";; + --with-xaudio2=*) with_xaudio2="$optarg";; + + --with-sort) with_sort="2";; + --without-sort) with_sort="0";; + --with-sort=*) with_sort="$optarg";; + + --with-iconv) with_iconv="2";; + --without-iconv) with_iconv="0";; + --with-iconv=*) with_iconv="$optarg";; + + --with-midi=*) with_midi="$optarg";; + --with-midi-arg=*) with_midi_arg="$optarg";; + + --without-distcc) with_distcc="0";; + --with-distcc) with_distcc="2";; + --with-distcc=*) with_distcc="$optarg";; + + --without-ccache) with_ccache="0";; + --with-ccache) with_ccache="2";; + --with-ccache=*) with_ccache="$optarg";; + + --without-nforenum) with_nforenum="0";; + --with-nforenum) with_nforenum="2";; + --with-nforenum=*) with_nforenum="$optarg";; + + --without-grfcodec) with_grfcodec="0";; + --with-grfcodec) with_grfcodec="2";; + --with-grfcodec=*) with_grfcodec="$optarg";; + + --without-osx-sysroot) with_osx_sysroot="0";; + --with-osx-sysroot) with_osx_sysroot="2";; + --with-osx-sysroot=*) with_osx_sysroot="$optarg";; + + --without-application-bundle) with_application_bundle="0";; + --with-application-bundle) with_application_bundle="1";; + --with-application-bundle=*) with_application_bundle="$optarg";; + + --without-threads) with_threads="0";; + --with-threads) with_threads="1";; + --with-threads=*) with_threads="$optarg";; + + --without-sse) with_sse="0";; + --with-sse) with_sse="1";; + --with-sse=*) with_sse="$optarg";; + + CC=* | --CC=*) CC="$optarg";; + CXX=* | --CXX=*) CXX="$optarg";; + CFLAGS=* | --CFLAGS=*) CFLAGS="$optarg";; + CXXFLAGS=* | --CXXFLAGS=*) CXXFLAGS="$optarg";; + LDFLAGS=* | --LDFLAGS=*) LDFLAGS="$optarg";; + CFLAGS_BUILD=* | --CFLAGS_BUILD=* | --CFLAGS-BUILD=*) CFLAGS_BUILD="$optarg";; + CXXFLAGS_BUILD=* | --CXXFLAGS_BUILD=* | --CXXFLAGS-BUILD=*) CXXFLAGS_BUILD="$optarg";; + LDFLAGS_BUILD=* | --LDFLAGS_BUILD=* | --LDFLAGS-BUILD=*) LDFLAGS_BUILD="$optarg";; + PKG_CONFIG_PATH=* | --PKG_CONFIG_PATH=* | --PKG-CONFIG-PATH=*) PKG_CONFIG_PATH="$optarg";; + PKG_CONFIG_LIBDIR=* | --PKG_CONFIG_LIBDIR=* | --PKG-CONFIG-LIBDIR=*) PKG_CONFIG_LIBDIR="$optarg";; + + --ignore-extra-parameters) ignore_extra_parameters="1";; + + --* | -*) + if [ "$ignore_extra_parameters" = "0" ]; then + log 1 "Unknown option $p" + exit 1 + else + log 1 "Unknown option $p ignored" + fi + ;; + esac + done + + if [ -n "$prev_p" ]; then + log 1 "configure: error: missing argument to --$prev_p" + exit 1 + fi + + # Clean the logfile + echo "" > $config_log + log 2 "Invocation: $0 $*" +} + +save_params() { + # Here we save all params, so we can later on do an exact redo of this + # configuration, without having the user to re-input stuff + + echo "Running configure with following options:" >> $config_log + echo "" >> $config_log + + configure="$CONFIGURE_EXECUTABLE --ignore-extra-parameters" + for p in $save_params_array; do + eval "v=\"\$$p\"" + p=`echo "$p" | sed 's@_@-@g;s@\n@@g;s@ @\\ @g'` + # Only save those params that aren't empty + configure="$configure --$p=\"$v\"" + done + + echo "$configure" >> $config_log + echo "$configure" > config.cache + echo "" >> $config_log +} + +# Export a variable so tools like pkg-config can see it when invoked. +# If the variable contains an empty string then unset it. +# $1 - name of the variable to export or unset +export_or_unset() { + eval local value=\$$1 + if [ -n "$value" ]; then + export $1; + log 2 "using $1=$value"; + else + unset $1; + log 2 "not using $1"; + fi +} + +check_params() { + # Some params want to be in full uppercase, else they might not work as + # expected.. fix that here + + os=`echo $os | tr '[a-z]' '[A-Z]'` + cpu_type=`echo $cpu_type | tr '[a-z]' '[A-Z]'` + + # Export some variables to be used by pkg-config + # + # PKG_CONFIG_LIBDIR variable mustn't be set if we are not willing to + # override the default pkg-config search path, it mustn't be an empty + # string. If the variable is empty (e.g. when an empty string comes + # from config.cache) then unset it. This way the "don't override" state + # will be properly preserved when (re)configuring. + export_or_unset PKG_CONFIG_PATH + export_or_unset PKG_CONFIG_LIBDIR + + # Check if all params have valid values + + # OS only allows DETECT, UNIX, OSX, FREEBSD, DRAGONFLY, OPENBSD, NETBSD, HAIKU, SUNOS, CYGWIN, MINGW, and OS2 + if [ -z "`echo $os | egrep '^(DETECT|UNIX|OSX|FREEBSD|DRAGONFLY|OPENBSD|NETBSD|HPUX|HAIKU|SUNOS|CYGWIN|MINGW|OS2)$'`" ]; then + log 1 "configure: error: invalid option --os=$os" + log 1 " Available options are: --os=[DETECT|UNIX|OSX|FREEBSD|DRAGONFLY|OPENBSD|NETBSD|HPUX|HAIKU|SUNOS|CYGWIN|MINGW|OS2]" + exit 1 + fi + # cpu_type can be either 32 or 64 + if [ -z "`echo $cpu_type | egrep '^(32|64|DETECT)$'`" ]; then + log 1 "configure: error: invalid option --cpu-type=$cpu_type" + log 1 " Available options are: --cpu-type[=DETECT|32|64]" + exit 1 + fi + # enable_debug should be between 0 and 4 + if [ -z "`echo $enable_debug | egrep '^[0123]$'`" ]; then + log 1 "configure: error: invalid option --enable-debug=$enable_debug" + log 1 " Available options are: --enable-debug[=0123]" + exit 1 + fi + + # enable_desync_debug should be between 0 and 3 + if [ -z "`echo $enable_desync_debug | egrep '^[012]$'`" ]; then + log 1 "configure: error: invalid option --enable-desync-debug=$enable_desync_debug" + log 1 " Available options are: --enable-desync-debug[=012]" + exit 1 + fi + + detect_awk + + detect_os + + check_build + check_host + + # Check for universal builds; they only make sense for OSX, so fail if enabled for another OS + if [ "$enable_universal" = "0" ]; then + log 1 "checking universal build... no" + else + if [ "$os" != "OSX" ]; then + log 1 "configure: error: --enable-universal only works on OSX" + exit 1 + fi + log 1 "checking universal build... yes, for: $enable_universal" + fi + + # Already detected by check_build + log 1 "checking build cc... $cc_build" + log 1 "checking host cc... $cc_host" + + check_cxx_build + check_cxx_host + check_windres + if [ "$enable_strip" != "0" ]; then + check_strip + else + log 1 "checking strip... disabled" + fi + check_lipo + + if [ "$enable_builtin_depend" != "0" ]; then + log 1 "checking builtin depend... yes" + makedepend="\$(SRC_OBJS_DIR)/\$(DEPEND)" + else + log 1 "checking builtin depend... no" + fi + + check_makedepend + detect_cputype + detect_sse_capable_architecture + + if [ "$enable_static" = "1" ]; then + if [ "$os" = "MINGW" ] || [ "$os" = "CYGWIN" ]; then + enable_static="2" + else + enable_static="0" + fi + fi + + if [ "$enable_static" != "0" ]; then + log 1 "checking static... yes" + + if [ "$os" != "MINGW" ] && [ "$os" != "CYGWIN" ] && [ "$os" != "OSX" ]; then + log 1 "WARNING: static is only known to work on Windows, and MacOSX" + log 1 "WARNING: use static at your own risk on this platform" + + sleep 5 + fi + else + log 1 "checking static... no" + fi + + if [ "$enable_unicode" = "1" ]; then + if [ "$os" = "MINGW" ] || [ "$os" = "CYGWIN" ]; then + enable_unicode="2" + else + enable_unicode="0" + fi + fi + + if [ "$enable_unicode" != "0" ]; then + log 1 "checking unicode... yes" + else + log 1 "checking unicode... no" + fi + + # Show what we configured + if [ "$enable_debug" = "0" ]; then + log 1 "using debug level... no" + elif [ "$enable_profiling" != "0" ]; then + log 1 "using debug level... profiling (debug level $enable_debug)" + else + log 1 "using debug level... level $enable_debug" + fi + + if [ "$enable_desync_debug" = "0" ]; then + log 1 "using desync debug level... no" + else + log 1 "using desync debug level... level $enable_desync_debug" + log 1 "WARNING: desync debug functions slow down the game considerably." + log 1 "WARNING: use only when you are instructed to do so" + log 1 " or when you know what you are doing." + + sleep 5 + fi + + if [ "$enable_lto" != "0" ]; then + # GCC 4.5 outputs '%{flto}', GCC 4.6 outputs '%{flto*}' + has_lto=`($cxx_build -dumpspecs 2>&1 | grep '\%{flto') || ($cxx_build -help ipo 2>&1 | grep '\-ipo')` + if [ -n "$has_lto" ]; then + log 1 "using link time optimization... yes" + else + enable_lto="0" + log 1 "using link time optimization... no" + log 1 "WARNING: you selected link time optimization but it is not found." + sleep 5 + fi + else + log 1 "using link time optimization... no" + fi + + + if [ "$os" != "OSX" ] && [ "$with_osx_sysroot" != "0" ]; then + if [ "$with_osx_sysroot" = "1" ]; then + with_osx_sysroot="0" + + log 1 "checking OSX sysroot... not OSX, skipping" + else + log 1 "configure: error: --with-osx-sysroot only works if OSX is the target" + exit 1 + fi + fi + + if [ "$with_osx_sysroot" != "0" ]; then + if [ "$enable_universal" = "0" ] && [ "$with_osx_sysroot" != "1" ] && [ "$with_osx_sysroot" != "2" ]; then + # Sysroot manually specified? Check for usability + log 1 "checking OSX sysroot... $with_osx_sysroot" + if ! check_osx_sdk "$with_osx_sysroot"; then + log 1 "Passed sysroot not found/not functional" + exit 1 + fi + else + # If autodetect and no universal, use system default + if [ "$with_osx_sysroot" = "1" ] && [ "$enable_universal" = "0" ]; then + log 1 "checking OSX sysroot... no (use system default)" + else + log 1 "checking OSX sysroot... automatically" + detect_osx_sdk + fi + fi + + if [ -n "$osx_sdk_path" ]; then + if [ "$enable_universal" != "0" ]; then + if [ -z "$osx_sdk_104_path" ]; then + log 1 "WARNING: Could not find a usable 10.4u SDK, the resulting" + log 1 "WARNING: binary will only run on OSX 10.5 or later" + osx_sdk_104_path="$osx_sdk_path" + fi + OSX_SYSROOT="-isysroot $osx_sdk_104_path" + OSX_LD_SYSROOT="-Wl,-syslibroot,$osx_sdk_104_path" + else + OSX_SYSROOT="-isysroot $osx_sdk_path" + OSX_LD_SYSROOT="-Wl,-syslibroot,$osx_sdk_path" + fi + fi + else + if [ "$os" = "OSX" ]; then + log 1 "checking OSX sysroot... no (use system default)" + fi + fi + + detect_allegro + detect_sdl + detect_cocoa + + if [ "$enable_dedicated" != "0" ]; then + log 1 "checking GDI video driver... dedicated server, skipping" + log 1 "checking dedicated... found" + else + if [ "$os" = "MINGW" ] || [ "$os" = "CYGWIN" ]; then + log 1 "checking GDI video driver... found" + else + log 1 "checking GDI video driver... not Windows, skipping" + fi + + if [ -z "$allegro_config" ] && [ -z "$sdl2_config" ] && [ -z "$sdl_config" ] && [ "$with_cocoa" = 0 ] && [ "$os" != "MINGW" ] && [ "$os" != "CYGWIN" ]; then + log 1 "configure: error: no video driver development files found" + log 1 " If you want a dedicated server use --enable-dedicated as parameter" + exit 1 + else + log 1 "checking dedicated... not selected" + fi + fi + + if [ "$os" != "MINGW" ] && [ "$os" != "CYGWIN" ]; then + log 1 "checking console application... not Windows, skipping" + elif [ "$enable_console" = "1" ] && [ "$enable_dedicated" != "0" ]; then + log 1 "checking console application... dedicated server, enabled" + enable_console="2" + elif [ "$enable_console" = "1" ]; then + log 1 "checking console application... disabled (only used when forced)" + enable_console="0" + elif [ "$enable_console" = "0" ]; then + log 1 "checking console application... disabled" + else + log 1 "checking console application... enabled" + fi + + log 1 "checking squirrel... found" + SCRIPT_SRC_DIR="$ROOT_DIR/src/3rdparty/squirrel/include" + + if [ "$enable_translator" != "0" ]; then + log 1 "checking translator... debug" + # -t shows TODO items, normally they are muted + strgen_flags="-t" + else + log 1 "checking translator... no" + strgen_flags="" + fi + + if [ "$enable_assert" != "0" ]; then + log 1 "checking assert... enabled" + else + log 1 "checking assert... disabled" + fi + + pre_detect_with_zlib=$with_zlib + detect_zlib + + if [ "$with_zlib" = "0" ] || [ -z "$zlib_config" ]; then + log 1 "WARNING: zlib was not detected or disabled" + log 1 "WARNING: OpenTTD doesn't require zlib, but it does mean that many features" + log 1 "WARNING: (like loading most old savegames/scenarios, loading heightmaps," + log 1 "WARNING: using PNG, or using fonts, ...) will be disabled." + if [ "$pre_detect_with_zlib" = "0" ]; then + log 1 "WARNING: We strongly suggest you to install zlib." + else + log 1 "configure: error: no zlib detected" + log 1 " If you want to compile without zlib use --without-zlib as parameter" + exit + fi + fi + + pre_detect_with_lzma=$with_lzma + detect_lzma + + if [ "$with_lzma" = "0" ] || [ -z "$lzma_config" ]; then + log 1 "WARNING: lzma was not detected or disabled" + log 1 "WARNING: OpenTTD doesn't require lzma, but it does mean that many features" + log 1 "WARNING: (like loading most savegames/scenarios and joining most servers)" + log 1 "WARNING: will be disabled." + if [ "$pre_detect_with_lzma" = "0" ]; then + log 1 "WARNING: We strongly suggest you to install liblzma." + log 1 "configure: error: no liblzma detected" + else + log 1 " If you want to compile without lzma use --without-lzma as parameter" + exit + fi + fi + + pre_detect_with_zstd=$with_zstd + detect_zstd + + if [ "$with_zstd" = "0" ] || [ -z "$zstd_config" ]; then + log 1 "WARNING: zstd was not detected or disabled" + if [ "$pre_detect_with_zstd" = "0" ]; then + log 1 "WARNING: We strongly suggest you to install zstd." + else + log 1 "configure: error: no zstd detected" + log 1 " If you want to compile without zstd use --without-zstd as parameter" + exit + fi + fi + + pre_detect_with_lzo2=$with_lzo2 + detect_lzo2 + + if [ "$with_lzo2" = "0" ] || [ -z "$lzo2" ]; then + log 1 "WARNING: liblzo2 was not detected or disabled" + log 1 "WARNING: OpenTTD doesn't require liblzo2, but it does mean that" + log 1 "WARNING: loading old savegames/scenarios will be disabled." + if [ "$pre_detect_with_lzo2" = "0" ]; then + log 1 "WARNING: We strongly suggest you to install liblzo2." + else + log 1 "configure: error: no liblzo2 detected" + log 1 " If you want to compile without liblzo2 use --without-liblzo2 as parameter" + exit + fi + fi + + if [ "$with_uniscribe" != "0" ]; then + if [ "$os" != "MINGW" ]; then + if [ "$with_uniscribe" != "1" ]; then + log 1 "configure: error: Uniscribe is only supported on native Win32 targets" + exit 1 + fi + with_uniscribe="0" + + log 1 "checking Uniscribe text layout... not Windows, skipping" + else + log 1 "checking Uniscribe text layout... found" + + # Don't use ICU unless forced. + if [ "$with_icu_layout" = "1" ]; then + with_icu_layout="0" + fi + if [ "$with_icu_sort" = "1" ]; then + with_icu_sort="0" + fi + fi + fi + + detect_xdg_basedir + detect_png + detect_freetype + detect_fontconfig + detect_icu_layout + detect_icu_sort + detect_fluidsynth + + if [ "$with_direct_music" != "0" ]; then + if [ "$os" != "MINGW" ] && [ "$os" != "CYGWIN" ]; then + if [ "$with_direct_music" != "1" ]; then + log 1 "configure: error: direct-music is only supported on Win32 targets" + exit 1 + fi + with_direct_music="0" + + log 1 "checking direct-music... not Windows, skipping" + else + check_direct_music + fi + fi + + if [ "$with_xaudio2" != "0" ]; then + if [ "$os" != "MINGW" ] && [ "$os" != "CYGWIN" ]; then + if [ "$with_xaudio2" != "1" ]; then + log 1 "configure: error: xaudio2 is only supported on Win32 targets" + exit 1 + fi + with_xaudio2="0" + + log 1 "checking xaudio2... not Windows, skipping" + else + check_xaudio2 + fi + fi + + detect_sort + + # Suppress language errors when there is a version defined, indicating a release + # It just isn't pretty if any release produces warnings in the languages. + if [ -f "$ROOT_DIR/version" ]; then + lang_suppress="yes" + log 1 "suppress language errors... yes" + else + lang_suppress="" + log 1 "suppress language errors... no" + fi + + if [ "$enable_debug" = "0" ] && [ "$enable_profiling" = "0" ] && [ "$enable_strip" != "0" ]; then + if [ "$os" = "OSX" ]; then + strip_arg="" + elif [ "$os" = "OS2" ]; then + strip_arg="" + # OS2 uses strip via gcc, because it needs to be feed to emxbind + LDFLAGS="$LDFLAGS -s" + elif [ "$os" = "SUNOS" ]; then + # The GNU strip does know -s, the non-GNU doesn't + # So try to detect it (in a bit of an ugly way) + strip_arg="`$strip -s strip.test 2>/dev/null && echo \"-s\"`" + else + strip_arg="-s" + fi + + log 1 "checking stripping... $strip $strip_arg" + else + strip="" + log 1 "checking stripping... skipped" + fi + + if [ "$with_distcc" = "0" ]; then + log 1 "checking distcc... no" + elif [ "$with_distcc" = "1" ]; then + with_distcc="0" + + log 1 "checking distcc... no (only used when forced)" + elif [ "$with_distcc" = "2" ]; then + distcc="distcc" + else + distcc="$with_distcc" + fi + if [ "$with_distcc" != "0" ]; then + res="`$distcc --version 2>/dev/null | head -n 1 | cut -b 1-6`" + if [ "$res" != "distcc" ]; then + distcc="" + log 1 "checking distcc... no" + if [ "$with_distcc" = "2" ]; then + log 1 "configure: error: no distcc detected, but was forced to be used" + exit 1 + fi + if [ "$with_distcc" != "1" ]; then + log 1 "configure: error: '$with_distcc' doesn't seem a distcc to me" + exit 1 + fi + fi + + log 1 "checking distcc... $distcc" + fi + + if [ "$with_ccache" = "0" ]; then + log 1 "checking ccache... no" + elif [ "$with_ccache" = "1" ]; then + with_ccache="0" + + log 1 "checking ccache... no (only used when forced)" + elif [ "$with_ccache" = "2" ]; then + ccache="ccache" + else + ccache="$with_ccache" + fi + if [ "$with_ccache" != "0" ]; then + res="`$ccache --version 2>/dev/null | head -n 1 | cut -b 1-6`" + if [ "$res" != "ccache" ]; then + ccache="" + log 1 "checking ccache... no" + if [ "$with_ccache" = "2" ]; then + log 1 "configure: error: no ccache detected, but was forced to be used" + exit 1 + fi + if [ "$with_ccache" != "1" ]; then + log 1 "configure: error: '$with_ccache' doesn't seem a ccache to me" + exit 1 + fi + fi + + log 1 "checking ccache... $ccache" + fi + + detect_grfcodec + detect_nforenum + + if [ -z "$grfcodec" ] && [ -n "$nforenum" ]; then + log 1 "checking nforenum/grfcodec... nforenum needs grfcodec enabled, disabling nforenum" + nforenum="" + fi + + if [ -z "$nforenum" ] && [ -n "$grfcodec" ]; then + log 1 "checking nforenum/grfcodec... grfcodec needs nforenum enabled, disabling grfcodec" + grfcodec="" + fi + + if [ "$os" != "OSX" ] && [ "$with_application_bundle" != "0" ]; then + if [ "$with_application_bundle" = "1" ]; then + with_application_bundle="0" + + log 1 "checking OSX application bundle... not OSX, skipping" + else + log 1 "configure: error: --with-application-bundle only works if OSX is the target" + exit 1 + fi + fi + + if [ "$os" = "OSX" ] && [ "$with_application_bundle" = "1" ]; then + OSXAPP="OpenTTD.app" + else + OSXAPP="" + fi + + if [ "$os" = "OSX" ]; then + # Test on ppc970 (G5) - we can optimize there + + if [ "$enable_osx_g5" != "0" ]; then + log 1 "detecting ppc970 (G5)... yes (forced)" + else + # First, are we a real OSX system, else we can't detect it + native=`LC_ALL=C uname | tr '[A-Z]' '[a-z]' | grep darwin` + # If $host doesn't match $build , we are cross-compiling + if [ -n "$native" ] && [ "$build" = "$host" ]; then + $cxx_build $SRC_DIR/os/macosx/G5_detector.cpp -o G5_detector + res=`./G5_detector` + rm -f G5_detector + if [ -n "$res" ]; then + # This is G5, add flags for it + enable_osx_g5="2" + + log 1 "detecting ppc970 (G5)... yes" + else + enable_osx_g5="0" + + log 1 "detecting ppc970 (G5)... no" + fi + else + enable_osx_g5="0" + + log 1 "detecting ppc970 (G5)... no (cross-compiling)" + fi + fi + else + if [ "$enable_osx_g5" != "0" ]; then + log 1 "configure: error: ppc970 (OSX G5) selected, but not compiling for OSX" + log 1 "configure: error: either select OSX as OS, or deselect ppc970" + + exit 1 + fi + fi + + if { [ -d "$ROOT_DIR/.git" ] || [ -f "$ROOT_DIR/.git" ]; } && [ -n "`git help 2>/dev/null`" ]; then + log 1 "checking revision... git detection" + elif [ -f "$ROOT_DIR/.ottdrev" ]; then + log 1 "checking revision... source tarball" + else + log 1 "checking revision... no detection" + log 1 "WARNING: there is no means to determine the version." + log 1 "WARNING: please use a subversion, mercurial, or git checkout of OpenTTD." + log 1 "WARNING: you can only join game servers that have been compiled without" + log 1 "WARNING: version detection." + log 1 "WARNING: there is a great chance you desync." + log 1 "WARNING: USE WITH CAUTION!" + + sleep 5 + fi + + if [ "$doc_dir" = "1" ]; then + if [ "$os" = "UNIX" ] || [ "$os" = "FREEBSD" ] || [ "$os" = "DRAGONFLY" ] || [ "$os" = "OPENBSD" ] || [ "$os" = "NETBSD" ] || [ "$os" = "HPUX" ] || [ "$os" = "SUNOS" ]; then + doc_dir="share/doc/openttd" + else + doc_dir="$data_dir/docs" + fi + else + doc_dir="`echo $doc_dir | sed 's@\([^\]\)\\\\ @\1\\\\\\\\ @g;s@\([^\]\) @\1\\\\\\\\ @g'`" + fi + + if [ "$icon_theme_dir" = "1" ]; then + if [ "$os" = "UNIX" ] || [ "$os" = "FREEBSD" ] || [ "$os" = "DRAGONFLY" ] || [ "$os" = "OPENBSD" ] || [ "$os" = "NETBSD" ] || [ "$os" = "HPUX" ] || [ "$os" = "SUNOS" ]; then + icon_theme_dir="share/icons/hicolor" + else + icon_theme_dir="" + fi + else + icon_theme_dir="`echo $icon_theme_dir | sed 's@\([^\]\)\\\\ @\1\\\\\\\\ @g;s@\([^\]\) @\1\\\\\\\\ @g'`" + fi + + if [ "$personal_dir" = "1" ]; then + if [ "$os" = "MINGW" ] || [ "$os" = "CYGWIN" ] || [ "$os" = "HAIKU" ]; then + personal_dir="OpenTTD" + elif [ "$os" = "OSX" ]; then + personal_dir="Documents/OpenTTD" + else + personal_dir=".openttd" + fi + else + personal_dir="`echo $personal_dir | sed 's@\([^\]\)\\\\ @\1\\\\\\\\ @g;s@\([^\]\) @\1\\\\\\\\ @g'`" + fi + + if [ "$shared_dir" = "1" ]; then + # we are using default values + if [ "$os" = "OSX" ]; then + shared_dir="/Library/Application\\\\ Support/OpenTTD" + else + shared_dir="" + fi + else + shared_dir="`echo $shared_dir | sed 's@\([^\]\)\\\\ @\1\\\\\\\\ @g;s@\([^\]\) @\1\\\\\\\\ @g'`" + fi + + if [ "$man_dir" = "1" ]; then + # add manpage on UNIX systems + if [ "$os" = "UNIX" ] || [ "$os" = "FREEBSD" ] || [ "$os" = "DRAGONFLY" ] || [ "$os" = "OPENBSD" ] || [ "$os" = "NETBSD" ] || [ "$os" = "HPUX" ] || [ "$os" = "SUNOS" ] || [ "$os" = "OSX" ]; then + man_dir="share/man/man6" + else + man_dir="" + fi + else + man_dir="`echo $man_dir | sed 's@\([^\]\)\\\\ @\1\\\\\\\\ @g;s@\([^\]\) @\1\\\\\\\\ @g'`" + fi + + if [ "$menu_dir" = "1" ]; then + # add a freedesktop menu item only for some UNIX systems + if [ "$os" = "UNIX" ] || [ "$os" = "FREEBSD" ] || [ "$os" = "DRAGONFLY" ] || [ "$os" = "OPENBSD" ] || [ "$os" = "NETBSD" ] || [ "$os" = "HPUX" ] || [ "$os" = "SUNOS" ]; then + menu_dir="share/applications" + else + menu_dir="" + fi + else + menu_dir="`echo $menu_dir | sed 's@\([^\]\)\\\\ @\1\\\\\\\\ @g;s@\([^\]\) @\1\\\\\\\\ @g'`" + fi + + detect_iconv + + if [ -n "$personal_dir" ] + then + log 1 "personal home directory... $personal_dir" + else + log 1 "personal home directory... none" + fi + + if [ -n "$shared_dir" ] + then + log 1 "shared data directory... $shared_dir" + else + log 1 "shared data directory... none" + fi + + if [ -n "$install_dir" ] + then + log 1 "installation directory... $install_dir" + else + log 1 "installation directory... none" + fi + + if [ -n "$icon_theme_dir" ] + then + log 1 "icon theme directory... $icon_theme_dir" + else + log 1 "icon theme directory... none" + fi + + if [ -n "$man_dir" ] + then + log 1 "manual page directory... $man_dir" + else + log 1 "manual page directory... none" + fi + + if [ -n "$menu_dir" ] + then + log 1 "menu item directory... $menu_dir" + else + log 1 "menu item directory... none" + fi +} + +make_compiler_cflags() { + # Params: + # $1 - compiler + # $2 - name of the cflags variable + # $3 - name of the cxxflags variable + # $4 - name of the ldflags variable + # $5 - name of the features variable + + # Get the compiler to tell us who it is + version_line="`$1 --version | head -n1`" + + eval eval "flags=\\\$$2" + eval eval "cxxflags=\\\$$3" + eval eval "ldflags=\\\$$4" + eval eval "features=\\\$$5" + + if [ `echo "$version_line" | cut -d' ' -f1` = "icc" ]; then + # Enable some things only for certain ICC versions + cc_version=`$1 -dumpversion | cut -c 1-4 | sed s@\\\.@@g` + + flags="$flags -rdynamic" + ldflags="$ldflags -rdynamic" + + if [ -z "$first_time_icc_check" ]; then + first_time_icc_check=no + if [ $cc_version -lt 90 ]; then + log 1 "WARNING: you seem to be using a very old version of ICC" + log 1 "WARNING: OpenTTD hasn't been tested with this version" + sleep 5 + elif [ $cc_version -lt 120 ]; then + log 1 "WARNING: you seem to be using an unsupported ICC version" + log 1 "WARNING: ICC older than 12.0 is known to fail to compile OpenTTD" + sleep 5 + fi + fi + + flags="$flags -Wall" + # remark #111: statement is unreachable + flags="$flags -wd111" + # remark #181: argument is incompatible with corresponding format string conversion + # ICC is very picky about signedness of operands, warnings provided by GCC are enough + flags="$flags -wd181" + # remark #271: trailing comma is nonstandard + flags="$flags -wd271" + # remark #280: selector expression is constant + flags="$flags -wd280" + # remark #304: access control not specified ("public" by default) + flags="$flags -wd304" + # remark #383: value copied to temporary, reference to temporary used + flags="$flags -wd383" + # remark #444: destructor for base class ... is not virtual + flags="$flags -wd444" + # remark #593: variable ... was set but never used + flags="$flags -wd593" + # warning #654: overloaded virtual function ... is only partially overridden in class ... + flags="$flags -wd654" + # remark #810: conversion from ... to ... may lose significant bits + flags="$flags -wd810" + # remark #869: parameter ... was never referenced + flags="$flags -wd869" + # warning #873: function ... ::operator new ... has no corresponding operator delete ... + flags="$flags -wd873" + # remark #981: operands are evaluated in unspecified order + flags="$flags -wd981" + # remark #1418: external function definition with no prior declaration + flags="$flags -wd1418" + # remark #1419: external declaration in primary source file + flags="$flags -wd1419" + # remark #1572: floating-point equality and inequality + flags="$flags -wd1572" + # remark #1599: declaration hides variable/parameter ... + flags="$flags -wd1599" + # remark #1720: function ... ::operator new ... has no corresponding member operator delete ... + flags="$flags -wd1720" + + if [ $cc_version -lt 110 ]; then + # warns about system headers with recent glibc: + # warning #1292: attribute "__nonnull__" ignored + flags="$flags -wd1292" + fi + + if [ $cc_version -ge 100 ]; then + # warning #1899: multicharacter character literal (potential portability problem) + flags="$flags -wd1899" + # vec report defaults to telling where it did loop vectorisation, which is not very important + flags="$flags -vec-report=0 " + fi + + if [ $cc_version -ge 110 ]; then + # remark #2259: non-pointer conversion from ... to ... may lose significant bits + flags="$flags -wd2259" + fi + + if [ "$enable_lto" != "0" ]; then + has_ipo=`$1 -help ipo | grep '\-ipo'` + if [ -n "$has_ipo" ]; then + # Use IPO (only if we see IPO exists and is requested) + flags="$flags -ipo" + features="$features lto" + fi + fi + elif echo "$version_line" | grep -q "clang"; then + # Enable some things only for certain clang versions + # Need to try really hard to get the version line, because OSX clang likes to hide its true version + cc_version="`$1 -v 2>&1 | grep -i version | head -n 1 | sed s@[^0-9]@@g | cut -c 1-2`" + + # aliasing rules are not held in openttd code + flags="$flags -fno-strict-aliasing" + + # -W alone doesn't enable all warnings enabled by -Wall; on the other hand, + # -Weverything enables too many useless warnings that can't be disabled (as of 3.0) + flags="$flags -Wall -W -Wextra" + + # warning: unused parameter '...' + flags="$flags -Wno-unused-parameter" + + # warning: expression result unused + flags="$flags -Wno-unused-value" + + # warning: multi-character character constant + flags="$flags -Wno-multichar" + + # warning: explicitly assigning a variable of type '...' to itself + # it happens when using the FOR_ALL_WINDOWS_FROM_BACK_FROM macro + flags="$flags -Wno-self-assign" + + # warning: is a C++11 extension + flags="$flags -Wno-c++11-extensions" + + if [ "$cc_version" -lt "30" ]; then + # warning: equality comparison with extraneous parentheses + flags="$flags -Wno-parentheses" + # warning: operands of ? are integers of different signs: 'unsigned int' and 'int' + flags="$flags -Wno-sign-compare" + fi + + if [ "$cc_version" -ge "30" ]; then + # warning: equality comparison with extraneous parentheses + # this warning could be useful, but it warns about code in squirrel + flags="$flags -Wno-parentheses-equality" + fi + + if [ "$with_ccache" != "0" -o "$with_distcc" != "0" ]; then + # ccache and distcc run separate preprocess and compile passes, + # both are fed with the same CFLAGS. Unfortunately, clang + # complains about -I when compiling preprocessed files: + # "clang: warning: argument unused during compilation: '-I /usr/include'" + flags="$flags -Qunused-arguments" + fi + + if [ "$enable_assert" -eq "0" ]; then + # do not warn about unused variables when building without asserts + flags="$flags -Wno-unused-variable" + fi + + # rdynamic is used to get useful stack traces from crash reports. + ldflags="$ldflags -rdynamic" + + # Assume gcc, since it just uses argv[0] in its --version output + else + # Enable some things only for certain GCC versions + # cc_version = major_version * 100 + minor_version + # For example: "3.3" -> 303, "4.9.2" -> 409, "6" -> 600, "23.5" -> 2305 + cc_version=`$1 -dumpversion | $awk -F . '{printf "%d%02d", $1, $2}'` + + if [ $cc_version -lt 303 ]; then + log 1 "configure: error: gcc older than 3.3 can't compile OpenTTD because of its poor template support" + exit 1 + fi + + flags="$flags -Wall -Wno-multichar -Wsign-compare -Wundef" + flags="$flags -Wwrite-strings -Wpointer-arith" + flags="$flags -W -Wno-unused-parameter -Wredundant-decls" + flags="$flags -Wformat=2 -Wformat-security" + + if [ $enable_assert -eq 0 ]; then + # Do not warn about unused variables when building without asserts + flags="$flags -Wno-unused-variable" + if [ $cc_version -ge 406 ]; then + # GCC 4.6 gives more warnings, disable them too + flags="$flags -Wno-unused-but-set-variable" + flags="$flags -Wno-unused-but-set-parameter" + fi + fi + + if [ $cc_version -ge 304 ]; then + # Warn when a variable is used to initialise itself: + # int a = a; + flags="$flags -Winit-self" + fi + + if [ $cc_version -ge 400 ]; then + # GCC 4.0+ 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. + flags="$flags -fno-strict-aliasing" + # Warn about casting-out 'const' with regular C-style cast. + # The preferred way is const_cast<>() which doesn't warn. + flags="$flags -Wcast-qual" + fi + + if [ $cc_version -ge 402 ]; then + # GCC 4.2+ automatically assumes that signed overflows do + # not occur in signed arithmetic, whereas we are not + # sure that they will not happen. It furthermore complains + # about its own optimized code in some places. + flags="$flags -fno-strict-overflow" + # GCC 4.2 no longer includes -Wnon-virtual-dtor in -Wall. + # Enable it in order to be consistent with older GCC versions. + flags="$flags -Wnon-virtual-dtor" + fi + + if [ $cc_version -eq 405 ]; then + # Prevent optimisation supposing enums are in a range specified by the standard + # For details, see http://gcc.gnu.org/PR43680 + flags="$flags -fno-tree-vrp" + fi + + if [ $cc_version -eq 407 ]; then + # Disable -Wnarrowing which gives many warnings, such as: + # warning: narrowing conversion of '...' from 'unsigned int' to 'int' inside { } [-Wnarrowing] + # They are valid according to the C++ standard, but useless. + cxxflags="$cxxflags -Wno-narrowing" + fi + + if [ $cc_version -ge 407 ]; then + # Disable bogus 'attempt to free a non-heap object' warning + flags="$flags -Wno-free-nonheap-object" + fi + + if [ $cc_version -ge 600 ]; then + # -flifetime-dse=2 (default since GCC 6) doesn't play + # well with our custom pool item allocator + cxxflags="$cxxflags -flifetime-dse=1" + fi + + if [ "$enable_lto" != "0" ]; then + # GCC 4.5 outputs '%{flto}', GCC 4.6 outputs '%{flto*}' + has_lto=`$1 -dumpspecs | grep '\%{flto'` + if [ -n "$has_lto" ]; then + # Use LTO only if we see LTO exists and is requested + if [ $cc_version -lt 406 ]; then + flags="$flags -flto" + else + flags="$flags -flto=jobserver" + fi + ldflags="$ldflags -fwhole-program" + features="$features lto" + fi + fi + + has_rdynamic=`$1 -dumpspecs | grep rdynamic` + if [ -n "$has_rdynamic" ]; then + # rdynamic is used to get useful stack traces from crash reports. + flags="$flags -rdynamic" + ldflags="$ldflags -rdynamic" + fi + fi + + eval "$2=\"$flags\"" + eval "$3=\"$cxxflags\"" + eval "$4=\"$ldflags\"" + eval "$5=\"$features\"" +} + +make_cflags_and_ldflags() { + # General CFlags for BUILD + CFLAGS_BUILD_ENV="$CFLAGS_BUILD" + CFLAGS_BUILD="" + # Special CXXFlags for BUILD + CXXFLAGS_BUILD_ENV="$CXXFLAGS_BUILD" + CXXFLAGS_BUILD="" + # LDFLAGS for BUILD + LDFLAGS_BUILD_ENV="$LDFLAGS_BUILD" + LDFLAGS_BUILD="" + # FEATURES for BUILD (lto) + FEATURES_BUILD="" + # General CFlags for HOST + CFLAGS_ENV="$CFLAGS" + CFLAGS="" + # Special CXXFlags for HOST + CXXFLAGS_ENV="$CXXFLAGS" + CXXFLAGS="" + # Libs to compile. In fact this is just LDFLAGS + LIBS="" + # LDFLAGS used for HOST + LDFLAGS_ENV="$LDFLAGS" + LDFLAGS="" + # FEATURES for HOST (lto) + FEATURES="" + + make_compiler_cflags "$cc_build" "CFLAGS_BUILD" "CXXFLAGS_BUILD" "LDFLAGS_BUILD" "FEATURES_BUILD" + make_compiler_cflags "$cc_host" "CFLAGS" "CXXFLAGS" "LDFLAGS" "FEATURES" + + CFLAGS="$CFLAGS -D$os" + CFLAGS_BUILD="$CFLAGS_BUILD -D$os" + CXXFLAGS="$CXXFLAGS -std=c++17" + CXXFLAGS_BUILD="$CXXFLAGS_BUILD -std=c++17" + + if [ "$enable_debug" = "0" ]; then + # No debug, add default stuff + OBJS_SUBDIR="release" + + if [ "$enable_profiling" = "0" ]; then + # -fomit-frame-pointer and -pg do not go well together (gcc errors they are incompatible) + CFLAGS="-fomit-frame-pointer $CFLAGS" + fi + CFLAGS="-O2 $CFLAGS" + else + OBJS_SUBDIR="debug" + + # Each debug level reduces the optimization by a bit + if [ $enable_debug -ge 1 ]; then + CFLAGS="$CFLAGS -g -D_DEBUG" + fi + if [ $enable_debug -ge 2 ]; then + CFLAGS="$CFLAGS -fno-inline" + fi + if [ $enable_debug -ge 3 ]; then + CFLAGS="$CFLAGS -O0" + else + CFLAGS="$CFLAGS -O2" + fi + fi + + if [ $enable_debug -le 2 ]; then + cc_host_is_gcc=`basename "$cc_host" | grep "gcc" 2>/dev/null` + if [ -n "$cc_host_is_gcc" ]; then + # Define only when compiling with GCC. Some GLIBC versions use GNU + # extensions in a way that breaks build with at least ICC. + # This requires -O1 or more, so debug level 3 (-O0) is excluded. + CFLAGS="$CFLAGS -D_FORTIFY_SOURCE=2" + if [ "$os" = "MINGW" ]; then + # Prevent undefined references when _FORTIFY_SOURCE > 0 + LDFLAGS="$LDFLAGS -fstack-protector" + fi + fi + + cc_build_is_gcc=`basename "$cc_build" | grep "gcc" 2>/dev/null` + if [ -n "$cc_build_is_gcc" ]; then + # Just add -O1 to the tools needed for building. + CFLAGS_BUILD="$CFLAGS_BUILD -D_FORTIFY_SOURCE=2 -O1" + if [ "$os" = "MINGW" ]; then + # Prevent undefined references when _FORTIFY_SOURCE > 0 + LDFLAGS_BUILD="$LDFLAGS_BUILD -fstack-protector" + fi + fi + fi + + if [ "$os" = "OSX" ] && [ $cc_version -eq 400 ]; then + # Apple's GCC 4.0 has a compiler bug for x86_64 with (higher) optimization, + # wrongly optimizing ^= in loops. This disables the failing optimisation. + CFLAGS="$CFLAGS -fno-expensive-optimizations" + fi + + if [ "$enable_profiling" != "0" ]; then + CFLAGS="$CFLAGS -pg" + LDFLAGS="$LDFLAGS -pg" + fi + + if [ "$with_threads" = "0" ]; then + CFLAGS="$CFLAGS -DNO_THREADS" + fi + if [ "$with_sse" = "1" ]; then + CFLAGS="$CFLAGS -DWITH_SSE" + fi + + if [ "`echo $1 | cut -c 1-3`" != "icc" ]; then + if [ "$os" = "CYGWIN" ]; then + flags="$flags -mwin32" + LDFLAGS="$LDFLAGS -mwin32" + fi + if [ "$os" = "MINGW" ] || [ "$os" = "CYGWIN" ]; then + if [ $cc_version -lt 406 ]; then + flags="$flags -mno-cygwin" + LDFLAGS="$LDFLAGS -mno-cygwin" + fi + + if [ "$enable_console" != "0" ]; then + LDFLAGS="$LDFLAGS -Wl,--subsystem,console" + else + LDFLAGS="$LDFLAGS -Wl,--subsystem,windows" + fi + + LIBS="$LIBS -lws2_32 -lwinmm -lusp10 -lgdi32 -ldxguid -lole32 -limm32" + + if [ $cc_version -ge 404 ]; then + LDFLAGS_BUILD="$LDFLAGS_BUILD -static-libgcc -static-libstdc++" + fi + if [ $cc_version -ge 407 ]; then + CFLAGS="$CFLAGS -mno-ms-bitfields" + fi + fi + fi + + if [ "$os" != "CYGWIN" ] && [ "$os" != "HAIKU" ] && [ "$os" != "OPENBSD" ] && [ "$os" != "MINGW" ] && [ "$os" != "OSX" ] && [ "$os" != "OS2" ]; then + LIBS="$LIBS -lpthread" + fi + + if [ "$os" != "CYGWIN" ] && [ "$os" != "HAIKU" ] && [ "$os" != "MINGW" ]; then + LIBS="$LIBS -lc" + fi + + if [ "$os" = "OPENBSD" ]; then + LIBS="$LIBS -pthread" + fi + + if [ "$os" = "OSX" ]; then + LDFLAGS="$LDFLAGS -framework Cocoa" + + # Add macports include dir which is not always set a default system dir. This avoids zillions of bogus warnings. + CFLAGS="$CFLAGS -isystem/opt/local/include" + + if [ "$enable_dedicated" = "0" ] && ([ "$cpu_type" = "32" ] || [ "$enable_universal" != "0" ]); then + LIBS="$LIBS -framework QuickTime" + else + CFLAGS="$CFLAGS -DNO_QUICKTIME" + fi + + if [ "$enable_universal" = "0" ]; then + # Universal builds set this elsewhere + CFLAGS="$OSX_SYSROOT $CFLAGS" + LDFLAGS="$OSX_LD_SYSROOT $LDFLAGS" + fi + fi + + if [ "$os" = "HAIKU" ]; then + LIBS="$LIBS -lmidi -lbe" + fi + + # Most targets act like UNIX, just with some additions + if [ "$os" = "HAIKU" ] || [ "$os" = "OSX" ] || [ "$os" = "FREEBSD" ] || [ "$os" = "DRAGONFLY" ] || [ "$os" = "OPENBSD" ] || [ "$os" = "NETBSD" ] || [ "$os" = "HPUX" ] || [ "$os" = "SUNOS" ] || [ "$os" = "OS2" ]; then + CFLAGS="$CFLAGS -DUNIX" + fi + # And others like Windows + if [ "$os" = "MINGW" ] || [ "$os" = "CYGWIN" ]; then + CFLAGS="$CFLAGS -DWIN" + fi + + if [ -n "$allegro_config" ]; then + CFLAGS="$CFLAGS -DWITH_ALLEGRO" + CFLAGS="$CFLAGS `$allegro_config --cflags`" + if [ "$os" != "MINGW" ] && [ "$os" != "CYGWIN" ]; then + if [ "$enable_static" != "0" ]; then + LIBS="$LIBS `$allegro_config --static --libs`" + else + LIBS="$LIBS `$allegro_config --libs`" + fi + fi + fi + + if [ -n "$sdl2_config" ]; then + CFLAGS="$CFLAGS -DWITH_SDL2" + # SDL must not add _GNU_SOURCE as it breaks many platforms + CFLAGS="$CFLAGS `$sdl2_config --cflags | sed 's@-D_GNU_SOURCE[^ ]*@@'`" + if [ "$enable_static" != "0" ]; then + LIBS="$LIBS `$sdl2_config --static --libs`" + else + LIBS="$LIBS `$sdl2_config --libs`" + fi + elif [ -n "$sdl_config" ]; then + CFLAGS="$CFLAGS -DWITH_SDL" + # SDL must not add _GNU_SOURCE as it breaks many platforms + CFLAGS="$CFLAGS `$sdl_config --cflags | sed 's@-D_GNU_SOURCE[^ ]*@@'`" + if [ "$enable_static" != "0" ]; then + LIBS="$LIBS `$sdl_config --static --libs`" + else + LIBS="$LIBS `$sdl_config --libs`" + fi + fi + + if [ "$with_cocoa" != "0" ]; then + CFLAGS="$CFLAGS -DWITH_COCOA" + LIBS="$LIBS -F/System/Library/Frameworks -framework Cocoa -framework Carbon -framework AudioUnit -framework AudioToolbox" + + if [ "$enable_cocoa_quartz" != "0" ]; then + CFLAGS="$CFLAGS -DENABLE_COCOA_QUARTZ" + fi + + if [ "$enable_cocoa_quickdraw" != "0" ]; then + CFLAGS="$CFLAGS -DENABLE_COCOA_QUICKDRAW" + fi + fi + + if [ "$with_zlib" != "0" ]; then + CFLAGS="$CFLAGS -DWITH_ZLIB" + CFLAGS="$CFLAGS `$zlib_config --cflags | tr '\n\r' ' '`" + if [ "$enable_static" != "0" ]; then + LIBS="$LIBS `$zlib_config --libs --static | tr '\n\r' ' '`" + else + LIBS="$LIBS `$zlib_config --libs | tr '\n\r' ' '`" + fi + fi + + if [ -n "$lzma_config" ]; then + CFLAGS="$CFLAGS -DWITH_LIBLZMA" + CFLAGS="$CFLAGS `$lzma_config --cflags | tr '\n\r' ' '`" + + if [ "$enable_static" != "0" ]; then + CFLAGS="$CFLAGS -DLZMA_API_STATIC" + LIBS="$LIBS `$lzma_config --libs --static | tr '\n\r' ' '`" + else + LIBS="$LIBS `$lzma_config --libs | tr '\n\r' ' '`" + fi + fi + + if [ -n "$zstd_config" ]; then + CFLAGS="$CFLAGS -DWITH_ZSTD" + CFLAGS="$CFLAGS `$zstd_config --cflags | tr '\n\r' ' '`" + + if [ "$enable_static" != "0" ]; then + LIBS="$LIBS `$zstd_config --libs --static | tr '\n\r' ' '`" + else + LIBS="$LIBS `$zstd_config --libs | tr '\n\r' ' '`" + fi + fi + + if [ "$with_lzo2" != "0" ]; then + if [ "$enable_static" != "0" ] && [ "$os" != "OSX" ]; then + LIBS="$LIBS $lzo2" + else + LIBS="$LIBS -llzo2" + fi + CFLAGS="$CFLAGS -DWITH_LZO" + fi + + if [ -n "$xdg_basedir_config" ]; then + CFLAGS="$CFLAGS -DWITH_XDG_BASEDIR" + CFLAGS="$CFLAGS `$xdg_basedir_config --cflags | tr '\n\r' ' '`" + + if [ "$enable_static" != "0" ]; then + LIBS="$LIBS `$xdg_basedir_config --libs --static | tr '\n\r' ' '`" + else + LIBS="$LIBS `$xdg_basedir_config --libs | tr '\n\r' ' '`" + fi + fi + + # 64bit machines need -D_SQ64 + if [ "$cpu_type" = "64" ] && [ "$enable_universal" = "0" ]; then + CFLAGS="$CFLAGS -D_SQ64" + fi + CFLAGS="$CFLAGS -I$SCRIPT_SRC_DIR" + + if [ -n "$png_config" ]; then + CFLAGS="$CFLAGS -DWITH_PNG" + CFLAGS="$CFLAGS `$png_config --cflags | tr '\n\r' ' '`" + + if [ "$enable_static" != "0" ]; then + LIBS="$LIBS `$png_config --libs --static | tr '\n\r' ' '`" + else + LIBS="$LIBS `$png_config --libs | tr '\n\r' ' '`" + fi + fi + + if [ -n "$fontconfig_config" ]; then + CFLAGS="$CFLAGS -DWITH_FONTCONFIG" + CFLAGS="$CFLAGS `$fontconfig_config --cflags | tr '\n\r' ' '`" + + if [ "$enable_static" != "0" ]; then + LIBS="$LIBS `$fontconfig_config --libs --static | tr '\n\r' ' '`" + else + LIBS="$LIBS `$fontconfig_config --libs | tr '\n\r' ' '`" + fi + fi + + if [ -n "$freetype_config" ]; then + CFLAGS="$CFLAGS -DWITH_FREETYPE" + CFLAGS="$CFLAGS `$freetype_config --cflags | tr '\n\r' ' '`" + + if [ "$enable_static" != "0" ]; then + LIBS="$LIBS `$freetype_config --libs --static | tr '\n\r' ' '` -lfreetype" + else + LIBS="$LIBS `$freetype_config --libs | tr '\n\r' ' '`" + fi + fi + + if [ -n "$icu_layout_config" ]; then + CFLAGS="$CFLAGS -DWITH_ICU_LX" + CFLAGS="$CFLAGS `$icu_layout_config --cflags | tr '\n\r' ' '`" + + if [ "$static_icu" != "0" ]; then + LIBS="$LIBS `$icu_layout_config --libs --static | tr '\n\r' ' ' | sed s/-licu/-lsicu/g`" + else + LIBS="$LIBS `$icu_layout_config --libs | tr '\n\r' ' '`" + fi + fi + + if [ -n "$icu_sort_config" ]; then + CFLAGS="$CFLAGS -DWITH_ICU_I18N" + CFLAGS="$CFLAGS `$icu_sort_config --cflags | tr '\n\r' ' '`" + + if [ "$static_icu" != "0" ]; then + LIBS="$LIBS `$icu_sort_config --libs --static | tr '\n\r' ' ' | sed s/-licu/-lsicu/g`" + else + LIBS="$LIBS `$icu_sort_config --libs | tr '\n\r' ' '`" + fi + fi + + if [ "$with_uniscribe" != "0" ]; then + CFLAGS="$CFLAGS -DWITH_UNISCRIBE" + LIBS="$LIBS -lusp10" + fi + + if [ "$with_direct_music" != "0" ]; then + CFLAGS="$CFLAGS -DWIN32_ENABLE_DIRECTMUSIC_SUPPORT" + # GCC 4.0+ doesn't like the DirectX includes (gives tons of + # warnings on it we won't be able to fix). For now just + # suppress those warnings. + if [ $cc_version -ge 400 ]; then + CFLAGS="$CFLAGS -Wno-non-virtual-dtor" + fi + fi + + if [ "$with_xaudio2" != "0" ]; then + CFLAGS="$CFLAGS -DWITH_XAUDIO2" + fi + + if [ -n "$fluidsynth" ]; then + LIBS="$LIBS -lfluidsynth" + CFLAGS="$CFLAGS -DFLUIDSYNTH" + fi + + if [ "$with_iconv" != "0" ]; then + CFLAGS="$CFLAGS -DWITH_ICONV" + if [ "$link_to_iconv" = "yes" ]; then + LIBS="$LIBS -liconv" + if [ "$with_iconv" != "2" ]; then + CFLAGS="$CFLAGS -I$with_iconv/include" + LIBS="$LIBS -L$with_iconv/lib" + fi + fi + + if [ "$os" != "OSX" ] && [ "$have_non_const_iconv" != "no" ]; then + CFLAGS="$CFLAGS -DHAVE_NON_CONST_ICONV" + fi + fi + + if [ -n "$with_midi" ]; then + CFLAGS="$CFLAGS -DEXTERNAL_PLAYER=\\\\\"$with_midi\\\\\"" + fi + if [ -n "$with_midi_arg" ]; then + CFLAGS="$CFLAGS -DMIDI_ARG=\\\\\"$with_midi_arg\\\\\"" + fi + + if [ "$enable_dedicated" != "0" ]; then + CFLAGS="$CFLAGS -DDEDICATED" + fi + + if [ "$enable_unicode" != "0" ]; then + CFLAGS="$CFLAGS -DUNICODE -D_UNICODE" + fi + + if [ "$os" = "HAIKU" ]; then + LDFLAGS="$LDFLAGS -lnetwork" + fi + + if [ "$os" = "SUNOS" ]; then + LDFLAGS="$LDFLAGS -lnsl -lsocket" + fi + + if [ "$enable_static" != "0" ]; then + # OSX can't handle -static in LDFLAGS + if [ "$os" != "OSX" ]; then + LDFLAGS="$LDFLAGS -static" + fi + fi + + if [ "$enable_assert" = "0" ]; then + CFLAGS="$CFLAGS -DNDEBUG" + CFLAGS_BUILD="$CFLAGS_BUILD -DNDEBUG" + fi + + if [ "$enable_desync_debug" != "0" ]; then + CFLAGS="$CFLAGS -DRANDOM_DEBUG" + fi + + if [ "$enable_osx_g5" != "0" ]; then + CFLAGS="$CFLAGS -mcpu=G5 -mpowerpc64 -mtune=970 -mcpu=970 -mpowerpc-gpopt" + fi + + if [ -n "$personal_dir" ]; then + CFLAGS="$CFLAGS -DWITH_PERSONAL_DIR -DPERSONAL_DIR=\\\\\"$personal_dir\\\\\"" + fi + + if [ -n "$shared_dir" ]; then + CFLAGS="$CFLAGS -DWITH_SHARED_DIR -DSHARED_DIR=\\\\\"$shared_dir\\\\\"" + fi + + CFLAGS="$CFLAGS -DGLOBAL_DATA_DIR=\\\\\"$prefix_dir/$data_dir\\\\\"" + + if [ "$enable_lto" != "0" ]; then + lto_build=`echo "$FEATURES_BUILD" | grep "lto"` + lto_host=`echo "$FEATURES" | grep "lto"` + if [ -z "$lto_build$lto_host" ]; then + log 1 "WARNING: you enabled LTO/IPO, but neither build nor host compiler supports it" + log 1 "WARNING: LTO/IPO has been disabled" + fi + if [ -n "$lto_build" ]; then + LDFLAGS_BUILD="$LDFLAGS_BUILD $CFLAGS_BUILD $CXXFLAGS_BUILD" + fi + if [ -n "$lto_host" ]; then + LDFLAGS="$LDFLAGS $CFLAGS $CXXFLAGS" + fi + fi + + # All flags to be extended via the env + CFLAGS_BUILD="$CFLAGS_BUILD $CFLAGS_BUILD_ENV" + CXXFLAGS_BUILD="$CXXFLAGS_BUILD $CXXFLAGS_BUILD_ENV" + LDFLAGS_BUILD="$LDFLAGS_BUILD $LDFLAGS_BUILD_ENV" + CFLAGS="$CFLAGS $CFLAGS_ENV" + CXXFLAGS="$CXXFLAGS $CXXFLAGS_ENV" + LDFLAGS="$LDFLAGS $LDFLAGS_ENV" + + log 1 "using CFLAGS_BUILD... $CFLAGS_BUILD" + log 1 "using CXXFLAGS_BUILD... $CXXFLAGS_BUILD" + log 1 "using LDFLAGS_BUILD... $LDFLAGS_BUILD" + log 1 "using CFLAGS... $CFLAGS" + log 1 "using CXXFLAGS... $CXXFLAGS" + log 1 "using LDFLAGS... $LIBS $LDFLAGS" + + # Makedepend doesn't like something like: -isysroot /OSX/blabla + # so convert it to: -isysroot -OSX/blabla. makedepend just ignores + # any - command it doesn't know, so we are pretty save. + # Lovely hackish, not? + # Btw, this almost always comes from outside the configure, so it is + # not something we can control. + # Also make makedepend aware of compiler's built-in defines. + if [ "$with_makedepend" != "0" ] || [ "$enable_builtin_depend" != "0" ]; then + # Append CXXFLAGS possibly containing -std=c++0x + cflags_makedep="`echo | $cxx_host $CXXFLAGS -E -x c++ -dM - | sed 's@.define @-D@g;s@ .*@ @g;s@(.*)@@g' | tr -d '\r\n'`" + + # Please escape ALL " within ` because e.g. "" terminates the string in some sh implementations + cflags_makedep="$cflags_makedep `echo \"$CFLAGS\" \"$CXXFLAGS\" | sed 's@ /@ -@g;s@-I[ ]*[^ ]*@@g;s@[ ]*-[^D][^ ]*@@g'`" + else + makedepend="" + fi + + if [ "$with_distcc" != "0" ]; then + cc_host="$distcc $cc_host" + cxx_host="$distcc $cxx_host" + log 1 "" + log 1 " NOTICE: remind yourself to use 'make -jN' to make use of distcc" + log 1 "" + fi + + if [ "$with_ccache" != "0" ]; then + cc_host="$ccache $cc_host" + cxx_host="$ccache $cxx_host" + fi +} + +check_compiler() { + # Params: + # $1 - Type for message (build / host) + # $2 - What to fill with the found compiler + # $3 - System to try + # $4 - Compiler to try + # $5 - Env-setting to try + # $6 - GCC alike to try + # $7 - CC alike to try + # $8 - "0" gcc, "1" g++, "2" windres, "3" strip, "4" lipo + # $9 - What the command is to check for + + if [ -n "$4" ]; then + # Check for manual compiler + machine=`$4 $9 2>/dev/null` + ret=$? + eval "$2=\"$4\"" + + log 2 "executing $4 $9" + log 2 " returned $machine" + log 2 " exit code $ret" + + if ( [ -z "$machine" ] && [ "$8" != "3" ] ) || [ "$ret" != "0" ]; then + log 1 "checking $1... $4 not found" + log 1 "the selected binary doesn't seem to be a $6 binary" + exit 1 + fi + elif [ -n "$3" ]; then + # Check for system + if [ -z "$6" ]; then + compiler="$3" + else + compiler="$3-$6" + fi + machine=`eval $compiler $9 2>/dev/null` + ret=$? + eval "$2=\"$compiler\"" + + log 2 "executing $compiler $9" + log 2 " returned $machine" + log 2 " exit code $ret" + + if ( [ -z "$machine" ] && [ "$8" != "3" ] ) || [ "$ret" != "0" ]; then + if [ -z "$5" ]; then + log 1 "checking $1... $compiler not found" + log 1 "I couldn't detect any $6 binary for $3" + exit 1 + else + compiler="$3-$5" + fi + machine=`eval $compiler $9 2>/dev/null` + ret=$? + eval "$2=\"$compiler\"" + + log 2 "executing $compiler $9" + log 2 " returned $machine" + log 2 " exit code $ret" + + if ( [ -z "$machine" ] && [ "$8" != "3" ] ) || [ "$ret" != "0" ]; then + log 1 "checking $1... $compiler not found" + log 1 "I couldn't detect any $5 binary for $3" + exit 1 + fi + fi + + if [ "$machine" != "$3" ] && ( [ "$8" = "0" ] || [ "$8" = "1" ] ); then + log 1 "checking $1... expected $3, found $machine" + log 1 "the compiler suggests it doesn't build code for the machine you specified" + exit 1 + fi + else + # Nothing given, autodetect + + if [ -n "$5" ]; then + machine=`$5 $9 2>/dev/null` + ret=$? + eval "$2=\"$5\"" + + log 2 "executing $5 $9" + log 2 " returned $machine" + log 2 " exit code $ret" + + # The user defined a GCC that doesn't reply to $9.. abort + if ( [ -z "$machine" ] && [ "$8" != "3" ] ) || [ "$ret" != "0" ]; then + log 1 "checking $1... $5 unusable" + log 1 "the CC environment variable is set, but it doesn't seem to be a $6 binary" + log 1 "please redefine the CC/CXX environment to a $6 binary" + exit 1 + fi + else + log 2 "checking $1... CC/CXX not set (skipping)" + + # No $5, so try '$6' + machine=`$6 $9 2>/dev/null` + ret=$? + eval "$2=\"$6\"" + + log 2 "executing $6 $9" + log 2 " returned $machine" + log 2 " exit code $ret" + + if ( [ -z "$machine" ] && [ "$8" != "3" ] ) || [ "$ret" != "0" ]; then + # Maybe '$7'? + machine=`$7 $9 2>/dev/null` + ret=$? + eval "$2=\"$7\"" + + log 2 "executing $7 $9" + log 2 " returned $machine" + log 2 " exit code $ret" + + # All failed, abort + if [ -z "$machine" ]; then + log 1 "checking $1... $6 not found" + log 1 "I couldn't detect any $6 binary on your system" + log 1 "please define the CC/CXX environment to where it is located" + + exit 1 + fi + fi + fi + fi + + if [ "$8" != "0" ]; then + eval "res=\$$2" + log 1 "checking $1... $res" + else + log 1 "checking $1... $machine" + fi +} + +check_build() { + check_compiler "build system type" "cc_build" "$build" "$cc_build" "$CC" "gcc" "cc" "0" "-dumpmachine" +} + +check_host() { + # By default the host is the build + if [ -z "$host" ]; then host="$build"; fi + check_compiler "host system type" "cc_host" "$host" "$cc_host" "$CC" "gcc" "cc" "0" "-dumpmachine" +} + +check_cxx_build() { + check_compiler "build c++" "cxx_build" "$build" "$cxx_build" "$CXX" "g++" "c++" 1 "-dumpmachine" +} + +check_cxx_host() { + # By default the host is the build + if [ -z "$host" ]; then host="$build"; fi + check_compiler "host c++" "cxx_host" "$host" "$cxx_host" "$CXX" "g++" "c++" 1 "-dumpmachine" +} + +check_windres() { + if [ "$os" = "MINGW" ] || [ "$os" = "CYGWIN" ]; then + check_compiler "host windres" "windres" "$host" "$windres" "$WINDRES" "windres" "windres" "2" "-V" + fi +} + +check_strip() { + if [ "$os" = "OS2" ]; then + # OS2 via gcc is a bit weird.. stripping HAS to be done via emxbind, which is via gcc directly + log 1 "checking host strip... using gcc -s option" + elif [ "$os" = "OSX" ]; then + # Most targets have -V in strip, to see if they exists... OSX doesn't.. so execute something + echo "int main(int argc, char *argv[]) { }" > strip.test.c + $cxx_host strip.test.c -o strip.test + check_compiler "host strip" "strip" "$host" "$strip" "$STRIP" "strip" "strip" "3" "strip.test" + rm -f strip.test.c strip.test + else + check_compiler "host strip" "strip" "$host" "$strip" "$STRIP" "strip" "strip" "3" "-V" + fi +} + +check_lipo() { + if [ "$os" = "OSX" ] && [ "$enable_universal" != "0" ]; then + echo "int main(int argc, char *argv[]) { }" > lipo.test.c + $cxx_host lipo.test.c -o lipo.test + check_compiler "host lipo" "lipo" "$host" "$lipo" "$LIPO" "lipo" "lipo" "4" "-info lipo.test" + rm -f lipo.test.c lipo.test + fi +} + +check_osx_sdk() { + local sysroot="" + if [ -n "$1" ]; then + if echo "$1" | grep -q / ; then + # Seems to be a file system path + osx_sdk_path="$1" + else + osx_sdk_path="/Developer/SDKs/MacOSX$1.sdk" + fi + if [ ! -d "$osx_sdk_path" ]; then + # No directory, not present or garbage + return 1 + fi + + # Set minimum version to 10.4 as that's when kCGBitmapByteOrder32Host was introduced + sysroot="-isysroot $osx_sdk_path -Wl,-syslibroot,$osx_sdk_path -mmacosx-version-min=10.4" + fi + +cat > tmp.osx.mm << EOF +#include +int main() { + kCGBitmapByteOrder32Host; + return 0; +} +EOF + execute="$cxx_host $sysroot $CFLAGS tmp.osx.mm -framework Cocoa -o tmp.osx 2>&1" + eval $execute > /dev/null + ret=$? + log 2 "executing $execute" + log 2 " exit code $ret" + rm -f tmp.osx.mm tmp.osx + return $ret +} + +check_direct_music() { + echo " + #include + #include + #include + int main(int argc, char *argv[]) { }" > direct_music.test.c + $cxx_host $CFLAGS direct_music.test.c -o direct_music.test 2> /dev/null + res=$? + rm -f direct_music.test.c direct_music.test + + if [ "$res" != "0" ]; then + if [ "$with_direct_music" != "1" ]; then + log 1 "configure: error: direct-music is not available on this system" + exit 1 + fi + with_direct_music="0" + + log 1 "checking direct-music... not found" + else + log 1 "checking direct-music... found" + fi +} + +check_xaudio2() { + echo " + #include + + #undef NTDDI_VERSION + #undef _WIN32_WINNT + + #define NTDDI_VERSION NTDDI_WIN8 + #define _WIN32_WINNT _WIN32_WINNT_WIN8 + + #include + int main(int argc, char *argv[]) { }" > xaudio2.test.c + $cxx_host $CFLAGS xaudio2.test.c -o xaudio2.test 2> /dev/null + res=$? + rm -f xaudio2.test.c xaudio2.test + + if [ "$res" != "0" ]; then + if [ "$with_xaudio2" != "1" ]; then + log 1 "configure: error: xaudio2 is not available on this system" + exit 1 + fi + with_xaudio2="0" + + log 1 "checking xaudio2... not found" + else + log 1 "checking xaudio2... found" + fi +} + +check_makedepend() { + if [ "$enable_builtin_depend" != "0" ]; then + with_makedepend="0" + fi + + if [ "$with_makedepend" = "0" ]; then + log 1 "checking makedepend... disabled" + return + fi + + if [ "$with_makedepend" = "1" ] || [ "$with_makedepend" = "2" ]; then + makedepend="makedepend" + else + makedepend="$with_makedepend" + fi + + rm -f makedepend.tmp + touch makedepend.tmp + res=`$makedepend -fmakedepend.tmp 2>/dev/null` + res=$? + log 2 "executing $makedepend -f makedepend.tmp" + log 2 " returned `cat makedepend.tmp`" + log 2 " exit code $ret" + + if [ ! -s makedepend.tmp ]; then + rm -f makedepend.tmp makedepend.tmp.bak + + if [ "$with_makedepend" = "2" ]; then + log 1 "checking makedepend... not found" + + log 1 "I couldn't detect any makedepend on your system" + log 1 "please locate it via --makedepend=[binary]" + + exit 1 + elif [ "$with_makedepend" != "1" ]; then + log 1 "checking makedepend... $makedepend not found" + + log 1 "the selected file doesn't seem to be a valid makedepend binary" + + exit 1 + else + log 1 "checking makedepend... not found" + + with_makedepend="0" + return + fi + fi + + rm -f makedepend.tmp makedepend.tmp.bak + + log 1 "checking makedepend... $makedepend" +} + +check_version() { + # $1 - requested version (major.minor) + # $2 - version we got (major.minor) + + if [ -z "$2" ]; then + return 0 + fi + + req_major=`echo $1 | cut -d. -f1` + got_major=`echo $2 | cut -d. -f1` + if [ $got_major -lt $req_major ]; then + return 0 + elif [ $got_major -gt $req_major ]; then + return 1 + fi + + req_minor=`echo $1 | cut -d. -f2` + got_minor=`echo $2 | cut -d. -f2` + if [ $got_minor -lt $req_minor ]; then + return 0 + fi + return 1 +} + +detect_awk() { + # Not all awks allow gsub(), so we test for that here! It is in fact all we need... + + # These awks are known to work. Test for them explicit + awks="gawk mawk nawk" + + awk_prefix="echo \"a.c b.c c.c\" | tr ' ' \\\\n | " + awk_param="' { ORS = \" \" } /\.c$/ { gsub(\".c$\", \".o\", \$0); print \$0; }' 2>/dev/null" + awk_result="a.o b.o c.o " + log 2 "Detecing awk..." + + log 2 "Trying: $awk_prefix $awk $awk_param" + res=`eval $awk_prefix $awk $awk_param` + log 2 "Result: '$res'" + if [ "$res" != "$awk_result" ] && [ "$awk" = "awk" ]; then + # User didn't supply his own awk, so try to detect some other known working names for an awk + for awk in $awks; do + log 2 "Trying: $awk_prefix $awk $awk_param" + res=`eval $awk_prefix $awk $awk_param` + log 2 "Result: '$res'" + if [ "$res" = "$awk_result" ]; then break; fi + done + + if [ "$res" != "$awk_result" ]; then + log 1 "checking awk... not found" + log 1 "configure: error: no awk found" + log 1 "configure: error: please install one of the following: $awks" + exit 1 + fi + fi + if [ "$res" != "$awk_result" ]; then + log 1 "checking awk... not found" + log 1 "configure: error: you supplied '$awk' but it doesn't seem a valid gawk or mawk" + exit 1 + fi + + log 1 "checking awk... $awk" +} + +detect_os() { + if [ "$os" = "DETECT" ]; then + # Detect UNIX, OSX, FREEBSD, DRAGONFLY, OPENBSD, NETBSD, HPUX, SUNOS, CYGWIN, MINGW, and OS2 + + # Try first via dumpmachine, then via uname + os=`echo "$host" | tr '[A-Z]' '[a-z]' | $awk ' + /linux/ { print "UNIX"; exit} + /darwin/ { print "OSX"; exit} + /freebsd/ { print "FREEBSD"; exit} + /dragonfly/ { print "DRAGONFLY"; exit} + /openbsd/ { print "OPENBSD"; exit} + /netbsd/ { print "NETBSD"; exit} + /hp-ux/ { print "HPUX"; exit} + /haiku/ { print "HAIKU"; exit} + /sunos/ { print "SUNOS"; exit} + /solaris/ { print "SUNOS"; exit} + /cygwin/ { print "CYGWIN"; exit} + /mingw/ { print "MINGW"; exit} + /os2/ { print "OS2"; exit} + '` + + if [ -z "$os" ]; then + os=`LC_ALL=C uname | tr '[A-Z]' '[a-z]' | $awk ' + /linux/ { print "UNIX"; exit} + /darwin/ { print "OSX"; exit} + /freebsd/ { print "FREEBSD"; exit} + /dragonfly/ { print "DRAGONFLY"; exit} + /openbsd/ { print "OPENBSD"; exit} + /netbsd/ { print "NETBSD"; exit} + /hp-ux/ { print "HPUX"; exit} + /haiku/ { print "HAIKU"; exit} + /sunos/ { print "SUNOS"; exit} + /cygwin/ { print "CYGWIN"; exit} + /mingw/ { print "MINGW"; exit} + /os\/2/ { print "OS2"; exit} + /gnu/ { print "UNIX"; exit} + '` + fi + + if [ -z "$os" ]; then + log 1 "detecting OS... none detected" + log 1 "I couldn't detect your OS. Please use --os=OS to force one" + log 1 "Allowed values are: UNIX, OSX, FREEBSD, DRAGONFLY, OPENBSD, NETBSD, HPUX, HAIKU, SUNOS, CYGWIN, MINGW, and OS2" + exit 1 + fi + + log 1 "detecting OS... $os" + else + log 1 "forcing OS... $os" + fi +} + +detect_allegro() { + # 0 means no, 1 is auto-detect, 2 is force + if [ "$with_allegro" = "0" ]; then + log 1 "checking Allegro... disabled" + + allegro_config="" + return 0 + fi + + if [ "$with_allegro" = "2" ] && [ "$with_cocoa" = "2" ]; then + log 1 "configure: error: it is impossible to compile both Allegro and COCOA" + log 1 "configure: error: please deselect one of them and try again" + exit 1 + fi + + if [ "$with_allegro" = "2" ] && [ "$enable_dedicated" != "0" ]; then + log 1 "configure: error: it is impossible to compile a dedicated with Allegro" + log 1 "configure: error: please deselect one of them and try again" + exit 1 + fi + + if [ "$enable_dedicated" != "0" ]; then + log 1 "checking Allegro... dedicated server, skipping" + + allegro_config="" + return 0 + fi + + # By default on OSX we don't use Allegro. The rest is auto-detect + if [ "$with_allegro" = "1" ] && [ "$os" = "OSX" ] && [ "$with_cocoa" != "0" ]; then + log 1 "checking Allegro... OSX, skipping" + + allegro_config="" + return 0 + fi + + detect_pkg_config "$with_allegro" "allegro" "allegro_config" "4.4" +} + + +detect_sdl() { + # 0 means no, 1 is auto-detect, 2 is force + if [ "$with_sdl" = "0" ]; then + log 1 "checking SDL... disabled" + + sdl_config="" + sdl2_config="" + return 0 + fi + + if [ "$with_sdl" != "1" ] && [ "$with_cocoa" = "2" ]; then + log 1 "configure: error: it is impossible to compile both SDL and COCOA" + log 1 "configure: error: please deselect one of them and try again" + exit 1 + fi + + if [ "$with_sdl" != "1" ] && [ "$enable_dedicated" != "0" ]; then + log 1 "configure: error: it is impossible to compile a dedicated with SDL" + log 1 "configure: error: please deselect one of them and try again" + exit 1 + fi + + if [ "$enable_dedicated" != "0" ]; then + log 1 "checking SDL... dedicated server, skipping" + + sdl_config="" + sdl2_config="" + return 0 + fi + + # By default on OSX we don't use SDL. The rest is auto-detect + if [ "$with_sdl" = "1" ] && [ "$os" = "OSX" ] && [ "$with_cocoa" != "0" ]; then + log 1 "checking SDL... OSX, skipping" + + sdl_config="" + return 0 + fi + + if [ "$os" = "OSX" ]; then + log 1 "WARNING: sdl is known to fail on some versions of Mac OS X" + log 1 "WARNING: with some hardware configurations. Use at own risk!" + sleep 5 + fi + + if [ $with_sdl = "sdl1" ]; then + detect_pkg_config "2" "sdl" "sdl_config" "1.2" + elif [ $with_sdl = "sdl2" ]; then + detect_pkg_config "2" "sdl2" "sdl2_config" "2.0" + else + sdl2_config="" + if [ -x "`which sdl2-config`" ]; then + detect_pkg_config "$with_sdl" "sdl2" "sdl2_config" "2.0" + fi + if [ -z "$sdl2_config" ]; then + detect_pkg_config "$with_sdl" "sdl" "sdl_config" "1.2" + fi + fi +} + +detect_osx_sdk() { + # Try to find the best SDK available. For a normal build this + # is currently the 10.5 SDK as this is needed to compile all + # optional code. Because such an executable won't run on 10.4 + # or lower, also check for the 10.4u SDK when doing an universal + # build. + + # Check for the 10.5 SDK, but try 10.6 if that fails + check_osx_sdk "10.5" || check_osx_sdk "10.6" || osx_sdk_path="" + + if [ -z "$osx_sdk_path" ] || [ "$enable_universal" != "0" ]; then + # No better SDK or universal build enabled? Check 10.4u SDK as well + local old_sdk="$osx_sdk_path" + if check_osx_sdk "10.4u"; then + osx_sdk_104_path="$osx_sdk_path" + else + osx_sdk_104_path="" + fi + if [ -z "$old_sdk" ]; then + osx_sdk_path="$osx_sdk_104_path" + else + osx_sdk_path="$old_sdk" + fi + fi + + if [ -z "$osx_sdk_path" ]; then + log 1 "Your system SDK is probably too old" + log 1 "Please install/upgrade your Xcode to >= 2.5" + + exit 1 + fi +} + +detect_cocoa() { + # 0 means no, 1 is auto-detect, 2 is force + if [ "$with_cocoa" = "0" ]; then + log 1 "checking COCOA... disabled" + + return 0 + fi + + if [ "$with_cocoa" = "2" ] && [ "$enable_dedicated" != "0" ]; then + log 1 "configure: error: it is impossible to compile a dedicated with COCOA" + log 1 "configure: error: please deselect one of them and try again" + exit 1 + fi + + if [ "$enable_dedicated" != "0" ]; then + log 1 "checking COCOA... dedicated server, skipping" + + with_cocoa="0" + return 0 + fi + + # By default on OSX we use COCOA. The rest doesn't support it + if [ "$with_cocoa" = "1" ] && [ "$os" != "OSX" ]; then + log 1 "checking COCOA... not OSX, skipping" + + with_cocoa="0" + return 0 + fi + + if [ "$os" != "OSX" ]; then + log 1 "checking COCOA... not OSX" + + log 1 "configure: error: COCOA video driver is only supported for OSX" + exit 1 + fi + + log 1 "checking COCOA... found" + + + if [ "$enable_cocoa_quartz" != "0" ]; then + log 1 "checking whether to enable the Quartz window subdriver... yes" + else + log 1 "checking whether to enable the Quartz window subdriver... no" + fi + + detect_quickdraw +} + +detect_quickdraw() { + # 0 means no, 1 is auto-detect, 2 is force + if [ "$enable_cocoa_quickdraw" = "0" ]; then + log 1 "checking Quickdraw window subdriver... disabled" + return 0 + fi + + # Assume QuickDraw is available when doing an universal build + if [ "$enable_universal" != "0" ]; then + log 1 "checking Quickdraw window subdriver... found" + return 0 + fi + + # 64 bits doesn't have quickdraw + if [ "$cpu_type" = "64" ]; then + enable_cocoa_quickdraw="0" + log 1 "checking Quickdraw window subdriver... disabled (64 bits)" + return 0 + fi + +cat > tmp.osx.mm << EOF +#include +#import +int main(int argc, char *argv[]) { SetEmptyRgn(NULL); return 0; } +EOF + execute="$cxx_host $OSX_SYSROOT $OSX_LD_SYSROOT $CFLAGS -mmacosx-version-min=10.3 tmp.osx.mm -framework Cocoa -o tmp.osx 2>&1" + eval $execute > /dev/null + ret=$? + log 2 "executing $execute" + log 2 " exit code $ret" + rm -f tmp.osx.mm tmp.osx + if [ "$ret" != "0" ]; then + log 1 "checking Quickdraw window subdriver... not found" + + # It was forced, so it should be found. + if [ "$enable_cocoa_quickdraw" != "1" ]; then + log 1 "configure: error: Quickdraw window driver could not be found" + exit 1 + fi + + enable_cocoa_quickdraw=0 + return 0 + fi + + enable_cocoa_quickdraw=1 + log 1 "checking Quickdraw window subdriver... found" +} + +detect_library() { + # $1 - config-param ($with_zlib value) + # $2 - library name ('zlib', sets $zlib) + # $3 - static library name (libz.a) + # $4 - header directory () + # $5 - header name (zlib.h) + # $6 - force static (if non-empty) + + if [ -n "$6" ]; then force_static="1"; fi + + # 0 means no, 1 is auto-detect, 2 is force + if [ "$1" = "0" ]; then + log 1 "checking $2... disabled" + + eval "$2=\"\"" + return 0 + fi + + log 2 "detecting $2" + + if [ "$1" = "1" ] || [ "$1" = "" ] || [ "$1" = "2" ]; then + eval "$2=`ls -1 /usr/include/$4*.h 2>/dev/null | egrep \"\/$5\$\"`" + eval "res=\$$2" + if [ -z "$res" ]; then + log 2 " trying /usr/include/$4$5... no" + eval "$2=`ls -1 /usr/local/include/$4*.h 2>/dev/null | egrep \"\/$5\$\"`" + fi + eval "res=\$$2" + if [ -z "$res" ]; then + log 2 " trying /usr/local/include/$4$5... no" + eval "$2=`ls -1 /mingw/include/$4*.h 2>/dev/null | egrep \"\/$5\$\"`" + fi + eval "res=\$$2" + if [ -z "$res" ]; then + log 2 " trying /mingw/include/$4$5... no" + eval "$2=`ls -1 /mingw$cpu_type/include/$4*.h 2>/dev/null | egrep \"\/$5\$\"`" + fi + eval "res=\$$2" + if [ -z "$res" ]; then + log 2 " trying /mingw$cpu_type/include/$4$5... no" + eval "$2=`ls -1 /opt/local/include/$4*.h 2>/dev/null | egrep \"\/$5\$\"`" + fi + eval "res=\$$2" + if [ -z "$res" ]; then + log 2 " trying /opt/local/include/$4$5... no" + fi + if [ -z "$res" ] && [ "$os" = "NETBSD" ]; then + eval "$2=`ls -1 /usr/pkg/include/$4*.h 2>/dev/null | egrep \"\/$5\$\"`" + eval "res=\$$2" + if [ -z "$res" ]; then + log 2 " trying /usr/pkg/include/$4$5... no" + fi + fi + if [ -z "$res" ] && [ "$os" = "HAIKU" ]; then + if [ -z "$includeDir" ]; then + includeDir=`finddir B_SYSTEM_HEADERS_DIRECTORY` + fi + eval "$2=`ls -1 $includeDir/$4*.h 2>/dev/null | egrep \"\/$5\$\"`" + eval "res=\$$2" + if [ -z "$res" ]; then + log 2 " trying $includeDir/$4$5... no" + fi + fi + + eval "res=\$$2" + if [ -n "$res" ] && ( [ -n "$force_static" ] || ( [ "$enable_static" != "0" ] && [ "$os" != "OSX" ] ) ); then + eval "res=\$$2" + log 2 " trying $res... found" + # Now find the static lib, if needed + eval "$2=`ls /lib/*.a 2>/dev/null | egrep \"\/$3\$\"`" + eval "res=\$$2" + if [ -z "$res" ]; then + log 2 " trying /lib/$3... no" + eval "$2=`ls /usr/lib/*.a 2>/dev/null | egrep \"\/$3\$\"`" + fi + eval "res=\$$2" + if [ -z "$res" ]; then + log 2 " trying /usr/lib/$3... no" + eval "$2=`ls /usr/local/lib/*.a 2>/dev/null | egrep \"\/$3\$\"`" + fi + eval "res=\$$2" + if [ -z "$res" ]; then + log 2 " trying /usr/local/lib/$3... no" + eval "$2=`ls /mingw/lib/*.a 2>/dev/null | egrep \"\/$3\$\"`" + fi + eval "res=\$$2" + if [ -z "$res" ]; then + log 2 " trying /mingw/lib/$3... no" + eval "$2=`ls /mingw$cpu_type/lib/*.a 2>/dev/null | egrep \"\/$3\$\"`" + fi + eval "res=\$$2" + if [ -z "$res" ]; then + log 2 " trying /mingw$cpu_type/lib/$3... no" + log 1 "configure: error: $2 couldn't be found" + log 1 "configure: error: you requested a static link, but I can't find $3" + + exit 1 + fi + fi + else + # Make sure it exists + if [ -f "$1" ]; then + eval "$2=`ls $1 2>/dev/null`" + else + eval "$2=`ls $1/$3 2>/dev/null`" + fi + fi + + eval "res=\$$2" + if [ -z "$res" ]; then + log 1 "checking $2... not found" + if [ "$1" = "2" ]; then + log 1 "configure: error: $2 couldn't be found" + + exit 1 + elif [ "$1" != "1" ]; then + log 1 "configure: error: $2 couldn't be found" + log 1 "configure: error: you supplied '$1', but it seems invalid" + + exit 1 + fi + + eval "with_$2=0" + + return 0 + fi + + eval "res=\$$2" + log 2 " trying $res... found" + + log 1 "checking $2... found" +} + +detect_zlib() { + detect_pkg_config "$with_zlib" "zlib" "zlib_config" "1.2" +} + +detect_lzo2() { + detect_library "$with_lzo2" "lzo2" "liblzo2.a" "lzo/" "lzo1x.h" +} + +detect_fluidsynth() { + detect_library "$with_fluidsynth" "fluidsynth" "" "" "fluidsynth.h" +} + +detect_pkg_config() { + # $1 - config-param ($with_lzma value) + # $2 - package name ('liblzma') + # $3 - config name ('lzma_config', sets $lzma_config) + # $4 - minimum module version ('2.3') + # $5 - check for dedicated, 1 is "skif if dedicated" + + # 0 means no, 1 is auto-detect, 2 is force + if [ "$1" = "0" ]; then + log 1 "checking $2... disabled" + + eval "$3=\"\"" + return 0 + fi + + if [ "$5" = "1" ] && [ "$1" = "1" ] && [ "$enable_dedicated" != "0" ]; then + log 1 "checking $2... dedicated server, skipping" + + eval "$3=\"\"" + return 0 + fi + + log 2 "detecting $2" + + if [ "$1" = "1" ] || [ "$1" = "" ] || [ "$1" = "2" ]; then + pkg_config_call="$pkg_config $2" + else + pkg_config_call="$1" + fi + + version=`$pkg_config_call --modversion 2>/dev/null` + ret=$? + check_version "$4" "$version" + version_ok=$? + log 2 "executing $pkg_config_call --modversion" + log 2 " returned $version" + log 2 " exit code $ret" + + if [ -z "$version" ] || [ "$ret" != "0" ] || [ "$version_ok" != "1" ]; then + if [ -n "$version" ] && [ "$version_ok" != "1" ]; then + log 1 "checking $2... needs at least version $4, $2 NOT enabled" + else + log 1 "checking $2... not found" + fi + + # It was forced, so it should be found. + if [ "$1" != "1" ]; then + log 1 "configure: error: $pkg_config $2 couldn't be found" + log 1 "configure: error: you supplied '$1', but it seems invalid" + exit 1 + fi + + eval "$3=\"\"" + return 0 + fi + + eval "$3=\"$pkg_config_call\"" + log 1 "checking $2... found" +} + +detect_lzma() { + detect_pkg_config "$with_lzma" "liblzma" "lzma_config" "5.0" +} + +detect_zstd() { + detect_pkg_config "$with_zstd" "libzstd" "zstd_config" "1.4" +} + +detect_xdg_basedir() { + detect_pkg_config "$with_xdg_basedir" "libxdg-basedir" "xdg_basedir_config" "1.2" +} + +detect_png() { + detect_pkg_config "$with_png" "libpng" "png_config" "1.2" +} + +detect_freetype() { + if [ "$with_freetype" = "1" ] && ([ "$os" = "MINGW" ] || [ "$os" = "CYGWIN" ]); then + log 1 "checking freetype2... WIN32, skipping" + freetype_config="" + return 0 + fi + + detect_pkg_config "$with_freetype" "freetype2" "freetype_config" "2.2" "1" +} + +detect_fontconfig() { + # 0 means no, 1 is auto-detect, 2 is force + if [ "$with_fontconfig" = "0" ]; then + log 1 "checking libfontconfig... disabled" + + fontconfig_config="" + return 0 + fi + if [ "$os" = "MINGW" ] || [ "$os" = "CYGWIN" ]; then + log 1 "checking libfontconfig... WIN32, skipping" + fontconfig_config="" + return 0 + fi + + if [ "$os" = "OSX" ]; then + log 1 "checking libfontconfig... OSX, skipping" + fontconfig_config="" + return 0 + fi + + detect_pkg_config "$with_fontconfig" "fontconfig" "fontconfig_config" "2.3" "1" +} + +detect_icu_layout() { + if [ "$with_cocoa" != "0" ] && [ "$with_icu_layout" = "1" ]; then + log 1 "checking icu-lx... OSX, skipping" + icu_layout_config="" + return 0 + fi + + detect_pkg_config "$with_icu_layout" "icu-lx" "icu_layout_config" "4.8" "1" +} + +detect_icu_sort() { + if [ "$with_cocoa" != "0" ] && [ "$with_icu_sort" = "1" ]; then + log 1 "checking icu-i18n... OSX, skipping" + icu_sort_config="" + return 0 + fi + + detect_pkg_config "$with_icu_sort" "icu-i18n" "icu_sort_config" "4.8" "1" +} + +detect_iconv() { + # 0 means no, 1 is auto-detect, 2 is force + if [ "$with_iconv" = "0" ]; then + log 1 "checking iconv... disabled" + + return 0 + fi + + if [ "$with_iconv" = "1" ] && [ "$os" != "OSX" ]; then + log 1 "checking iconv... not OSX, skipping" + with_iconv="0" + + return 0 + fi + + # Try to find iconv.h, seems to only thing to detect iconv with + + if [ "$with_iconv" = "1" ] || [ "$with_iconv" = "" ] || [ "$with_iconv" = "2" ]; then + # Iterate over search paths + iconv="" + search_paths=`LC_ALL=C $cxx_host $OSX_SYSROOT $CFLAGS -E - -v &1 | \ + $awk '/#include <...> search starts here:/{flag=1;next}/End of search list./{flag=0}flag'` + for path in $search_paths; do + iconv=`ls -1 $path 2>/dev/null | grep "iconv.h"` + if [ -n "$iconv" ]; then + break + fi + done + else + # Make sure it exists + iconv=`ls $with_iconv/include/iconv.h 2>/dev/null` + fi + + if [ -z "$iconv" ]; then + log 1 "checking iconv... not found" + if [ "$with_iconv" = "2" ]; then + log 1 "configure: error: iconv couldn't be found" + + exit 1 + elif [ "$with_iconv" != "1" ]; then + log 1 "configure: error: iconv couldn't be found" + log 1 "configure: error: you supplied '$with_iconv', but I couldn't detect iconv in it" + + exit 1 + fi + + return 0 + fi + + if [ "$with_iconv" = "1" ]; then + with_iconv="2" + fi + + log 2 "found iconv in $iconv" + + log 1 "checking iconv... found" + + # There are different implementations of iconv. The older ones, + # e.g. SUSv2, pass a const pointer, whereas the newer ones, e.g. + # IEEE 1003.1 (2004), pass a non-const pointer. + + cat > tmp.iconv.cpp << EOF +#include "src/stdafx.h" +#include +int main() { + static char buf[1024]; + iconv_t convd = 0; + const char *inbuf = ""; + char *outbuf = buf; + size_t outlen = 1023; + size_t inlen = 0; + return iconv(convd, &inbuf, &inlen, &outbuf, &outlen); +} +EOF + execute="$cxx_host $OSX_SYSROOT $CFLAGS -c tmp.iconv.cpp -o tmp.iconv -DTESTING 2>&1" + eval $execute > /dev/null + ret=$? + log 2 "executing $execute" + log 2 " exit code $ret" + if [ "$ret" = "0" ]; then have_non_const_iconv="no"; else have_non_const_iconv="yes"; fi + log 1 "checking if iconv has non-const inbuf... $have_non_const_iconv" + + cat > tmp.iconv.cpp << EOF +#include "src/stdafx.h" +#include +int main() { + static char buf[1024]; + iconv_t convd = 0; + char *inbuf = ""; + char *outbuf = buf; + size_t outlen = 1023; + size_t inlen = 0; + return iconv(convd, &inbuf, &inlen, &outbuf, &outlen); +} +EOF + execute="$cxx_host $OSX_SYSROOT $OSX_LD_SYSROOT $CFLAGS tmp.iconv.cpp -o tmp.iconv -DTESTING 2>&1" + eval $execute > /dev/null + ret=$? + log 2 "executing $execute" + log 2 " exit code $ret" + if [ "$ret" = "0" ]; then link_to_iconv="no"; else link_to_iconv="yes"; fi + log 1 "checking whether to link to iconv... $link_to_iconv" + rm -f tmp.iconv tmp.iconv.cpp +} + +_detect_sort() { + sort_test_in="d +a +c +b" + + sort_test_out="a +b +c +d" + + log 2 "running echo | $1" + + if [ "`echo \"$sort_test_in\" | $1 2>/dev/null`" = "$sort_test_out" ]; then + sort="$1" + log 2 " result was valid" + else + log 2 " result was invalid" + fi +} + +detect_sort() { + if [ "$with_sort" = "0" ]; then + log 1 "checking sort... disabled" + + return + fi + + if [ "$with_sort" = "1" ] || [ "$with_sort" = "2" ]; then + _detect_sort "sort" + if [ -z "$sort" ]; then _detect_sort "/sbin/sort"; fi + if [ -z "$sort" ]; then _detect_sort "/usr/sbin/sort"; fi + if [ -z "$sort" ]; then _detect_sort "/usr/local/sbin/sort"; fi + if [ -z "$sort" ]; then _detect_sort "/bin/sort"; fi + if [ -z "$sort" ]; then _detect_sort "/usr/bin/sort"; fi + if [ -z "$sort" ]; then _detect_sort "/usr/local/bin/sort"; fi + else + _detect_sort "$with_sort" + fi + + if [ -z "$sort" ]; then + if [ "$with_sort" = "2" ]; then + log 1 "checking sort... not found" + + log 1 "configure: error: couldn't detect sort on your system" + exit 1 + elif [ "$with_sort" != "1" ]; then + log 1 "checking sort... $with_sort not found" + + log 1 "configure: error: '$with_sort' doesn't look like a sort to me" + log 1 "configure: error: please verify its location and function and try again" + + exit 1 + else + log 1 "checking sort... not found" + fi + else + log 1 "checking sort... $sort" + fi +} + +detect_grfcodec() { + # 0 means no, 1 is auto-detect, 2 is force + if [ "$with_grfcodec" = "0" ]; then + log 1 "checking grfcodec... disabled" + + grfcodec="" + return 0 + fi + + if [ "$with_grfcodec" = "1" ] || [ "$with_grfcodec" = "" ] || [ "$with_grfcodec" = "2" ]; then + grfcodec="grfcodec" + else + grfcodec="$with_grfcodec" + fi + + version=`$grfcodec -v 2>/dev/null | $awk '{print $3}' | sed 's/[rM]//g;s/-/0/'` + ret=$? + log 2 "executing grfcodec -v" + log 2 " returned $version" + log 2 " exit code $ret" + + if [ -z "$version" ] || [ "$ret" != "0" ] || [ "$version" -lt "985" ]; then + if [ -n "$version" ] && [ "$version" -lt "985" ]; then + log 1 "checking grfcodec... needs at least version 6.0.5 (r985), disabled" + else + log 1 "checking grfcodec... not found" + fi + + # It was forced, so it should be found. + if [ "$with_grfcodec" != "1" ]; then + log 1 "configure: error: grfcodec couldn't be found" + log 1 "configure: error: you supplied '$with_grfcodec', but it seems invalid" + exit 1 + fi + + grfcodec="" + return 0 + fi + + log 1 "checking grfcodec... found" +} + +detect_nforenum() { + # 0 means no, 1 is auto-detect, 2 is force + if [ "$with_nforenum" = "0" ]; then + log 1 "checking nforenum... disabled" + + nforenum="" + return 0 + fi + + if [ "$with_nforenum" = "1" ] || [ "$with_nforenum" = "" ] || [ "$with_nforenum" = "2" ]; then + nforenum="nforenum" + else + nforenum="$with_nforenum" + fi + + version=`$nforenum -v 2>/dev/null | $awk '{print $3}' | sed 's/[rM]//g;s/-/0/'` + ret=$? + log 2 "executing nforenum -v" + log 2 " returned $version" + log 2 " exit code $ret" + + if [ -z "$version" ] || [ "$ret" != "0" ] || [ "$version" -lt "985" ]; then + if [ -n "$version" ] && [ "$version" -lt "985" ]; then + log 1 "checking nforenum... needs at least version 6.0.5 (r985), disabled" + else + log 1 "checking nforenum... not found" + fi + + # It was forced, so it should be found. + if [ "$with_nforenum" != "1" ]; then + log 1 "configure: error: nforenum couldn't be found" + log 1 "configure: error: you supplied '$with_nforenum', but it seems invalid" + exit 1 + fi + + nforenum="" + return 0 + fi + + log 1 "checking nforenum... found" +} + +detect_cputype() { + if [ -n "$cpu_type" ] && [ "$cpu_type" != "DETECT" ]; then + log 1 "forcing cpu-type... $cpu_type bits" + return; + fi + echo "#define _SQ64 1" > tmp.64bit.cpp + echo "#include \"src/stdafx.h\"" >> tmp.64bit.cpp + echo "assert_compile(sizeof(size_t) == 8);" >> tmp.64bit.cpp + echo "int main() { return 0; }" >> tmp.64bit.cpp + execute="$cxx_host $CFLAGS tmp.64bit.cpp -o tmp.64bit -DTESTING 2>&1" + cpu_type="`eval $execute 2>/dev/null`" + ret=$? + log 2 "executing $execute" + log 2 " returned $cpu_type" + log 2 " exit code $ret" + if [ "$ret" = "0" ]; then cpu_type="64"; else cpu_type="32"; fi + log 1 "detecting cpu-type... $cpu_type bits" + rm -f tmp.64bit tmp.64bit.cpp +} + +detect_sse_capable_architecture() { + # 0 means no, 1 is auto-detect, 2 is force + if [ "$with_sse" = "0" ]; then + log 1 "checking SSE... disabled" + return + fi + + echo "#define _SQ64 1" > tmp.sse.cpp + echo "#include " >> tmp.sse.cpp + echo "#include " >> tmp.sse.cpp + echo "#include " >> tmp.sse.cpp + echo "int main() { return 0; }" >> tmp.sse.cpp + execute="$cxx_host -msse4.1 $CFLAGS tmp.sse.cpp -o tmp.sse 2>&1" + sse="`eval $execute 2>/dev/null`" + ret=$? + log 2 "executing $execute" + log 2 " returned $sse" + log 2 " exit code $ret" + if [ "$ret" = "0" ]; then + log 1 "detecting SSE... found" + else + # It was forced, so it should be found. + if [ "$with_sse" != "1" ]; then + log 1 "configure: error: SSE couldn't be found" + log 1 "configure: error: you force enabled SSE, but it seems unavailable" + exit 1 + fi + + log 1 "detecting SSE... not found" + with_sse="0" + fi + rm -f tmp.sse tmp.exe tmp.sse.cpp +} + +make_sed() { + T_CFLAGS="$CFLAGS" + T_CXXFLAGS="$CXXFLAGS" + T_LDFLAGS="$LDFLAGS" + + SRC_OBJS_DIR="$BASE_SRC_OBJS_DIR/$OBJS_SUBDIR" + + # All the data needed to compile a single target + # Make sure if you compile multiple targets to + # use multiple OBJS_DIR, because all in-between + # binaries are stored in there, and nowhere else. + SRC_REPLACE=" + s@!!CC_HOST!!@$cc_host@g; + s@!!CXX_HOST!!@$cxx_host@g; + s@!!CC_BUILD!!@$cc_build@g; + s@!!CXX_BUILD!!@$cxx_build@g; + s@!!WINDRES!!@$windres@g; + s@!!STRIP!!@$strip $strip_arg@g; + s@!!LIPO!!@$lipo@g; + s@!!CFLAGS!!@$T_CFLAGS@g; + s@!!CFLAGS_BUILD!!@$CFLAGS_BUILD@g; + s@!!CXXFLAGS!!@$T_CXXFLAGS@g; + s@!!CXXFLAGS_BUILD!!@$CXXFLAGS_BUILD@g; + s@!!STRGEN_FLAGS!!@$strgen_flags@g; + s@!!LIBS!!@$LIBS@g; + s@!!LDFLAGS!!@$T_LDFLAGS@g; + s@!!LDFLAGS_BUILD!!@$LDFLAGS_BUILD@g; + s@!!BIN_DIR!!@$BIN_DIR@g; + s@!!ROOT_DIR!!@$ROOT_DIR@g; + s@!!MEDIA_DIR!!@$MEDIA_DIR@g; + s@!!SOURCE_LIST!!@$SOURCE_LIST@g; + s@!!SRC_OBJS_DIR!!@$SRC_OBJS_DIR@g; + s@!!LANG_OBJS_DIR!!@$LANG_OBJS_DIR@g; + s@!!GRF_OBJS_DIR!!@$GRF_OBJS_DIR@g; + s@!!SETTING_OBJS_DIR!!@$SETTING_OBJS_DIR@g; + s@!!SRC_DIR!!@$SRC_DIR@g; + s@!!SCRIPT_SRC_DIR!!@$SCRIPT_SRC_DIR@g; + s@!!OSXAPP!!@$OSXAPP@g; + s@!!LANG_DIR!!@$LANG_DIR@g; + s@!!TTD!!@$TTD@g; + s@!!BINARY_DIR!!@$prefix_dir/$binary_dir@g; + s@!!DATA_DIR!!@$prefix_dir/$data_dir@g; + s@!!DOC_DIR!!@$prefix_dir/$doc_dir@g; + s@!!MAN_DIR!!@$prefix_dir/$man_dir@g; + s@!!ICON_DIR!!@$prefix_dir/$icon_dir@g; + s@!!ICON_THEME_DIR!!@$prefix_dir/$icon_theme_dir@g; + s@!!PERSONAL_DIR!!@$personal_dir@g; + s@!!SHARED_DIR!!@$shared_dir@g; + s@!!INSTALL_DIR!!@$install_dir@g; + s@!!BINARY_NAME!!@$binary_name@g; + s@!!STRGEN!!@$STRGEN@g; + s@!!DEPEND!!@$DEPEND@g; + s@!!SETTINGSGEN!!@$SETTINGSGEN@g; + s@!!STAGE!!@$STAGE@g; + s@!!MAKEDEPEND!!@$makedepend@g; + s@!!CFLAGS_MAKEDEP!!@$cflags_makedep@g; + s@!!SORT!!@$sort@g; + s@!!CONFIG_CACHE_COMPILER!!@config.cache.compiler@g; + s@!!CONFIG_CACHE_LINKER!!@config.cache.linker@g; + s@!!CONFIG_CACHE_SOURCE!!@config.cache.source@g; + s@!!CONFIG_CACHE_VERSION!!@config.cache.version@g; + s@!!CONFIG_CACHE_SOURCE_LIST!!@config.cache.source.list@g; + s@!!CONFIG_CACHE_PWD!!@config.cache.pwd@g; + s@!!LANG_SUPPRESS!!@$lang_suppress@g; + s@!!OBJS_C!!@$OBJS_C@g; + s@!!OBJS_CPP!!@$OBJS_CPP@g; + s@!!OBJS_MM!!@$OBJS_MM@g; + s@!!OBJS_RC!!@$OBJS_RC@g; + s@!!SRCS!!@$SRCS@g; + s@!!OS!!@$os@g; + s@!!CONFIGURE_FILES!!@$CONFIGURE_FILES@g; + s@!!AWK!!@$awk@g; + s@!!DISTCC!!@$distcc@g; + s@!!NFORENUM!!@$nforenum@g; + s@!!GRFCODEC!!@$grfcodec@g; + " + + if [ "$icon_theme_dir" != "" ]; then + SRC_REPLACE="$SRC_REPLACE + s@!!ICON_THEME_DIR!!@$prefix_dir/$icon_theme_dir@g; + " + else + SRC_REPLACE="$SRC_REPLACE + s@!!ICON_THEME_DIR!!@@g; + " + fi + + if [ "$man_dir" != "" ]; then + SRC_REPLACE="$SRC_REPLACE + s@!!MAN_DIR!!@$prefix_dir/$man_dir@g; + " + else + SRC_REPLACE="$SRC_REPLACE + s@!!MAN_DIR!!@@g; + " + fi + + if [ "$menu_dir" != "" ]; then + SRC_REPLACE="$SRC_REPLACE + s@!!MENU_DIR!!@$prefix_dir/$menu_dir@g; + " + else + SRC_REPLACE="$SRC_REPLACE + s@!!MENU_DIR!!@@g; + " + fi +} + +generate_menu_item() { + MENU_REPLACE=" + s@!!TTD!!@$TTD@g; + s@!!MENU_GROUP!!@$menu_group@g; + s@!!MENU_NAME!!@$menu_name@g + " + log 1 "Generating menu item..." + mkdir -p media + < $ROOT_DIR/media/openttd.desktop.in sed "$MENU_REPLACE" > media/openttd.desktop +} + +generate_main() { + STAGE="[MAIN]" + + make_sed + + # Create the main Makefile + log 1 "Generating Makefile..." + echo "# Auto-generated file from 'Makefile.in' -- DO NOT EDIT" > Makefile + < $ROOT_DIR/Makefile.in sed "$SRC_REPLACE" >> Makefile + cp $ROOT_DIR/Makefile.bundle.in Makefile.bundle + echo "# Auto-generated file -- DO NOT EDIT" > Makefile.am + echo >> Makefile.am + # Make the copy of the source-list, so we don't trigger an unwanted recompile + cp $SOURCE_LIST config.cache.source.list + # Add the current directory, so we don't trigger an unwanted recompile + echo "`pwd`" > config.cache.pwd + # Make sure config.cache is OLDER then config.cache.source.list + touch config.cache + touch config.pwd + + if [ "$menu_dir" != "" ]; then + generate_menu_item + fi +} + +generate_lang() { + STAGE="[LANG]" + + make_sed + + # Create the language file + mkdir -p $LANG_OBJS_DIR + + log 1 "Generating lang/Makefile..." + echo "# Auto-generated file from 'Makefile.lang.in' -- DO NOT EDIT" > $LANG_OBJS_DIR/Makefile + < $ROOT_DIR/Makefile.lang.in sed "$SRC_REPLACE" >> $LANG_OBJS_DIR/Makefile + echo "DIRS += $LANG_OBJS_DIR" >> Makefile.am + echo "LANG_DIRS += $LANG_OBJS_DIR" >> Makefile.am +} + +generate_settings() { + STAGE="[SETTING]" + + make_sed + + # Create the language file + mkdir -p $SETTING_OBJS_DIR + + log 1 "Generating setting/Makefile..." + echo "# Auto-generated file from 'Makefile.settings.in' -- DO NOT EDIT" > $SETTING_OBJS_DIR/Makefile + < $ROOT_DIR/Makefile.setting.in sed "$SRC_REPLACE" >> $SETTING_OBJS_DIR/Makefile + echo "DIRS += $SETTING_OBJS_DIR" >> Makefile.am +} + +generate_grf() { + STAGE="[BASESET]" + + make_sed + + # Create the language file + mkdir -p $GRF_OBJS_DIR + + log 1 "Generating grf/Makefile..." + echo "# Auto-generated file from 'Makefile.grf.in' -- DO NOT EDIT" > $GRF_OBJS_DIR/Makefile + < $ROOT_DIR/Makefile.grf.in sed "$SRC_REPLACE" >> $GRF_OBJS_DIR/Makefile + echo "DIRS += $GRF_OBJS_DIR" >> Makefile.am +} + +generate_src_normal() { + STAGE=$1 + + make_sed + + # Create the source file + mkdir -p $SRC_OBJS_DIR + + log 1 "Generating $2/Makefile..." + echo "# Auto-generated file from 'Makefile.src.in' -- DO NOT EDIT" > $SRC_OBJS_DIR/Makefile + < $ROOT_DIR/Makefile.src.in sed "$SRC_REPLACE" >> $SRC_OBJS_DIR/Makefile + echo "DIRS += $SRC_OBJS_DIR" >> Makefile.am + echo "SRC_DIRS += $SRC_OBJS_DIR" >> Makefile.am +} + +generate_src_osx() { + cc_host_orig="$cc_host" + cxx_host_orig="$cxx_host" + CFLAGS_orig="$CFLAGS" + LDFLAGS_orig="$LDFLAGS" + + for type in $enable_universal; do + + if [ -n "$osx_sdk_104_path" ]; then + # Use 10.4 SDK for 32-bit targets + CFLAGS="-isysroot $osx_sdk_104_path $CFLAGS_orig" + LDFLAGS="-Wl,-syslibroot,$osx_sdk_104_path $LDFLAGS_orig" + fi + + # We don't want to duplicate the x86_64 stuff for each target, so do it once here + if [ "$type" = "ppc64" ] || [ "$type" = "x86_64" ]; then + # 64 bits is always 10.5 or higher. Furthermore it has a non const ICONV + # and they also removed support for QuickTime/QuickDraw + if [ -n "$osx_sdk_path" ]; then + CFLAGS="-isysroot $osx_sdk_path $CFLAGS_orig" + LDFLAGS="-Wl,-syslibroot,$osx_sdk_path $LDFLAGS_orig" + fi + CFLAGS="$CFLAGS -D_SQ64 -DNO_QUICKTIME -UENABLE_COCOA_QUICKDRAW" + LIBS="`echo $LIBS | sed 's/-framework QuickTime//'`" + fi + + case $type in + ppc) + BASE_SRC_OBJS_DIR="$OBJS_DIR/ppc" + cc_host="$cc_host_orig -arch ppc -mmacosx-version-min=10.3" + cxx_host="$cxx_host_orig -arch ppc -mmacosx-version-min=10.3" + generate_src_normal "[ppc]" "objs/ppc";; + ppc970) + BASE_SRC_OBJS_DIR="$OBJS_DIR/ppc970" + cc_host="$cc_host_orig -arch ppc970 -mmacosx-version-min=10.3 -mcpu=G5 -mpowerpc64 -mtune=970 -mcpu=970 -mpowerpc-gpopt" + cxx_host="$cxx_host_orig -arch ppc970 -mmacosx-version-min=10.3 -mcpu=G5 -mpowerpc64 -mtune=970 -mcpu=970 -mpowerpc-gpopt" + generate_src_normal "[ppc970]" "objs/ppc970";; + i386) + BASE_SRC_OBJS_DIR="$OBJS_DIR/i386" + cc_host="$cc_host_orig -arch i386 -mmacosx-version-min=10.4" + cxx_host="$cxx_host_orig -arch i386 -mmacosx-version-min=10.4" + generate_src_normal "[i386]" "objs/i386";; + ppc64) + BASE_SRC_OBJS_DIR="$OBJS_DIR/ppc64" + cc_host="$cc_host_orig -arch ppc64 -mmacosx-version-min=10.5" + cxx_host="$cxx_host_orig -arch ppc64 -mmacosx-version-min=10.5" + generate_src_normal "[ppc64]" "objs/ppc64";; + x86_64) + BASE_SRC_OBJS_DIR="$OBJS_DIR/x86_64" + cc_host="$cc_host_orig -arch x86_64 -mmacosx-version-min=10.5" + cxx_host="$cxx_host_orig -arch x86_64 -mmacosx-version-min=10.5" + generate_src_normal "[x86_64]" "objs/x86_64";; + *) log 1 "Unknown architecture requested for universal build: $type";; + esac + done +} + +generate_src() { + if [ "$os" = "OSX" ] && [ "$enable_universal" != "0" ]; then + generate_src_osx + else + generate_src_normal "[SRC]" "objs" + fi +} + +showhelp() { + echo "'configure' configures OpenTTD." + echo "" + echo "Usage: $0 [OPTION]... [VAR=VALUE]..." + echo "" + echo "To assign environment variables (e.g., CC, CFLAGS...), specify them as" + echo "VAR=VALUE. See below for descriptions of some of the useful variables." + echo "" + echo "Defaults for the options are specified in brackets." + echo "" + echo "Configuration:" + echo " -h, --help display this help and exit" + echo "" + echo "System types:" + echo " --build=BUILD configure for building on BUILD [guessed]" + echo " --host=HOST cross-compile to build programs to run" + echo " on HOST [BUILD]" + echo " --windres=WINDRES the windres to use [HOST-windres]" + echo " --strip=STRIP the strip to use [HOST-strip]" + echo " --awk=AWK the awk to use in configure [awk]" + echo " --pkg-config=PKG-CONFIG the pkg-config to use in configure [pkg-config]" + echo " --lipo=LIPO the lipo to use (OSX ONLY) [HOST-lipo]" + echo " --os=OS the OS we are compiling for [DETECT]" + echo " DETECT/UNIX/OSX/FREEBSD/DRAGONFLY/OPENBSD/" + echo " NETBSD/HPUX/SUNOS/CYGWIN/" + echo " MINGW/OS2/HAIKU" + echo "" + echo "Paths:" + echo " --prefix-dir=dir specifies the prefix for all installed" + echo " files [/usr/local]" + echo " --binary-dir=dir location of the binary. Will be prefixed" + echo " with the prefix-dir [games]" + echo " --data-dir=dir location of data files (lang, data, gm)." + echo " Will be prefixed with the prefix-dir" + echo " [share/games/openttd]" + echo " --doc-dir=dir location of the doc files" + echo " Will be prefixed with the prefix-dir" + echo " [$doc_dir]" + echo " --icon-dir=dir location of icons. Will be prefixed" + echo " with the prefix-dir [share/pixmaps]" + echo " --icon-theme-dir=dir location of icon theme." + echo " Will be prefixed with the prefix-dir" + echo " and postfixed with size-dirs [$icon_theme_dir]" + echo " --man-dir=dir location of the manual page (UNIX only)" + echo " Will be prefixed with the prefix-dir" + echo " [$man_dir]" + echo " --menu-dir=dir location of the menu item. (UNIX only, except OSX)" + echo " Will be prefixed with the prefix-dir" + echo " [share/applications]" + echo " --personal-dir=dir location of the personal directory" + echo " [os-dependent default]" + echo " --shared-dir=dir location of shared data files" + echo " [os-dependent default]" + echo " --install-dir=dir specifies the root to install to." + echo " Useful to install into jails [/]" + echo " --binary-name the name used for the binary, icons," + echo " desktop file, etc. when installing [openttd]" + echo "" + echo "Features and packages:" + echo " --enable-debug[=LVL] enable debug-mode (LVL=[0123], 0 is release)" + echo " --enable-desync-debug=[LVL] enable desync debug options (LVL=[012], 0 is none" + echo " --enable-profiling enables profiling" + echo " --enable-lto enables GCC's Link Time Optimization (LTO)/ICC's" + echo " Interprocedural Optimization if available" + echo " --enable-dedicated compile a dedicated server (without video)" + echo " --enable-static enable static compile (doesn't work for" + echo " all HOSTs)" + echo " --enable-translator enable extra output for translators" + echo " --enable-universal[=ARCH] enable universal builds (OSX ONLY). Allowed is any combination" + echo " of architectures: i386 ppc ppc970 ppc64 x86_64" + echo " Default architectures are: i386 ppc" + echo " --enable-osx-g5 enables optimizations for ppc970 (G5) (OSX ONLY)" + echo " --disable-cocoa-quartz disable the quartz window mode driver for Cocoa (OSX ONLY)" + echo " --disable-cocoa-quickdraw disable the quickdraw window mode driver for Cocoa (OSX ONLY)" + echo " --disable-unicode disable unicode support to build win9x" + echo " version (Win32 ONLY)" + echo " --enable-console compile as a console application instead of as a GUI application." + echo " If this setting is active, debug output will appear in the same" + echo " console instead of opening a new window. (Win32 ONLY)" + echo " --disable-assert disable asserts (continue on errors)" + echo " --enable-strip enable any possible stripping" + echo " --without-osx-sysroot disable the automatic adding of sysroot " + echo " (OSX ONLY)" + echo " --without-application-bundle disable generation of application bundle" + echo " (OSX ONLY)" + echo " --without-menu-entry Don't generate a menu item (Freedesktop based only)" + echo " --menu-group=group Category in which the menu item will be placed (Freedesktop based only)" + echo " --menu-name=name Name of the menu item when placed [OpenTTD]" + echo " --with-direct-music enable direct music support (Win32 ONLY)" + echo " --with-sort=sort define a non-default location for sort" + echo " --with-midi=midi define which midi-player to use" + echo " --with-midi-arg=arg define which args to use for the" + echo " midi-player" + echo " --with-fluidsynth enables fluidsynth support" + echo " --with-allegro[=\"pkg-config allegro\"]" + echo " enables Allegro video driver support" + echo " --with-cocoa enables COCOA video driver (OSX ONLY)" + echo " --with-sdl[=\"sdl1|sdl2\"] enables SDL video driver support" + echo " --with-zlib[=\"pkg-config zlib\"]" + echo " enables zlib support" + echo " --with-liblzma[=\"pkg-config liblzma\"]" + echo " enables liblzma support" + echo " --with-liblzo2[=liblzo2.a] enables liblzo2 support" + echo " --with-png[=\"pkg-config libpng\"]" + echo " enables libpng support" + echo " --with-freetype[=\"pkg-config freetype2\"]" + echo " enables libfreetype support" + echo " --with-fontconfig[=\"pkg-config fontconfig\"]" + echo " enables fontconfig support" + echo " --with-xdg-basedir[=\"pkg-config libxdg-basedir\"]" + echo " enables XDG base directory support" + echo " --with-icu enables icu components for layout and sorting" + echo " --with-icu-layout[=\"pkg-config icu-lx\"]" + echo " enables icu components for layouting (right-to-left support)" + echo " --with-icu-sort[=\"pkg-config icu-i18n\"]" + echo " enables icu components for locale specific string sorting" + echo " --static-icu try to link statically (libsicu instead of" + echo " libicu; can fail as the new name is guessed)" + echo " --with-iconv[=iconv-path] enables iconv support" + echo " --disable-builtin-depend disable use of builtin deps finder" + echo " --with-makedepend[=makedepend] enables makedepend support" + echo " --with-ccache enables ccache support" + echo " --with-distcc enables distcc support" + echo " --without-grfcodec disable usage of grfcodec and re-generation of base sets" + echo " --without-threads disable threading support" + echo " --without-sse disable SSE support (x86/x86_64 only)" + echo "" + echo "Some influential environment variables:" + echo " CC C compiler command" + echo " CXX C++ compiler command" + echo " CFLAGS C compiler flags" + echo " CXXFLAGS C++ compiler flags" + echo " WINDRES windres command" + echo " LDFLAGS linker flags, e.g. -L if you" + echo " have libraries in a nonstandard" + echo " directory " + echo " CFLAGS_BUILD C compiler flags for build time tool generation" + echo " CXXFLAGS_BUILD C++ compiler flags for build time tool generation" + echo " LDFLAGS_BUILD linker flags for build time tool generation" + echo " PKG_CONFIG_PATH additional library search paths (see \"man pkg-config\")" + echo " PKG_CONFIG_LIBDIR replace the default library search path (see \"man pkg-config\")" + echo "" + echo "Use these variables to override the choices made by 'configure' or to help" + echo "it to find libraries and programs with nonstandard names/locations." +} diff --git a/src/citymania/cm_highlight.cpp b/src/citymania/cm_highlight.cpp index d356dac757..5de8f1a395 100644 --- a/src/citymania/cm_highlight.cpp +++ b/src/citymania/cm_highlight.cpp @@ -48,6 +48,7 @@ extern int _selected_airport_index; extern byte _selected_airport_layout; extern DiagDirection _build_depot_direction; ///< Currently selected depot direction extern DiagDirection _road_station_picker_orientation; +extern DiagDirection _road_depot_orientation; extern uint32 _realtime_tick; extern void GetStationLayout(byte *layout, int numtracks, int plat_len, const StationSpec *statspec); @@ -142,6 +143,13 @@ ObjectTileHighlight ObjectTileHighlight::make_road_stop(SpriteID palette, RoadTy return oh; } +ObjectTileHighlight ObjectTileHighlight::make_road_depot(SpriteID palette, RoadType roadtype, DiagDirection ddir) { + auto oh = ObjectTileHighlight(Type::ROAD_DEPOT, palette); + oh.u.road.depot.roadtype = roadtype; + oh.u.road.depot.ddir = ddir; + return oh; +} + ObjectTileHighlight ObjectTileHighlight::make_airport_tile(SpriteID palette, StationGfx gfx) { auto oh = ObjectTileHighlight(Type::AIRPORT_TILE, palette); oh.u.airport_tile.gfx = gfx; @@ -197,6 +205,14 @@ ObjectHighlight ObjectHighlight::make_road_stop(TileIndex start_tile, TileIndex return oh; } +ObjectHighlight ObjectHighlight::make_road_depot(TileIndex tile, RoadType roadtype, DiagDirection orientation) { + auto oh = ObjectHighlight{ObjectHighlight::Type::ROAD_DEPOT}; + oh.tile = tile; + oh.ddir = orientation; + oh.roadtype = roadtype; + return oh; +} + ObjectHighlight ObjectHighlight::make_airport(TileIndex start_tile, int airport_type, byte airport_layout) { auto oh = ObjectHighlight{ObjectHighlight::Type::AIRPORT}; oh.tile = start_tile; @@ -330,6 +346,17 @@ void ObjectHighlight::UpdateTiles() { break; } + case Type::ROAD_DEPOT: { + auto palette = (CanBuild( + this->tile, + this->roadtype << 2 | this->ddir, + 0, + CMD_BUILD_ROAD_DEPOT + ) ? PALETTE_TINT_WHITE : PALETTE_TINT_RED_DEEP); + this->tiles.insert(std::make_pair(this->tile, ObjectTileHighlight::make_road_depot(palette, this->roadtype, this->ddir))); + break; + } + case Type::AIRPORT: { auto palette = (CanBuild( this->tile, @@ -515,6 +542,73 @@ void DrawRoadStop(SpriteID palette, const TileInfo *ti, RoadType roadtype, DiagD // DrawRoadCatenary(ti); } + +struct DrawRoadTileStruct { + uint16 image; + byte subcoord_x; + byte subcoord_y; +}; + +#include "../table/road_land.h" + +// copied from road_gui.cpp +static uint GetRoadSpriteOffset(Slope slope, RoadBits bits) +{ + if (slope != SLOPE_FLAT) { + switch (slope) { + case SLOPE_NE: return 11; + case SLOPE_SE: return 12; + case SLOPE_SW: return 13; + case SLOPE_NW: return 14; + default: NOT_REACHED(); + } + } else { + static const uint offsets[] = { + 0, 18, 17, 7, + 16, 0, 10, 5, + 15, 8, 1, 4, + 9, 3, 6, 2 + }; + return offsets[bits]; + } +} + + +void DrawRoadDepot(SpriteID palette, const TileInfo *ti, RoadType roadtype, DiagDirection orientation) { + const RoadTypeInfo* rti = GetRoadTypeInfo(roadtype); + int relocation = GetCustomRoadSprite(rti, INVALID_TILE, ROTSG_DEPOT); + bool default_gfx = relocation == 0; + if (default_gfx) { + if (HasBit(rti->flags, ROTF_CATENARY)) { + if (_loaded_newgrf_features.tram == TRAMWAY_REPLACE_DEPOT_WITH_TRACK && RoadTypeIsTram(roadtype) && !rti->UsesOverlay()) { + /* Sprites with track only work for default tram */ + relocation = SPR_TRAMWAY_DEPOT_WITH_TRACK - SPR_ROAD_DEPOT; + default_gfx = false; + } else { + /* Sprites without track are always better, if provided */ + relocation = SPR_TRAMWAY_DEPOT_NO_TRACK - SPR_ROAD_DEPOT; + } + } + } else { + relocation -= SPR_ROAD_DEPOT; + } + + const DrawTileSprites *dts = &_road_depot[orientation]; + AddSortableSpriteToDraw(dts->ground.sprite, palette, ti->x, ti->y, 1, 1, BB_HEIGHT_UNDER_BRIDGE, ti->z); + + if (default_gfx) { + uint offset = GetRoadSpriteOffset(SLOPE_FLAT, DiagDirToRoadBits(orientation)); + if (rti->UsesOverlay()) { + SpriteID ground = GetCustomRoadSprite(rti, INVALID_TILE, ROTSG_OVERLAY); + if (ground != 0) AddSortableSpriteToDraw(ground + offset, palette, ti->x, ti->y, 1, 1, BB_HEIGHT_UNDER_BRIDGE, ti->z); + } else if (RoadTypeIsTram(roadtype)) { + AddSortableSpriteToDraw(SPR_TRAMWAY_OVERLAY + offset, palette, ti->x, ti->y, 1, 1, BB_HEIGHT_UNDER_BRIDGE, ti->z); + } + } + + DrawRailTileSeq(ti, dts, TO_INVALID, relocation, 0, palette); +} + #include "../table/station_land.h" void DrawAirportTile(SpriteID palette, const TileInfo *ti, StationGfx gfx) { @@ -709,6 +803,9 @@ void ObjectHighlight::Draw(const TileInfo *ti) { case ObjectTileHighlight::Type::ROAD_STOP: DrawRoadStop(oth.palette, ti, oth.u.road.stop.roadtype, oth.u.road.stop.ddir, oth.u.road.stop.is_truck); break; + case ObjectTileHighlight::Type::ROAD_DEPOT: + DrawRoadDepot(oth.palette, ti, oth.u.road.depot.roadtype, oth.u.road.depot.ddir); + break; case ObjectTileHighlight::Type::AIRPORT_TILE: DrawAirportTile(oth.palette, ti, oth.u.airport_tile.gfx); break; @@ -1047,25 +1144,10 @@ bool DrawTileSelection(const TileInfo *ti, const TileHighlightType &tht) { // if (_thd.drawstyle == CM_HT_BLUEPRINT_PLACE) return true; - // if ((_thd.drawstyle & HT_DRAG_MASK) == HT_RECT && _thd.outersize.x > 0) { if (_thd.select_proc == DDSP_BUILD_STATION || _thd.select_proc == DDSP_BUILD_BUSSTOP - || _thd.select_proc == DDSP_BUILD_TRUCKSTOP || _thd.select_proc == CM_DDSP_BUILD_AIRPORT) { - // station selector, handled by DrawTileZoning - return true; - } - - if (_thd.select_proc == CM_DDSP_BUILD_RAIL_DEPOT) { - // if ((_thd.drawstyle & HT_DRAG_MASK) == HT_RECT && IsInsideSelectedRectangle(ti->x, ti->y) - // && _cursor.sprite_seq[0].sprite == GetRailTypeInfo(_cur_railtype)->cursor.depot) { - // DrawTileSelectionRect(ti, _thd.make_square_red ? PALETTE_SEL_TILE_RED : PAL_NONE); - - // auto rti = GetRailTypeInfo(_cur_railtype); - // int depot_sprite = GetCustomRailSprite(rti, ti->tile, RTSG_DEPOT); - // auto relocation = depot_sprite != 0 ? depot_sprite - SPR_RAIL_DEPOT_SE_1 : rti->GetRailtypeSpriteOffset(); - // AddSortableSpriteToDraw(relocation, PALETTE_TINT_WHITE, ti->x, ti->y, 0x10, 0x10, 1, ti->z); - // AddSortableSpriteToDraw(SPR_RAIL_DEPOT_SE_1, PALETTE_TINT_WHITE, ti->x, ti->y, 0x10, 0x10, 1, ti->z); - // DrawTrainDepotSprite(r.left + 1 + ScaleGUITrad(31), r.bottom - ScaleGUITrad(31), widget - WID_BRAD_DEPOT_NE + DIAGDIR_NE, _cur_railtype); - // DrawTrainDepotSprite(ti, _cur_railtype, (DiagDirection)(_thd.drawstyle & HT_DIR_MASK)); + || _thd.select_proc == DDSP_BUILD_TRUCKSTOP || _thd.select_proc == CM_DDSP_BUILD_AIRPORT + || _thd.select_proc == CM_DDSP_BUILD_ROAD_DEPOT || _thd.select_proc == CM_DDSP_BUILD_RAIL_DEPOT) { + // handled by DrawTileZoning return true; } @@ -1115,6 +1197,15 @@ HighLightStyle UpdateTileSelection(HighLightStyle new_drawstyle) { // new_drawstyle = CM_HT_BLUEPRINT_PLACE; // } else if (_thd.make_square_red) { + } else if (_thd.select_proc == CM_DDSP_BUILD_ROAD_DEPOT) { + auto dir = _road_depot_orientation; + if (pt.x != -1) { + if (dir == DEPOTDIR_AUTO) { + dir = AddAutodetectionRotation(AutodetectRoadObjectDirection(tile, pt, _cur_roadtype)); + } + _thd.cm_new = ObjectHighlight::make_road_depot(tile, _cur_roadtype, dir); + } + new_drawstyle = HT_RECT; } else if (_thd.select_proc == CM_DDSP_BUILD_RAIL_DEPOT) { auto dir = _build_depot_direction; if (pt.x != -1) { diff --git a/src/citymania/cm_highlight_type.hpp b/src/citymania/cm_highlight_type.hpp index 9b8a9cebfc..3a9a74c244 100644 --- a/src/citymania/cm_highlight_type.hpp +++ b/src/citymania/cm_highlight_type.hpp @@ -30,6 +30,7 @@ public: RAIL_BRIDGE_HEAD, RAIL_TUNNEL_HEAD, ROAD_STOP, + ROAD_DEPOT, AIRPORT_TILE, END, }; @@ -67,6 +68,10 @@ public: DiagDirection ddir; bool is_truck; } stop; + struct { + RoadType roadtype; + DiagDirection ddir; + } depot; } road; struct { StationGfx gfx; @@ -83,6 +88,7 @@ public: static ObjectTileHighlight make_rail_tunnel_head(SpriteID palette, DiagDirection ddir); static ObjectTileHighlight make_road_stop(SpriteID palette, RoadType roadtype, DiagDirection ddir, bool is_truck); + static ObjectTileHighlight make_road_depot(SpriteID palette, RoadType roadtype, DiagDirection ddir); static ObjectTileHighlight make_airport_tile(SpriteID palette, StationGfx gfx); }; @@ -109,6 +115,7 @@ public: RAIL_BRIDGE, RAIL_TUNNEL, ROAD_STOP, + ROAD_DEPOT, END, }; Type type; @@ -150,6 +157,9 @@ public: DiagDirection ddir; TileIndexDiffC other_end; } stop; + struct { + DiagDirection ddir; + } depot; } road; } u; Item(Type type, TileIndexDiffC tdiff) @@ -184,7 +194,8 @@ public: RAIL_DEPOT = 1, RAIL_STATION = 2, ROAD_STOP = 3, - AIRPORT = 4, + ROAD_DEPOT = 4, + AIRPORT = 5, // BLUEPRINT = 2, }; @@ -214,6 +225,7 @@ public: static ObjectHighlight make_rail_station(TileIndex start_tile, TileIndex end_tile, Axis axis); // static ObjectHighlight make_blueprint(TileIndex tile, sp blueprint); static ObjectHighlight make_road_stop(TileIndex start_tile, TileIndex end_tile, RoadType roadtype, DiagDirection orientation, bool is_truck); + static ObjectHighlight make_road_depot(TileIndex tile, RoadType roadtype, DiagDirection orientation); static ObjectHighlight make_airport(TileIndex start_tile, int airport_type, byte airport_layout); void Draw(const TileInfo *ti); diff --git a/src/citymania/cm_station_gui.hpp b/src/citymania/cm_station_gui.hpp index b199a42085..2befe59735 100644 --- a/src/citymania/cm_station_gui.hpp +++ b/src/citymania/cm_station_gui.hpp @@ -9,6 +9,7 @@ namespace citymania { +const DiagDirection DEPOTDIR_AUTO = DIAGDIR_END; const DiagDirection STATIONDIR_X = DIAGDIR_END; const DiagDirection STATIONDIR_Y = (DiagDirection)((uint)DIAGDIR_END + 1); const DiagDirection STATIONDIR_AUTO = (DiagDirection)((uint)DIAGDIR_END + 2); diff --git a/src/crashlog.cpp b/src/crashlog.cpp index b2be2f21f5..c394ea79b9 100644 --- a/src/crashlog.cpp +++ b/src/crashlog.cpp @@ -56,6 +56,9 @@ #ifdef WITH_LIBLZMA # include #endif +#ifdef WITH_ZSTD +#include +#endif #ifdef WITH_LZO #include #endif @@ -255,6 +258,10 @@ char *CrashLog::LogLibraries(char *buffer, const char *last) const buffer += seprintf(buffer, last, " LZMA: %s\n", lzma_version_string()); #endif +#ifdef WITH_ZSTD + buffer += seprintf(buffer, last, " ZSTD: %s\n", ZSTD_versionString()); +#endif + #ifdef WITH_LZO buffer += seprintf(buffer, last, " LZO: %s\n", lzo_version_string()); #endif diff --git a/src/network/network_client.cpp b/src/network/network_client.cpp index 0a90830303..78644271df 100644 --- a/src/network/network_client.cpp +++ b/src/network/network_client.cpp @@ -395,6 +395,7 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::SendJoin() p->Send_string(_settings_client.network.client_name); // Client name p->Send_uint8 (_network_join_as); // PlayAs p->Send_uint8 (NETLANG_ANY); // Language + p->Send_uint8 (citymania::GetAvailableLoadFormats()); // Compressnion formats that we can decompress my_client->SendPacket(p); return NETWORK_RECV_STATUS_OKAY; } diff --git a/src/network/network_server.cpp b/src/network/network_server.cpp index 9e4d0d88f9..467366e21a 100644 --- a/src/network/network_server.cpp +++ b/src/network/network_server.cpp @@ -629,7 +629,7 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::SendMap() sent_packets = 4; // We start with trying 4 packets /* Make a dump of the current game */ - if (SaveWithFilter(this->savegame, true) != SL_OK) usererror("network savedump failed"); + if (SaveWithFilter(this->savegame, true, this->cm_preset) != SL_OK) usererror("network savedump failed"); } if (this->status == STATUS_MAP) { @@ -925,9 +925,15 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_JOIN(Packet *p) p->Recv_string(name, sizeof(name)); playas = (Owner)p->Recv_uint8(); client_lang = (NetworkLanguage)p->Recv_uint8(); + uint8 savegame_formats = p->CanReadFromPacket(1) ? p->Recv_uint8() : 23u /* assume non-modded has everything but zstd */; if (this->HasClientQuit()) return NETWORK_RECV_STATUS_CONN_LOST; + /* Find common savegame compression format to use */ + auto preset = citymania::FindCompatibleSavePreset("", savegame_formats); + if (!preset) return this->SendError(NETWORK_ERROR_NOT_EXPECTED); + this->cm_preset = *preset; + /* join another company does not affect these values */ switch (playas) { case COMPANY_NEW_COMPANY: // New company diff --git a/src/network/network_server.h b/src/network/network_server.h index 77612fdc8c..9f762fcf71 100644 --- a/src/network/network_server.h +++ b/src/network/network_server.h @@ -12,6 +12,7 @@ #include "network_internal.h" #include "core/tcp_listen.h" +#include "../saveload/saveload.h" class ServerNetworkGameSocketHandler; /** Make the code look slightly nicer/simpler. */ @@ -71,6 +72,7 @@ public: struct PacketWriter *savegame; ///< Writer used to write the savegame. NetworkAddress client_address; ///< IP-address of the client (so he can be banned) + citymania::SavePreset cm_preset; ///< Preset to use for the savegame ServerNetworkGameSocketHandler(SOCKET s); ~ServerNetworkGameSocketHandler(); diff --git a/src/rail_gui.cpp b/src/rail_gui.cpp index 85ea464289..9436426958 100644 --- a/src/rail_gui.cpp +++ b/src/rail_gui.cpp @@ -809,7 +809,7 @@ struct BuildRailToolbarWindow : Window { case WID_RAT_BUILD_DEPOT: ddir = _build_depot_direction; - if (ddir == DIAGDIR_NW + 1) { + if (ddir == citymania::DEPOTDIR_AUTO) { assert(_thd.cm.type == citymania::ObjectHighlight::Type::RAIL_DEPOT); ddir = _thd.cm.ddir; } @@ -2203,8 +2203,8 @@ static WindowDesc _build_depot_desc( WDP_AUTO, nullptr, 0, 0, WC_BUILD_DEPOT, WC_BUILD_TOOLBAR, WDF_CONSTRUCTION, - _nested_build_depot_widgets, lengthof(_nested_build_depot_widgets), - &BuildRailDepotWindow::hotkeys // CityMania addition + _nested_build_depot_widgets, lengthof(_nested_build_depot_widgets) + ,&BuildRailDepotWindow::hotkeys // CityMania addition ); static void ShowBuildTrainDepotPicker(Window *parent) diff --git a/src/road_gui.cpp b/src/road_gui.cpp index 4b43001a47..c0a914a1da 100644 --- a/src/road_gui.cpp +++ b/src/road_gui.cpp @@ -70,7 +70,7 @@ static RoadFlags _place_road_flag; /* CM static */ RoadType _cur_roadtype; -static DiagDirection _road_depot_orientation; +/* CM static */ DiagDirection _road_depot_orientation; DiagDirection _road_station_picker_orientation; void CcPlaySound_CONSTRUCTION_OTHER(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2, uint32 cmd) @@ -472,6 +472,7 @@ struct BuildRoadToolbarWindow : Window { case WID_ROT_DEPOT: if (HandlePlacePushButton(this, WID_ROT_DEPOT, this->rti->cursor.depot, HT_RECT, CM_DDSP_BUILD_ROAD_DEPOT)) { + citymania::ResetRotateAutodetection(); ShowRoadDepotPicker(this); this->last_started_action = widget; } @@ -566,8 +567,9 @@ struct BuildRoadToolbarWindow : Window { case WID_ROT_DEPOT: ddir = _road_depot_orientation; - if (ddir == DIAGDIR_NW + 1) { - ddir = citymania::AutodetectRoadObjectDirection(tile, GetTileBelowCursor(), _cur_roadtype); + if (ddir == citymania::DEPOTDIR_AUTO) { + assert(_thd.cm.type == citymania::ObjectHighlight::Type::ROAD_DEPOT); + ddir = _thd.cm.ddir; } DoCommandP(tile, _cur_roadtype << 2 | ddir, 0, CMD_BUILD_ROAD_DEPOT | CMD_MSG(this->rti->strings.err_depot), CcRoadDepot); @@ -1023,6 +1025,13 @@ Window *ShowBuildRoadScenToolbar(RoadType roadtype) } struct BuildRoadDepotWindow : public PickerWindowBase { +/* CityMania code start */ +public: + enum class Hotkey : int { + ROTATE, + }; +/* CityMania code end */ + BuildRoadDepotWindow(WindowDesc *desc, Window *parent) : PickerWindowBase(desc, parent) { this->CreateNestedTree(); @@ -1080,6 +1089,33 @@ struct BuildRoadDepotWindow : public PickerWindowBase { break; } } + + /* CityMania code start */ + EventState OnHotkey(int hotkey) override + { + switch ((BuildRoadDepotWindow::Hotkey)hotkey) { + /* Indicate to the OnClick that the action comes from a hotkey rather + * then from a click and that the CTRL state should be ignored. */ + case BuildRoadDepotWindow::Hotkey::ROTATE: + if (_road_depot_orientation < DIAGDIR_END) { + this->RaiseWidget(_road_depot_orientation + WID_BROD_DEPOT_NE); + _road_depot_orientation = ChangeDiagDir(_road_depot_orientation, DIAGDIRDIFF_90RIGHT); + this->LowerWidget(_road_depot_orientation + WID_BROD_DEPOT_NE); + } else { + citymania::RotateAutodetection(); + } + this->SetDirty(); + return ES_HANDLED; + + default: + NOT_REACHED(); + } + + return ES_NOT_HANDLED; + } + + static HotkeyList hotkeys; + /* CityMania code end */ }; static const NWidgetPart _nested_build_road_depot_widgets[] = { @@ -1118,11 +1154,20 @@ static const NWidgetPart _nested_build_road_depot_widgets[] = { EndContainer(), }; +/* CityMania code start */ +static Hotkey build_depot_hotkeys[] = { + Hotkey(CM_WKC_MOUSE_MIDDLE, "rotate", (int)BuildRoadDepotWindow::Hotkey::ROTATE), + HOTKEY_LIST_END +}; +HotkeyList BuildRoadDepotWindow::hotkeys("cm_build_road_depot", build_depot_hotkeys); +/* CityMania code end */ + static WindowDesc _build_road_depot_desc( WDP_AUTO, nullptr, 0, 0, WC_BUILD_DEPOT, WC_BUILD_TOOLBAR, WDF_CONSTRUCTION, _nested_build_road_depot_widgets, lengthof(_nested_build_road_depot_widgets) + ,&BuildRoadDepotWindow::hotkeys // CityMania addition ); static void ShowRoadDepotPicker(Window *parent) diff --git a/src/saveload/saveload.cpp b/src/saveload/saveload.cpp index dcfcc9f431..9d050679fd 100644 --- a/src/saveload/saveload.cpp +++ b/src/saveload/saveload.cpp @@ -44,6 +44,7 @@ #include "../fios.h" #include "../error.h" #include +#include #include #ifdef __EMSCRIPTEN__ # include @@ -2301,40 +2302,163 @@ struct LZMASaveFilter : SaveFilter { #endif /* WITH_LIBLZMA */ +/******************************************** + ********** START OF ZSTD CODE ************** + ********************************************/ + +#if defined(WITH_ZSTD) +#include + + +/** Filter using ZSTD compression. */ +struct ZSTDLoadFilter : LoadFilter { + ZSTD_DCtx *zstd; ///< ZSTD decompression context + byte fread_buf[MEMORY_CHUNK_SIZE]; ///< Buffer for reading from the file + ZSTD_inBuffer input; ///< ZSTD input buffer for fread_buf + + /** + * Initialise this filter. + * @param chain The next filter in this chain. + */ + ZSTDLoadFilter(LoadFilter *chain) : LoadFilter(chain) + { + this->zstd = ZSTD_createDCtx(); + if (!this->zstd) SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR, "cannot initialize compressor"); + this->input = {this->fread_buf, 0, 0}; + } + + /** Clean everything up. */ + ~ZSTDLoadFilter() + { + ZSTD_freeDCtx(this->zstd); + } + + size_t Read(byte *buf, size_t size) override + { + ZSTD_outBuffer output{buf, size, 0}; + + do { + /* read more bytes from the file? */ + if (this->input.pos == this->input.size) { + this->input.size = this->chain->Read(this->fread_buf, sizeof(this->fread_buf)); + this->input.pos = 0; + } + + size_t ret = ZSTD_decompressStream(this->zstd, &output, &this->input); + if (ZSTD_isError(ret)) SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR, "libzstd returned error code"); + if (ret == 0) break; + } while (output.pos < output.size); + + return output.pos; + } +}; + +/** Filter using ZSTD compression. */ +struct ZSTDSaveFilter : SaveFilter { + ZSTD_CCtx *zstd; ///< ZSTD compression context + + /** + * Initialise this filter. + * @param chain The next filter in this chain. + * @param compression_level The requested level of compression. + */ + ZSTDSaveFilter(SaveFilter *chain, byte compression_level) : SaveFilter(chain) + { + this->zstd = ZSTD_createCCtx(); + if (!this->zstd) SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR, "cannot initialize compressor"); + if (ZSTD_isError(ZSTD_CCtx_setParameter(this->zstd, ZSTD_c_compressionLevel, (int)compression_level - 100))) { + ZSTD_freeCCtx(this->zstd); + SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR, "invalid compresison level"); + } + } + + /** Clean up what we allocated. */ + ~ZSTDSaveFilter() + { + ZSTD_freeCCtx(this->zstd); + } + + /** + * Helper loop for writing the data. + * @param p The bytes to write. + * @param len Amount of bytes to write. + * @param mode Mode for ZSTD_compressStream2. + */ + void WriteLoop(byte *p, size_t len, ZSTD_EndDirective mode) + { + byte buf[MEMORY_CHUNK_SIZE]; // output buffer + ZSTD_inBuffer input{p, len, 0}; + + bool finished; + do { + ZSTD_outBuffer output{buf, sizeof(buf), 0}; + size_t remaining = ZSTD_compressStream2(this->zstd, &output, &input, mode); + if (ZSTD_isError(remaining)) SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR, "libzstd returned error code"); + + if (output.pos != 0) this->chain->Write(buf, output.pos); + + finished = (mode == ZSTD_e_end ? (remaining == 0) : (input.pos == input.size)); + } while (!finished); + } + + void Write(byte *buf, size_t size) override + { + this->WriteLoop(buf, size, ZSTD_e_continue); + } + + void Finish() override + { + this->WriteLoop(nullptr, 0, ZSTD_e_end); + this->chain->Finish(); + } +}; +#endif /* WITH_LIBZSTD */ + /******************************************* ************* END OF CODE ***************** *******************************************/ /** The format for a reader/writer type of a savegame */ -struct SaveLoadFormat { - const char *name; ///< name of the compressor/decompressor (debug-only) - uint32 tag; ///< the 4-letter tag by which it is identified in the savegame +// struct SaveLoadFormat { +// const char *name; ///< name of the compressor/decompressor (debug-only) +// uint32 tag; ///< the 4-letter tag by which it is identified in the savegame - LoadFilter *(*init_load)(LoadFilter *chain); ///< Constructor for the load filter. - SaveFilter *(*init_write)(SaveFilter *chain, byte compression); ///< Constructor for the save filter. +// LoadFilter *(*init_load)(LoadFilter *chain); ///< Constructor for the load filter. +// SaveFilter *(*init_write)(SaveFilter *chain, byte compression); ///< Constructor for the save filter. - byte min_compression; ///< the minimum compression level of this format - byte default_compression; ///< the default compression level of this format - byte max_compression; ///< the maximum compression level of this format -}; +// byte min_compression; ///< the minimum compression level of this format +// byte default_compression; ///< the default compression level of this format +// byte max_compression; ///< the maximum compression level of this format +// }; /** The different saveload formats known/understood by OpenTTD. */ -static const SaveLoadFormat _saveload_formats[] = { +static const citymania::SaveLoadFormat _saveload_formats[] = { + /* Roughly 5 times larger at only 1% of the CPU usage over zlib level 6. */ + {0, "none", TO_BE32X('OTTN'), CreateLoadFilter, CreateSaveFilter, citymania::CompressionMethod::None, 0, 0, 0}, #if defined(WITH_LZO) /* Roughly 75% larger than zlib level 6 at only ~7% of the CPU usage. */ - {"lzo", TO_BE32X('OTTD'), CreateLoadFilter, CreateSaveFilter, 0, 0, 0}, + {1, "lzo", TO_BE32X('OTTD'), CreateLoadFilter, CreateSaveFilter, citymania::CompressionMethod::LZO, 0, 0, 0}, #else - {"lzo", TO_BE32X('OTTD'), nullptr, nullptr, 0, 0, 0}, + {1, "lzo", TO_BE32X('OTTD'), nullptr, nullptr, citymania::CompressionMethod::LZO, 0, 0, 0}, #endif - /* Roughly 5 times larger at only 1% of the CPU usage over zlib level 6. */ - {"none", TO_BE32X('OTTN'), CreateLoadFilter, CreateSaveFilter, 0, 0, 0}, #if defined(WITH_ZLIB) /* After level 6 the speed reduction is significant (1.5x to 2.5x slower per level), but the reduction in filesize is * fairly insignificant (~1% for each step). Lower levels become ~5-10% bigger by each level than level 6 while level * 1 is "only" 3 times as fast. Level 0 results in uncompressed savegames at about 8 times the cost of "none". */ - {"zlib", TO_BE32X('OTTZ'), CreateLoadFilter, CreateSaveFilter, 0, 6, 9}, + {2, "zlib", TO_BE32X('OTTZ'), CreateLoadFilter, CreateSaveFilter, citymania::CompressionMethod::Zlib, 0, 6, 9}, #else - {"zlib", TO_BE32X('OTTZ'), nullptr, nullptr, 0, 0, 0}, + {2, "zlib", TO_BE32X('OTTZ'), nullptr, nullptr, citymania::CompressionMethod::Zlib, 0, 0, 0}, +#endif +#if defined(WITH_ZSTD) + /* Zstd provides a decent compression rate at a very high compression/decompression speed. Compared to lzma level 2 + * zstd saves are about 40% larger (on level 1) but it has about 30x faster compression and 5x decompression making it + * a good choice for multiplayer servers. And zstd level 1 seems to be the optimal one for client connection speed + * (compress + 10 MB/s download + decompress time), about 3x faster than lzma:2 and 1.5x than zlib:2 and lzo. + * As zstd has negative compression levels the values were increased by 100 moving zstd level range -100..22 into + * openttd 0..122. Also note that value 100 mathes zstd level 0 which is a special value for default level 3 (openttd 103) */ + {3, "zstd", TO_BE32X('OTTS'), CreateLoadFilter, CreateSaveFilter, citymania::CompressionMethod::ZSTD, 0, 101, 122}, +#else + {3, "zstd", TO_BE32X('OTTS'), nullptr, nullptr, citymania::CompressionMethod::ZSTD, 0, 0, 0}, #endif #if defined(WITH_LIBLZMA) /* Level 2 compression is speed wise as fast as zlib level 6 compression (old default), but results in ~10% smaller saves. @@ -2342,12 +2466,111 @@ static const SaveLoadFormat _saveload_formats[] = { * The next significant reduction in file size is at level 4, but that is already 4 times slower. Level 3 is primarily 50% * slower while not improving the filesize, while level 0 and 1 are faster, but don't reduce savegame size much. * It's OTTX and not e.g. OTTL because liblzma is part of xz-utils and .tar.xz is preferred over .tar.lzma. */ - {"lzma", TO_BE32X('OTTX'), CreateLoadFilter, CreateSaveFilter, 0, 2, 9}, + {4, "lzma", TO_BE32X('OTTX'), CreateLoadFilter, CreateSaveFilter, citymania::CompressionMethod::LZMA, 0, 2, 9}, #else - {"lzma", TO_BE32X('OTTX'), nullptr, nullptr, 0, 0, 0}, + {4, "lzma", TO_BE32X('OTTX'), nullptr, nullptr, citymania::CompressionMethod::LZMA, 0, 0, 0}, #endif }; +namespace citymania { // citymania savegame format handling + +static const std::string DEFAULT_NETWORK_SAVEGAME_COMPRESSION = "zstd:1 zlib:2 lzma:0 lzo:0"; + +/** + * Parses the savegame format and compression level string ("format:[compression_level]"). + * @param str String to parse + * @return Parsest SavePreset or std::nullopt + */ +static std::optional ParseSavePreset(const std::string &str) +{ + auto delimiter_pos = str.find(':'); + auto format = (delimiter_pos != std::string::npos ? str.substr(0, delimiter_pos) : str); + for (auto &slf : _saveload_formats) { + if (slf.init_write != nullptr && format == slf.name) { + /* If compression level wasn't specified use the default one */ + if (delimiter_pos == std::string::npos) return SavePreset{&slf, slf.default_compression}; + + auto level_str = str.substr(delimiter_pos + 1); + int level; + try{ + level = stoi(level_str); + } catch(const std::exception &e) { + /* Can't parse compression level, set it out ouf bounds to fail later */ + level = (int)slf.max_compression + 1; + } + + if (level != Clamp(level, slf.min_compression, slf.max_compression)) { + /* Invalid compression level, show the error and use default level */ + SetDParamStr(0, level_str.c_str()); + ShowErrorMessage(STR_CONFIG_ERROR, STR_CONFIG_ERROR_INVALID_SAVEGAME_COMPRESSION_LEVEL, WL_CRITICAL); + return SavePreset{&slf, slf.default_compression}; + } + + return SavePreset{&slf, (byte)level}; + } + } + SetDParamStr(0, str.c_str()); + ShowErrorMessage(STR_CONFIG_ERROR, STR_CONFIG_ERROR_INVALID_SAVEGAME_COMPRESSION_ALGORITHM, WL_CRITICAL); + return {}; +} + +static_assert(lengthof(_saveload_formats) <= 8); // uint8 is used for the bitset of format ids + +/** + * Finds the best savegame preset to use in network game based on server settings and client capabilies. + * @param server_formats String of space-separated format descriptions in form format[:compression_level] acceptable for the server (listed first take priority). + * @param client_formats Bitset of savegame formats available to the client (as returned by GetAvailableLoadFormats) + * @return SavePreset that satisfies both server and client or std::nullopt + */ +std::optional FindCompatibleSavePreset(const std::string &server_formats, uint8 client_formats) +{ + std::istringstream iss(server_formats.empty() ? DEFAULT_NETWORK_SAVEGAME_COMPRESSION : server_formats); + std::string preset_str; + while (std::getline(iss, preset_str, ' ')) { + auto preset = ParseSavePreset(preset_str); + if (!preset) continue; + if ((client_formats & (1 << preset->format->id)) != 0) return preset; + } + return {}; +} + +/** + * Return the bitset of savegame formats that this game instance can load + * @return bitset of available savegame formats + */ +uint8 GetAvailableLoadFormats() +{ + return 3; + uint8 res = 0; + for(auto &slf : _saveload_formats) { + if (slf.init_load != nullptr) { + res &= (1 << slf.id); + } + } + return res; +} + +/** + * Return the save preset to use for local game saves. + * @return SavePreset to use + */ +static SavePreset GetLocalSavePreset() +{ + if (!StrEmpty(_savegame_format)) { + auto config = ParseSavePreset(_savegame_format); + if (config) return *config; + } + + const citymania::SaveLoadFormat *def = lastof(_saveload_formats); + + /* find default savegame format, the highest one with which files can be written */ + while (!def->init_write) def--; + + return {def, def->default_compression}; +} + +} // namespace citymania + /** * Return the savegameformat of the game. Whether it was created with ZLIB compression * uncompressed, or another type @@ -2355,6 +2578,8 @@ static const SaveLoadFormat _saveload_formats[] = { * @param compression_level Output for telling what compression level we want. * @return Pointer to SaveLoadFormat struct giving all characteristics of this type of savegame */ +#if 0 +Citymania uses other way static const SaveLoadFormat *GetSavegameFormat(char *s, byte *compression_level) { const SaveLoadFormat *def = lastof(_saveload_formats); @@ -2402,6 +2627,8 @@ static const SaveLoadFormat *GetSavegameFormat(char *s, byte *compression_level) return def; } +#endif + /* actual loader/saver function */ void InitializeGame(uint size_x, uint size_y, bool reset_date, bool reset_settings); extern bool AfterLoadGame(); @@ -2493,17 +2720,17 @@ static void SaveFileError() * We have written the whole game into memory, _memory_savegame, now find * and appropriate compressor and start writing to file. */ -static SaveOrLoadResult SaveFileToDisk(bool threaded) +static SaveOrLoadResult SaveFileToDisk(bool threaded, citymania::SavePreset preset) { try { - byte compression; - const SaveLoadFormat *fmt = GetSavegameFormat(_savegame_format, &compression); + // byte compression; + // const SaveLoadFormat *fmt = GetSavegameFormat(_savegame_format, &compression); /* We have written our stuff to memory, now write it to file! */ - uint32 hdr[2] = { fmt->tag, TO_BE32(SAVEGAME_VERSION << 16) }; + uint32 hdr[2] = { preset.format->tag, TO_BE32(SAVEGAME_VERSION << 16) }; _sl.sf->Write((byte*)hdr, sizeof(hdr)); - _sl.sf = fmt->init_write(_sl.sf, compression); + _sl.sf = preset.format->init_write(_sl.sf, preset.compression_level); _sl.dumper->Flush(_sl.sf); ClearSaveLoadState(); @@ -2551,7 +2778,7 @@ void WaitTillSaved() * @param threaded Whether to try to perform the saving asynchronously. * @return Return the result of the action. #SL_OK or #SL_ERROR */ -static SaveOrLoadResult DoSave(SaveFilter *writer, bool threaded) +static SaveOrLoadResult DoSave(SaveFilter *writer, bool threaded, citymania::SavePreset preset) { assert(!_sl.saveinprogress); @@ -2565,10 +2792,10 @@ static SaveOrLoadResult DoSave(SaveFilter *writer, bool threaded) SaveFileStart(); - if (!threaded || !StartNewThread(&_save_thread, "ottd:savegame", &SaveFileToDisk, true)) { + if (!threaded || !StartNewThread(&_save_thread, "ottd:savegame", &SaveFileToDisk, true, std::move(preset))) { if (threaded) DEBUG(sl, 1, "Cannot create savegame thread, reverting to single-threaded mode..."); - SaveOrLoadResult result = SaveFileToDisk(false); + SaveOrLoadResult result = SaveFileToDisk(false, preset); SaveFileDone(); return result; @@ -2583,11 +2810,11 @@ static SaveOrLoadResult DoSave(SaveFilter *writer, bool threaded) * @param threaded Whether to try to perform the saving asynchronously. * @return Return the result of the action. #SL_OK or #SL_ERROR */ -SaveOrLoadResult SaveWithFilter(SaveFilter *writer, bool threaded) +SaveOrLoadResult SaveWithFilter(SaveFilter *writer, bool threaded, citymania::SavePreset preset) { try { _sl.action = SLA_SAVE; - return DoSave(writer, threaded); + return DoSave(writer, threaded, preset); } catch (...) { ClearSaveLoadState(); return SL_ERROR; @@ -2615,7 +2842,7 @@ static SaveOrLoadResult DoLoad(LoadFilter *reader, bool load_check) if (_sl.lf->Read((byte*)hdr, sizeof(hdr)) != sizeof(hdr)) SlError(STR_GAME_SAVELOAD_ERROR_FILE_NOT_READABLE); /* see if we have any loader for this type. */ - const SaveLoadFormat *fmt = _saveload_formats; + const citymania::SaveLoadFormat *fmt = _saveload_formats; for (;;) { /* No loader found, treat as version 0 and use LZO format */ if (fmt == endof(_saveload_formats)) { @@ -2828,7 +3055,7 @@ SaveOrLoadResult SaveOrLoad(const std::string &filename, SaveLoadOperation fop, DEBUG(desync, 1, "save: %08x; %02x; %s", _date, _date_fract, filename.c_str()); if (_network_server || !_settings_client.gui.threaded_saves) threaded = false; - return DoSave(new FileWriter(fh), threaded); + return DoSave(new FileWriter(fh), threaded, citymania::GetLocalSavePreset()); } /* LOAD game */ diff --git a/src/saveload/saveload.h b/src/saveload/saveload.h index 7f4f0d287c..f04558003e 100644 --- a/src/saveload/saveload.h +++ b/src/saveload/saveload.h @@ -12,6 +12,8 @@ #include "../fileio_type.h" #include "../strings_type.h" +#include "saveload_filter.h" +#include #include /** SaveLoad versions @@ -359,6 +361,42 @@ enum SavegameType { SGT_INVALID = 0xFF, ///< broken savegame (used internally) }; +namespace citymania { + +enum class CompressionMethod : uint8 { + None = 0u, + LZO = 1u, + Zlib = 2u, + ZSTD = 3u, + LZMA = 4u, +}; + +/** The format for a reader/writer type of a savegame */ +struct SaveLoadFormat { + uint8 id; ///< unique integer id of this savegame format (olny used for networkking so is not guaranteed to be preserved between versions) + const char *name; ///< name of the compressor/decompressor (debug-only) + uint32 tag; ///< the 4-letter tag by which it is identified in the savegame + + LoadFilter *(*init_load)(LoadFilter *chain); ///< Constructor for the load filter. + SaveFilter *(*init_write)(SaveFilter *chain, byte compression); ///< Constructor for the save filter. + + CompressionMethod method; ///< compression method used in this format + byte min_compression; ///< the minimum compression level of this format + byte default_compression; ///< the default compression level of this format + byte max_compression; ///< the maximum compression level of this format +}; + +/** The preset to use for generating savegames */ +struct SavePreset { + const SaveLoadFormat *format; ///< savegame format to use + byte compression_level; ///< compression level to use +}; + +std::optional FindCompatibleSavePreset(const std::string &server_formats, uint8 client_format_flags); +uint8 GetAvailableLoadFormats(); + +} // namespace citymania + extern FileToSaveLoad _file_to_saveload; void GenerateDefaultSaveName(char *buf, const char *last); @@ -369,7 +407,7 @@ void WaitTillSaved(); void ProcessAsyncSaveFinish(); void DoExitSave(); -SaveOrLoadResult SaveWithFilter(struct SaveFilter *writer, bool threaded); +SaveOrLoadResult SaveWithFilter(struct SaveFilter *writer, bool threaded, citymania::SavePreset preset); SaveOrLoadResult LoadWithFilter(struct LoadFilter *reader); typedef void ChunkSaveLoadProc(); diff --git a/src/viewport.cpp b/src/viewport.cpp index 93e25e40b6..a56fa38ac3 100644 --- a/src/viewport.cpp +++ b/src/viewport.cpp @@ -4006,7 +4006,7 @@ static LineSnapPoint LineSnapPointAtRailTrackEndpoint(TileIndex tile, DiagDirect TrackStatusToTrackBits(GetTileTrackStatus(tile, TRANSPORT_RAIL, INVALID_DIAGDIR)) == AxisToTrackBits(DiagDirToAxis(exit_dir)) && IsTileOwner(tile, _local_company)) { /* Check if this is a tunnel/bridge and move the tile to the other end if so. */ - if (IsTileType(tile, MP_TUNNELBRIDGE)) tile = GetOtherTunnelBridgeEnd(tile); + if (IsTileType(tile, MP_TUNNELBRIDGE) && GetTunnelBridgeDirection(tile) == exit_dir) tile = GetOtherTunnelBridgeEnd(tile); LineSnapPoint ex = LineSnapPointAtRailTrackEndpoint(tile, exit_dir, false, extended); if (!bidirectional) return ex; // if we are interested in forward direction only then return just the extended point *extended = ex; // otherwise return two points, extended with forward direction and base with reverse direction