diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d9227eb..a4d882d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -22,13 +22,6 @@ jobs: cxx: "g++", cxxpackage: "g++" } - - { - name: "Ubuntu GCC 7", - os: ubuntu-latest, - cc: "gcc-7", - cxx: "g++-7", - cxxpackage: "g++-7" - } - { name: "Ubuntu Clang", os: ubuntu-latest, @@ -43,20 +36,38 @@ jobs: cxx: "clang++", cxxpackage: "clang++" } + - { + name: "FreeBSD", + os: ubuntu-latest, + cc: "clang", + cxx: "clang++", + freebsd: true + } steps: - name: Checkout Code - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Install Linux Dependencies - if: runner.os == 'Linux' - run: sudo apt-get update && sudo apt-get install $CC $CXXPACKAGE libopenal-dev zlib1g-dev libfreetype6-dev libjpeg-dev libsfml-dev libavutil-dev libavcodec-dev libavformat-dev libswscale-dev libswresample-dev libarchive-dev libfontconfig1-dev libxinerama-dev libxrandr-dev freeglut3-dev libcurl4-openssl-dev pkg-config + if: runner.os == 'Linux' && !matrix.config.freebsd + run: sudo apt-get update && sudo apt-get install ${{ matrix.config.cxxpackage }} libopenal-dev zlib1g-dev libfreetype6-dev libjpeg-dev libsfml-dev libavutil-dev libavcodec-dev libavformat-dev libswscale-dev libswresample-dev libarchive-dev libfontconfig1-dev libxinerama-dev libxrandr-dev freeglut3-dev libcurl4-openssl-dev pkg-config - name: Install MacOS Dependencies - if: runner.os == 'MacOS' + if: runner.os == 'macOS' run: brew update && brew install ffmpeg sfml libarchive curl + - name: Build on FreeBSD + if: matrix.config.freebsd + uses: vmactions/freebsd-vm@v1 + with: + usesh: true + run: | + pkg install -y gmake clang pkgconf sfml openal-soft ffmpeg libarchive curl fontconfig libGLU + gmake clean + gmake + - name: Build + if: '!matrix.config.freebsd' env: CC: ${{ matrix.config.cc }} CXX: ${{ matrix.config.cxx }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 2c7cbb7..a967328 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -13,17 +13,21 @@ jobs: outputs: upload_url: ${{ steps.create_release.outputs.upload_url }} tag_name: ${{ steps.tag_name.outputs.tag_name }} - version: ${{ steps.changelog.outputs.version }} steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - name: Get Tag Name id: tag_name - run: echo ::set-output name=tag_name::${GITHUB_REF/refs\/tags\//} + run: echo "tag_name=${GITHUB_REF/refs\/tags\//}" >> $GITHUB_OUTPUT - name: Generate ChangeLog id: changelog - run: util/output-changelog-md.sh >release.txt + run: | + if [ -f util/output-changelog-md.sh ]; then + util/output-changelog-md.sh > release.txt + else + echo "Release ${{ steps.tag_name.outputs.tag_name }}" > release.txt + fi - name: Create Release id: create_release @@ -36,27 +40,59 @@ jobs: body_path: release.txt draft: true prerelease: false - macosx: - name: MacOS Release - runs-on: macos-latest - continue-on-error: false - needs: draft_release - steps: - - uses: actions/checkout@v2 - - name: Install MacOS Dependencies - run: brew update && brew install ffmpeg sfml libarchive curl + macosx: + name: MacOS Release + runs-on: macos-latest + continue-on-error: false + needs: draft_release + steps: + - uses: actions/checkout@v4 - - name: MacOS Package - run: util/osx/create-pkg.sh ${{ github.ref }} + - name: Install MacOS Dependencies + run: brew update && brew install ffmpeg sfml libarchive curl - - name: Upload Release Asset - id: upload-release-asset - uses: actions/upload-release-asset@v1 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - with: - upload_url: ${{ needs.draft_release.outputs.upload_url }} - asset_path: ./attract-${{ github.ref }}.dmg - asset_name: attract-${{ github.ref }}.dmg - asset_content_type: application/zip + - name: MacOS Package + run: util/osx/create-pkg.sh ${{ needs.draft_release.outputs.tag_name }} + + - name: Upload Release Asset + uses: actions/upload-release-asset@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + upload_url: ${{ needs.draft_release.outputs.upload_url }} + asset_path: ./attract-${{ needs.draft_release.outputs.tag_name }}.dmg + asset_name: attract-${{ needs.draft_release.outputs.tag_name }}.dmg + asset_content_type: application/zip + + freebsd: + name: FreeBSD Release + runs-on: ubuntu-latest + continue-on-error: false + needs: draft_release + steps: + - uses: actions/checkout@v4 + + - name: Build FreeBSD Release + uses: vmactions/freebsd-vm@v1 + with: + usesh: true + run: | + pkg install -y gmake clang pkgconf sfml openal-soft ffmpeg libarchive curl fontconfig libGLU + gmake clean + gmake + mkdir -p attract-freebsd + cp attract attract-freebsd/ + cp -r config attract-freebsd/ + cp Readme.md License.txt attract-freebsd/ + tar -czf attract-freebsd-${{ needs.draft_release.outputs.tag_name }}.tar.gz attract-freebsd/ + + - name: Upload FreeBSD Release Asset + uses: actions/upload-release-asset@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + upload_url: ${{ needs.draft_release.outputs.upload_url }} + asset_path: ./attract-freebsd-${{ needs.draft_release.outputs.tag_name }}.tar.gz + asset_name: attract-freebsd-${{ needs.draft_release.outputs.tag_name }}.tar.gz + asset_content_type: application/gzip diff --git a/Makefile b/Makefile index 45f42dc..61b11c1 100644 --- a/Makefile +++ b/Makefile @@ -69,6 +69,10 @@ FE_VERSION=v2.7.0 +# Detect operating system +UNAME_S := $(shell uname -s) + +# Default settings CC=gcc CXX=g++ CFLAGS= @@ -83,6 +87,15 @@ RM=rm -f MD=mkdir -p WINDRES=windres +# FreeBSD-specific settings +ifeq ($(UNAME_S),FreeBSD) +CC=clang +CXX=clang++ +CXXFLAGS=-std=c++14 $(EXTRA_CXXFLAGS) +PKG_CONFIG=pkgconf +NO_SWF=1 +endif + -include attract.mk OPTIMIZE ?= 2 @@ -788,9 +801,16 @@ $(DATA_PATH): $(MD) -p $(DESTDIR)$@ install: $(EXE) $(DATA_PATH) +ifeq ($(UNAME_S),FreeBSD) + mkdir -p $(DESTDIR)$(bindir) + install $(EXE) $(DESTDIR)$(bindir)/$(EXE) + mkdir -p $(DESTDIR)$(DATA_PATH) + cp -r config/* $(DESTDIR)$(DATA_PATH) +else install -D $(EXE) $(DESTDIR)$(bindir)/$(EXE) mkdir -p $(DESTDIR)$(DATA_PATH) cp -r config/* $(DESTDIR)$(DATA_PATH) +endif smallclean: -$(RM) $(OBJ_DIR)/*.o *~ core diff --git a/extlibs/gameswf/base/container.h b/extlibs/gameswf/base/container.h index 21ffd67..2b05c53 100644 --- a/extlibs/gameswf/base/container.h +++ b/extlibs/gameswf/base/container.h @@ -17,10 +17,16 @@ #include #include // for strcmp and friends #include // for placement new - +#ifdef __FreeBSD__ +#include +#endif // If you prefer STL implementations of array<> (i.e. std::vector) and +#ifdef __FreeBSD__ +// hash<> (i.e. std::unordered_map) instead of home cooking, then put +#else // hash<> (i.e. std::hash_map) instead of home cooking, then put +#endif // -D_TU_USE_STL=1 in your compiler flags, or do it in tu_config.h, or do // it right here: //#define _TU_USE_STL 1 @@ -71,6 +77,8 @@ public: #if defined(__APPLE__) || defined(ANDROID) #include +#elif defined(__FreeBSD__) +#include #else #include #endif @@ -120,11 +128,19 @@ public: }; +#ifdef __FreeBSD__ +// hash<> is similar to std::hash_map<>, but now converted to use unordered_map +#else // hash<> is similar to std::hash_map<> +#endif // // @@ move this towards a strict subset of std::hash_map<> ? template > +#ifdef __FreeBSD__ +class hash : public std::unordered_map +#else class hash : public __gnu_cxx::hash_map +#endif { public: // extra convenience interfaces @@ -139,7 +155,11 @@ public: (*this)[key] = value; } +#ifdef __FreeBSD__ + bool is_empty() const { return std::unordered_map::empty(); } +#else bool is_empty() const { return __gnu_cxx::hash_map::empty(); } +#endif bool get(const T& key, U* value) const // Retrieve the value under the given key. @@ -153,8 +173,13 @@ public: // If value == NULL, return true or false according to the // presence of the key, but don't touch *value. { +#ifdef __FreeBSD__ + typename std::unordered_map::const_iterator it = std::unordered_map::find(key); + if (it != std::unordered_map::end()) +#else typename __gnu_cxx::hash_map::const_iterator it = __gnu_cxx::hash_map::find(key); if (it != __gnu_cxx::hash_map::end()) +#endif { if (value) *value = it->second; return true; @@ -165,7 +190,11 @@ public: } } +#ifdef __FreeBSD__ + void set_capacity( int c ) { std::unordered_map::rehash(c); } +#else void set_capacity( int c ) { __gnu_cxx::hash_map::resize(c); } +#endif }; diff --git a/extlibs/gameswf/base/tu_timer.cpp b/extlibs/gameswf/base/tu_timer.cpp index fe154a0..03b1750 100755 --- a/extlibs/gameswf/base/tu_timer.cpp +++ b/extlibs/gameswf/base/tu_timer.cpp @@ -5,21 +5,40 @@ // Utility/profiling timer. +#ifdef __FreeBSD__ +#include +#else #include // for ftime() +#endif #include #include "base/tu_timer.h" +#ifdef __FreeBSD__ +// static timeb s_start_time; +static std::chrono::steady_clock::time_point s_start_time; +#else static timeb s_start_time; +#endif void tu_timer::init_timer() { +#ifdef __FreeBSD__ + s_start_time = std::chrono::steady_clock::now(); +#else ftime(&s_start_time); +#endif } Uint32 tu_timer::get_ticks() { +#ifdef __FreeBSD__ + auto now = std::chrono::steady_clock::now(); + auto elapsed = std::chrono::duration_cast(now - s_start_time).count(); + return static_cast(elapsed); +#else struct timeb tv; ftime(&tv); return (tv.time - s_start_time.time) * 1000 + (tv.millitm - s_start_time.millitm); +#endif } tu_datetime::tu_datetime() diff --git a/extlibs/gameswf/base/utility.cpp b/extlibs/gameswf/base/utility.cpp index 4226fd9..f38947d 100644 --- a/extlibs/gameswf/base/utility.cpp +++ b/extlibs/gameswf/base/utility.cpp @@ -45,6 +45,7 @@ void dump_memory_stats(const char *from, int line, const char *label) // This does not work with DMALLOC, since the internal data structures // differ. +#ifdef __linux__ #ifndef USE_DMALLOC struct mallinfo mi; @@ -75,6 +76,7 @@ void dump_memory_stats(const char *from, int line, const char *label) //} #endif // not USE_DMALLOC +#endif #endif // not _WIN32 } diff --git a/util/output-changelog-md.sh b/util/output-changelog-md.sh index e656048..dd1f2cc 100755 --- a/util/output-changelog-md.sh +++ b/util/output-changelog-md.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # # Generate markdown format changelog # from tag (default HEAD) to previous tag