diff --git a/.gitignore b/.gitignore index 922fac4aaf187f58ab2145c69641397c4ff81dc5..3090417dd6b00b8796d2743675301615e488707d 100644 --- a/.gitignore +++ b/.gitignore @@ -19,3 +19,5 @@ Win32_LIB_ASM_Release *.db *.opendb /.vs +/debian +/assets/debian diff --git a/.travis.yml b/.travis.yml index 15a3c844c1879a8accde781002dd4429d0d24cd5..6d2e8cddfc1d55810123c5da2a083197dc2cec9f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,9 +1,20 @@ +# Travis-CI Config +# +# You may use the Deployer to upload packages and builds to external servers. +# See deployer/travis/deployer_defaults.sh for environment variables to configure. + language: c sudo: required dist: trusty matrix: include: +################################ +# Test Buildbots +# Deployer does not operate on these. See Deployer Buildbots, below. +# These bots are disabled when a deployment is triggered by 'deployer' branch name AND DPL_TERMINATE_TESTS=1. +# These bots remain enabled when a deployment is triggered by release tag. +################################ - os: linux addons: apt: @@ -16,6 +27,7 @@ matrix: - gcc-4.4 compiler: gcc-4.4 env: GCC44=1 + if: env(DPL_ENABLED) != "1" OR env(DPL_TERMINATE_TESTS) != "1" OR NOT branch =~ /^.*deployer.*$/ #gcc-4.4 (Ubuntu/Linaro 4.4.7-8ubuntu1) 4.4.7 - os: linux addons: @@ -29,6 +41,7 @@ matrix: - gcc-4.6 compiler: gcc-4.6 env: GCC46=1 + if: env(DPL_ENABLED) != "1" OR env(DPL_TERMINATE_TESTS) != "1" OR NOT branch =~ /^.*deployer.*$/ #gcc-4.6 (Ubuntu/Linaro 4.6.4-6ubuntu2) 4.6.4 - os: linux addons: @@ -42,10 +55,12 @@ matrix: - gcc-4.7 compiler: gcc-4.7 env: GCC47=1 + if: env(DPL_ENABLED) != "1" OR env(DPL_TERMINATE_TESTS) != "1" OR NOT branch =~ /^.*deployer.*$/ #gcc-4.7 - os: linux compiler: gcc env: GCC48=1 + if: env(DPL_ENABLED) != "1" OR env(DPL_TERMINATE_TESTS) != "1" OR NOT branch =~ /^.*deployer.*$/ #gcc (Ubuntu 4.8.4-2ubuntu1~14.04) 4.8.4 - os: linux addons: @@ -61,6 +76,7 @@ matrix: - gcc-4.8 compiler: gcc-4.8 env: GCC48=1 + if: env(DPL_ENABLED) != "1" OR env(DPL_TERMINATE_TESTS) != "1" OR NOT branch =~ /^.*deployer.*$/ #gcc-4.8 (Ubuntu 4.8.5-2ubuntu1~14.04.1) 4.8.5 - os: linux addons: @@ -76,6 +92,7 @@ matrix: - gcc-7 compiler: gcc-7 env: WFLAGS="-Wno-tautological-compare -Wno-error=implicit-fallthrough -Wno-implicit-fallthrough" GCC72=1 + if: env(DPL_ENABLED) != "1" OR env(DPL_TERMINATE_TESTS) != "1" OR NOT branch =~ /^.*deployer.*$/ #gcc-7 (Ubuntu 7.2.0-1ubuntu1~14.04) 7.2.0 20170802 - os: linux addons: @@ -90,10 +107,12 @@ matrix: - p7zip-full - gcc-8 compiler: gcc-8 - env: WFLAGS="-Wno-tautological-compare -Wno-error=implicit-fallthrough -Wno-implicit-fallthrough -Wno-error=format-overflow" GCC81=1 + env: WFLAGS="-Wno-tautological-compare -Wno-error=implicit-fallthrough -Wno-implicit-fallthrough -Wno-error=format-overflow -Wno-error=format-truncation" GCC81=1 + if: env(DPL_ENABLED) != "1" OR env(DPL_TERMINATE_TESTS) != "1" OR NOT branch =~ /^.*deployer.*$/ #gcc-8 (Ubuntu 7.2.0-1ubuntu1~14.04) 8.1.0 - os: linux compiler: clang + if: env(DPL_ENABLED) != "1" OR env(DPL_TERMINATE_TESTS) != "1" OR NOT branch =~ /^.*deployer.*$/ #clang version 3.5.0 (tags/RELEASE_350/final) - os: linux addons: @@ -108,6 +127,7 @@ matrix: - p7zip-full - clang-3.5 compiler: clang-3.5 + if: env(DPL_ENABLED) != "1" OR env(DPL_TERMINATE_TESTS) != "1" OR NOT branch =~ /^.*deployer.*$/ #Ubuntu clang version 3.5.0-4ubuntu2~trusty2 (tags/RELEASE_350/final) (based on LLVM 3.5.0) - os: linux addons: @@ -123,6 +143,7 @@ matrix: - p7zip-full - clang-3.6 compiler: clang-3.6 + if: env(DPL_ENABLED) != "1" OR env(DPL_TERMINATE_TESTS) != "1" OR NOT branch =~ /^.*deployer.*$/ #Ubuntu clang version 3.6.2-svn240577-1~exp1 (branches/release_36) (based on LLVM 3.6.2) - os: linux addons: @@ -138,6 +159,7 @@ matrix: - p7zip-full - clang-3.7 compiler: clang-3.7 + if: env(DPL_ENABLED) != "1" OR env(DPL_TERMINATE_TESTS) != "1" OR NOT branch =~ /^.*deployer.*$/ #Ubuntu clang version 3.7.1-svn253571-1~exp1 (branches/release_37) (based on LLVM 3.7.1) - os: linux addons: @@ -153,6 +175,7 @@ matrix: - p7zip-full - clang-3.8 compiler: clang-3.8 + if: env(DPL_ENABLED) != "1" OR env(DPL_TERMINATE_TESTS) != "1" OR NOT branch =~ /^.*deployer.*$/ #clang version 3.8.1-svn271127-1~exp1 (branches/release_38) - os: linux addons: @@ -168,6 +191,7 @@ matrix: - p7zip-full - clang-3.9 compiler: clang-3.9 + if: env(DPL_ENABLED) != "1" OR env(DPL_TERMINATE_TESTS) != "1" OR NOT branch =~ /^.*deployer.*$/ #clang version 3.9.X # - os: linux # addons: @@ -183,6 +207,7 @@ matrix: # - p7zip-full # - clang-4.0 # compiler: clang-4.0 +# if: env(DPL_ENABLED) != "1" OR env(DPL_TERMINATE_TESTS) != "1" OR NOT branch =~ /^.*deployer.*$/ # #clang version 4.0.X # - os: linux # addons: @@ -198,34 +223,325 @@ matrix: # - p7zip-full # - clang-5.0 # compiler: clang-5.0 +# if: env(DPL_ENABLED) != "1" OR env(DPL_TERMINATE_TESTS) != "1" OR NOT branch =~ /^.*deployer.*$/ # #clang version 5.0.X # - os: osx # osx_image: beta-xcode6.1 +# if: env(DPL_ENABLED) != "1" OR env(DPL_TERMINATE_TESTS) != "1" OR NOT branch =~ /^.*deployer.*$/ # #Apple LLVM version 6.0 (clang-600.0.54) (based on LLVM 3.5svn) # - os: osx # osx_image: beta-xcode6.2 # compiler: gcc +# if: env(DPL_ENABLED) != "1" OR env(DPL_TERMINATE_TESTS) != "1" OR NOT branch =~ /^.*deployer.*$/ # #Apple LLVM version 6.0 (clang-600.0.57) (based on LLVM 3.5svn) ## - os: osx ## osx_image: beta-xcode6.3 +## if: env(DPL_ENABLED) != "1" OR env(DPL_TERMINATE_TESTS) != "1" OR NOT branch =~ /^.*deployer.*$/ ## #I think xcode.6.3 VM is broken, it does not boot # - os: osx # osx_image: xcode6.4 +# if: env(DPL_ENABLED) != "1" OR env(DPL_TERMINATE_TESTS) != "1" OR NOT branch =~ /^.*deployer.*$/ # #Apple LLVM version 6.1.0 (clang-602.0.53) (based on LLVM 3.6.0svn) # - os: osx # osx_image: xcode7 +# if: env(DPL_ENABLED) != "1" OR env(DPL_TERMINATE_TESTS) != "1" OR NOT branch =~ /^.*deployer.*$/ # #Apple LLVM version 7.0.0 (clang-700.0.72) # - os: osx # osx_image: xcode7.1 +# if: env(DPL_ENABLED) != "1" OR env(DPL_TERMINATE_TESTS) != "1" OR NOT branch =~ /^.*deployer.*$/ # #Apple LLVM version 7.0.0 (clang-700.1.76) # - os: osx # osx_image: xcode7.2 +# if: env(DPL_ENABLED) != "1" OR env(DPL_TERMINATE_TESTS) != "1" OR NOT branch =~ /^.*deployer.*$/ # #Apple LLVM version 7.0.2 (clang-700.1.81) # - os: osx # osx_image: xcode7.3 +# #Apple LLVM version 7.3.0 (clang-703.0.31) +# - os: osx +# osx_image: xcode7.3 # #Apple LLVM version 7.3.0 (clang-703.0.31) - os: osx + if: env(DPL_ENABLED) != "1" OR env(DPL_TERMINATE_TESTS) != "1" OR NOT branch =~ /^.*deployer.*$/ #Default: macOS 10.13 and Xcode 9.4.1 + + +################################ +# Deployer Buildbots - OSX +################################ + - os: osx + if: env(DPL_ENABLED) = "1" AND (env(_DPL_JOB_ENABLED) = "1" OR env(DPL_JOB_ENABLE_ALL) = "1") + AND (branch =~ /^.*deployer.*$/ OR (tag IS present AND env(DPL_TAG_ENABLED) = "1")) + AND env(DPL_TERMINATE_MAIN) != "1" + env: + - _DPL_JOB_ENABLED=1 + - _DPL_JOB_NAME=osx + - _DPL_FTP_TARGET=1 + - _DPL_PACKAGE_BINARY=1 + #Apple LLVM version 7.3.0 (clang-703.0.31) + + +################################ +# Deployer Buildbots - Linux assets +# Set DPL_TERMINATE_ASSETS to disable all of these +# List Ubuntu LTS next, newest to oldest +# Then list non-LTS, newest to oldest +################################ + - os: linux + addons: + apt: + packages: + - libsdl2-mixer-dev + - libpng-dev + - libgl1-mesa-dev + - libgme-dev + - p7zip-full + - gcc-4.8 + compiler: gcc-4.8 + dist: xenial + if: env(DPL_ENABLED) = "1" AND (env(_DPL_JOB_ENABLED) = "1" OR env(DPL_JOB_ENABLE_ALL) = "1") + AND (branch =~ /^.*deployer.*$/ OR (tag IS present AND env(DPL_TAG_ENABLED) = "1")) + AND env(DPL_TERMINATE_ASSETS) != "1" + env: + - _DPL_JOB_ENABLED=1 + - _DPL_JOB_NAME=bionic-asset + - _DPL_DPUT_TARGET=1 + - _DPL_PACKAGE_SOURCE=1 + - _DPL_PACKAGE_MAIN=0 + - _DPL_PACKAGE_ASSET=1 + - PACKAGE_DISTRO=bionic + #- PACKAGE_SUBVERSION=~18.04bionic + #gcc-4.8 (Ubuntu 4.8.5-2ubuntu1~14.04.1) 4.8.5 + + ################################ + # The below asset bots produce packages that occupy too much space. + # It would be nice if the asset files were not included in the source package itself, + # so these can deploy to each Ubuntu target without manual intervention. + # + # Currently, to get around Launchpad's space limitation, + # copy the packages from *one* bot and the space usage is not increased. + ################################ + # - os: linux + # addons: + # apt: + # packages: + # - libsdl2-mixer-dev + # - libpng-dev + # - libgl1-mesa-dev + # - libgme-dev + # - p7zip-full + # - gcc-4.8 + # compiler: gcc-4.8 + # dist: trusty + # if: env(DPL_ENABLED) = "1" AND (env(_DPL_JOB_ENABLED) = "1" OR env(DPL_JOB_ENABLE_ALL) = "1") + # AND (branch =~ /^.*deployer.*$/ OR (tag IS present AND env(DPL_TAG_ENABLED) = "1")) + # AND env(DPL_TERMINATE_ASSETS) != "1" + # env: + # - _DPL_JOB_ENABLED=1 + # - _DPL_JOB_NAME=trusty-asset + # - _DPL_DPUT_TARGET=1 + # - _DPL_PACKAGE_SOURCE=1 + # - _DPL_PACKAGE_MAIN=0 + # - _DPL_PACKAGE_ASSET=1 + # - PACKAGE_DISTRO=trusty + # #- PACKAGE_SUBVERSION=~14.04trusty + # #gcc-4.8 (Ubuntu 4.8.5-2ubuntu1~14.04.1) 4.8.5 + # - os: linux + # addons: + # apt: + # packages: + # - libsdl2-mixer-dev + # - libpng-dev + # - libgl1-mesa-dev + # - libgme-dev + # - p7zip-full + # - gcc-4.8 + # compiler: gcc-4.8 + # dist: xenial + # if: env(DPL_ENABLED) = "1" AND (env(_DPL_JOB_ENABLED) = "1" OR env(DPL_JOB_ENABLE_ALL) = "1") + # AND (branch =~ /^.*deployer.*$/ OR (tag IS present AND env(DPL_TAG_ENABLED) = "1")) + # AND env(DPL_TERMINATE_ASSETS) != "1" + # env: + # - _DPL_JOB_ENABLED=1 + # - _DPL_JOB_NAME=disco-asset + # - _DPL_DPUT_TARGET=1 + # - _DPL_PACKAGE_SOURCE=1 + # - _DPL_PACKAGE_MAIN=0 + # - _DPL_PACKAGE_ASSET=1 + # - PACKAGE_DISTRO=disco + # #- PACKAGE_SUBVERSION=~19.04disco + # #gcc-4.8 (Ubuntu 4.8.5-2ubuntu1~14.04.1) 4.8.5 + # - os: linux + # addons: + # apt: + # packages: + # - libsdl2-mixer-dev + # - libpng-dev + # - libgl1-mesa-dev + # - libgme-dev + # - p7zip-full + # - gcc-4.8 + # compiler: gcc-4.8 + # dist: xenial + # if: env(DPL_ENABLED) = "1" AND (env(_DPL_JOB_ENABLED) = "1" OR env(DPL_JOB_ENABLE_ALL) = "1") + # AND (branch =~ /^.*deployer.*$/ OR (tag IS present AND env(DPL_TAG_ENABLED) = "1")) + # AND env(DPL_TERMINATE_ASSETS) != "1" + # env: + # - _DPL_JOB_ENABLED=1 + # - _DPL_JOB_NAME=cosmic-asset + # - _DPL_DPUT_TARGET=1 + # - _DPL_PACKAGE_SOURCE=1 + # - _DPL_PACKAGE_MAIN=0 + # - _DPL_PACKAGE_ASSET=1 + # - PACKAGE_DISTRO=cosmic + # #- PACKAGE_SUBVERSION=~18.10cosmic + # #gcc-4.8 (Ubuntu 4.8.5-2ubuntu1~14.04.1) 4.8.5 + # - os: linux + # addons: + # apt: + # packages: + # - libsdl2-mixer-dev + # - libpng-dev + # - libgl1-mesa-dev + # - libgme-dev + # - p7zip-full + # - gcc-4.8 + # compiler: gcc-4.8 + # dist: xenial + # if: env(DPL_ENABLED) = "1" AND (env(_DPL_JOB_ENABLED) = "1" OR env(DPL_JOB_ENABLE_ALL) = "1") + # AND (branch =~ /^.*deployer.*$/ OR (tag IS present AND env(DPL_TAG_ENABLED) = "1")) + # AND env(DPL_TERMINATE_ASSETS) != "1" + # env: + # - _DPL_JOB_ENABLED=1 + # - _DPL_JOB_NAME=xenial-asset + # - _DPL_DPUT_TARGET=1 + # - _DPL_PACKAGE_SOURCE=1 + # - _DPL_PACKAGE_MAIN=0 + # - _DPL_PACKAGE_ASSET=1 + # - PACKAGE_DISTRO=xenial + # #- PACKAGE_SUBVERSION=~16.04xenial + # #gcc-4.8 (Ubuntu 4.8.5-2ubuntu1~14.04.1) 4.8.5 + + +################################ +# Deployer Buildbots - Linux binaries +# List Ubuntu LTS, newest to oldest +# Then list non-LTS, newest to oldest +################################ + - os: linux + addons: + apt: + packages: + - libsdl2-mixer-dev + - libpng-dev + - libgl1-mesa-dev + - libgme-dev + - p7zip-full + - gcc-4.8 + compiler: gcc-4.8 + dist: xenial + if: env(DPL_ENABLED) = "1" AND (env(_DPL_JOB_ENABLED) = "1" OR env(DPL_JOB_ENABLE_ALL) = "1") + AND (branch =~ /^.*deployer.*$/ OR (tag IS present AND env(DPL_TAG_ENABLED) = "1")) + AND env(DPL_TERMINATE_MAIN) != "1" + env: + - _DPL_JOB_ENABLED=1 + - _DPL_JOB_NAME=bionic + - _DPL_DPUT_TARGET=1 + - _DPL_PACKAGE_SOURCE=1 + - PACKAGE_DISTRO=bionic + - PACKAGE_SUBVERSION=~18.04bionic + #gcc-4.8 (Ubuntu 4.8.5-2ubuntu1~14.04.1) 4.8.5 + - os: linux + addons: + apt: + packages: + - libsdl2-mixer-dev + - libpng-dev + - libgl1-mesa-dev + - libgme-dev + - p7zip-full + - gcc-4.8 + compiler: gcc-4.8 + dist: trusty + if: env(DPL_ENABLED) = "1" AND (env(_DPL_JOB_ENABLED) = "1" OR env(DPL_JOB_ENABLE_ALL) = "1") + AND (branch =~ /^.*deployer.*$/ OR (tag IS present AND env(DPL_TAG_ENABLED) = "1")) + AND env(DPL_TERMINATE_MAIN) != "1" + env: + - _DPL_JOB_ENABLED=1 + - _DPL_JOB_NAME=trusty + - _DPL_DPUT_TARGET=1 + - _DPL_PACKAGE_SOURCE=1 + - PACKAGE_DISTRO=trusty + - PACKAGE_SUBVERSION=~14.04trusty + #gcc-4.8 (Ubuntu 4.8.5-2ubuntu1~14.04.1) 4.8.5 + - os: linux + addons: + apt: + packages: + - libsdl2-mixer-dev + - libpng-dev + - libgl1-mesa-dev + - libgme-dev + - p7zip-full + - gcc-4.8 + compiler: gcc-4.8 + dist: xenial + if: env(DPL_ENABLED) = "1" AND (env(_DPL_JOB_ENABLED) = "1" OR env(DPL_JOB_ENABLE_ALL) = "1") + AND (branch =~ /^.*deployer.*$/ OR (tag IS present AND env(DPL_TAG_ENABLED) = "1")) + AND env(DPL_TERMINATE_MAIN) != "1" + env: + - _DPL_JOB_ENABLED=1 + - _DPL_JOB_NAME=disco + - _DPL_DPUT_TARGET=1 + - _DPL_PACKAGE_SOURCE=1 + - PACKAGE_DISTRO=disco + - PACKAGE_SUBVERSION=~19.04disco + #gcc-4.8 (Ubuntu 4.8.5-2ubuntu1~14.04.1) 4.8.5 + - os: linux + addons: + apt: + packages: + - libsdl2-mixer-dev + - libpng-dev + - libgl1-mesa-dev + - libgme-dev + - p7zip-full + - gcc-4.8 + compiler: gcc-4.8 + dist: xenial + if: env(DPL_ENABLED) = "1" AND (env(_DPL_JOB_ENABLED) = "1" OR env(DPL_JOB_ENABLE_ALL) = "1") + AND (branch =~ /^.*deployer.*$/ OR (tag IS present AND env(DPL_TAG_ENABLED) = "1")) + AND env(DPL_TERMINATE_MAIN) != "1" + env: + - _DPL_JOB_ENABLED=1 + - _DPL_JOB_NAME=cosmic + - _DPL_DPUT_TARGET=1 + - _DPL_PACKAGE_SOURCE=1 + - PACKAGE_DISTRO=cosmic + - PACKAGE_SUBVERSION=~18.10cosmic + #gcc-4.8 (Ubuntu 4.8.5-2ubuntu1~14.04.1) 4.8.5 + - os: linux + addons: + apt: + packages: + - libsdl2-mixer-dev + - libpng-dev + - libgl1-mesa-dev + - libgme-dev + - p7zip-full + - gcc-4.8 + compiler: gcc-4.8 + dist: xenial + if: env(DPL_ENABLED) = "1" AND (env(_DPL_JOB_ENABLED) = "1" OR env(DPL_JOB_ENABLE_ALL) = "1") + AND (branch =~ /^.*deployer.*$/ OR (tag IS present AND env(DPL_TAG_ENABLED) = "1")) + AND env(DPL_TERMINATE_MAIN) != "1" + env: + - _DPL_JOB_ENABLED=1 + - _DPL_JOB_NAME=xenial + - _DPL_DPUT_TARGET=1 + - _DPL_PACKAGE_SOURCE=1 + - PACKAGE_DISTRO=xenial + - PACKAGE_SUBVERSION=~16.04xenial + #gcc-4.8 (Ubuntu 4.8.5-2ubuntu1~14.04.1) 4.8.5 allow_failures: - compiler: clang-3.5 - compiler: clang-3.6 @@ -235,12 +551,14 @@ matrix: - compiler: clang-4.0 - compiler: clang-5.0 + cache: apt: true ccache: true directories: - $HOME/srb2_cache + addons: apt: packages: @@ -248,6 +566,7 @@ addons: - libpng-dev - libgl1-mesa-dev - libgme-dev + - zlib1g-dev - p7zip-full homebrew: taps: @@ -260,18 +579,115 @@ addons: update: true + +before_install: + # Initialize Deployer defaults + - . ./deployer/travis/deployer_defaults.sh + + # Initialize Deployer; check if Deployer is enabled + # This needs to be run in the current shell so that $__DPL_ACTIVE is set for this session + - . ./deployer/travis/deployer.sh + + # Also check if we should now terminate -- see `deployer.sh` for conditions. + # This should never happen on non-release buildbots when Deployer is not triggered. + - if [[ "$__DPL_TRY_TERMINATE_EARLY" == "1" ]]; then + if [[ "$__DPL_ACTIVE" != "1" ]]; then + echo "Exiting early because this job is not deploying."; + exit; + fi; + fi + + # If we're triggered by release tag, force ASSET_FILES_OPTIONAL_GET=1 + - if [[ "$__DPL_TAG_ELIGIBLE" = "1" ]]; then + ASSET_FILES_OPTIONAL_GET=1; + fi; + + +install: + # Install OS X library dependencies via Homebrew + # Do this differently for release buildbots: + # * `brew install --build-bottle` builds libraries for x86_64's lowest common denominator CPU, core2 + # * `sdl2_mixer` requires options from the formula tap https://github.com/mazmazz/homebrew-srb2 + # * `brew postinstall` runs post-install scripts after building a bottle + - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then + if [[ "$__DPL_ACTIVE" == "1" ]]; then + brew install --build-bottle sdl2 game-music-emu; + brew install --build-bottle mazmazz/srb2/sdl2_mixer --with-flac --with-mpg123; + brew postinstall sdl2 game-music-emu mazmazz/srb2/sdl2_mixer; + fi; + fi + - mkdir -p $HOME/srb2_cache + + before_script: - - wget --verbose --server-response -c http://rosenthalcastle.org/srb2/SRB2-v2115-assets-2.7z -O $HOME/srb2_cache/SRB2-v2115-assets-2.7z - - 7z x $HOME/srb2_cache/SRB2-v2115-assets-2.7z -oassets + # OLDPWD is root repo folder + - OLDPWD=$PWD + - __ASSET_DIRECTORY="$OLDPWD/assets/installer" + - mkdir -p "$__ASSET_DIRECTORY" + - cd "$HOME/srb2_cache" + + # Get stat command so we know what the cached archive date is. + # stat is different for OSX + - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then + STATCMD="stat -f %m"; + else + STATCMD="stat -c %y"; + fi + + # Get asset files (required for MD5) + # See `deployer_defaults.sh` for asset download path + - if [[ "$ASSET_ARCHIVE_PATH" != "" ]]; then + if [ -f "$(basename $ASSET_ARCHIVE_PATH)" ]; then + echo "$(basename $ASSET_ARCHIVE_PATH) cache date -- $($STATCMD $(basename $ASSET_ARCHIVE_PATH))"; + fi; + wget --verbose --server-response -N "$ASSET_ARCHIVE_PATH"; + 7z x "$(basename $ASSET_ARCHIVE_PATH)" -o"$__ASSET_DIRECTORY" -aos; + fi; + + # Get optional files too + - if [[ "$__DPL_ACTIVE" == "1" ]] && [[ "$ASSET_FILES_OPTIONAL_GET" == "1" ]] && [[ "$ASSET_ARCHIVE_OPTIONAL_PATH" != "" ]]; then + if [ -f "$(basename $ASSET_ARCHIVE_OPTIONAL_PATH)" ]; then + echo "$(basename $ASSET_ARCHIVE_OPTIONAL_PATH) cache date -- $($STATCMD $(basename $ASSET_ARCHIVE_OPTIONAL_PATH))"; + fi; + wget --verbose --server-response -N "$ASSET_ARCHIVE_OPTIONAL_PATH"; + 7z x "$(basename $ASSET_ARCHIVE_OPTIONAL_PATH)" -o"$__ASSET_DIRECTORY" -aos; + fi; + + # Go back to root repo folder + - cd "$OLDPWD" + + # Prepare CMake asset lists + - SRB2_ASSET_HASHED=$(echo ${ASSET_FILES_HASHED// /\;}) + - SRB2_ASSET_DOCS=$(echo ${ASSET_FILES_DOCS// /\;}) + - SRB2_ASSET_DIRECTORY="$__ASSET_DIRECTORY" + + # Prepare CMake - mkdir build - cd build + - mkdir package - export CFLAGS="-Wall -W -Werror $WFLAGS" - export CCACHE_COMPRESS=true - - cmake .. -DCMAKE_BUILD_TYPE=Release + # If OS X, set -march=core2 to build compatible binaries with old Macs + - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then + export CFLAGS="${CFLAGS} -march=core2"; + fi; + - cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$PWD/bin -DCPACK_PACKAGE_DIRECTORY=$PWD/package + -DSRB2_ASSET_HASHED="${SRB2_ASSET_HASHED}" -DSRB2_ASSET_DOCS="${SRB2_ASSET_DOCS}" + -DSRB2_ASSET_DIRECTORY="${SRB2_ASSET_DIRECTORY}" + -DCPACK_PACKAGE_DESCRIPTION_SUMMARY="${PROGRAM_NAME}" + -DCPACK_PACKAGE_VENDOR="${PROGRAM_VENDOR}" + -DSRB2_SDL2_EXE_NAME="${PROGRAM_FILENAME}" -before_install: - - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then curl -O -L https://www.libsdl.org/release/SDL2-2.0.6.dmg; hdiutil attach SDL2-2.0.6.dmg; sudo cp -a /Volumes/SDL2/SDL2.framework /Library/Frameworks/; fi - - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then curl -O -L https://www.libsdl.org/projects/SDL_mixer/release/SDL2_mixer-2.0.1.dmg; hdiutil attach SDL2_mixer-2.0.1.dmg; sudo cp -a /Volumes/SDL2_mixer/SDL2_mixer.framework /Library/Frameworks/; fi - - mkdir -p $HOME/srb2_cache +script: + # Build our Makefile from Cmake! + - if [[ "$__DPL_ACTIVE" == "1" ]]; then + . ../deployer/travis/deployer_build.sh; + else + make -k; + fi; -script: make -k +after_success: + # Run the upload scripts + # These do nothing if Deployer is not triggered + - . ../deployer/travis/deployer_ftp.sh + - . ../deployer/travis/deployer_dput.sh diff --git a/CMakeLists.txt b/CMakeLists.txt index 0a5507b924c38620bb9845e332e1af0b72b4972c..b702218592579c74176c96e7cf8ea761c9bc911f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,8 @@ cmake_minimum_required(VERSION 3.0) +# DO NOT CHANGE THIS SRB2 STRING! Some variable names depend on this string. +# Version change is fine. project(SRB2 - VERSION 2.1.23 + VERSION 2.1.24 LANGUAGES C) if(${PROJECT_SOURCE_DIR} MATCHES ${PROJECT_BINARY_DIR}) @@ -92,8 +94,8 @@ set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin") set(CMAKE_PDB_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin") # Set EXE names so the assets CMakeLists can refer to its target -set(SRB2_SDL2_EXE_NAME srb2) -set(SRB2_WIN_EXE_NAME srb2dd) +set(SRB2_SDL2_EXE_NAME srb2 CACHE STRING "Executable binary output name") +set(SRB2_WIN_EXE_NAME srb2dd CACHE STRING "Executable binary output name for DirectDraw build") include_directories(${CMAKE_CURRENT_BINARY_DIR}/src) @@ -122,8 +124,8 @@ if(${CMAKE_SYSTEM} MATCHES "Darwin") set(CPACK_GENERATOR "DragNDrop") endif() -set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Sonic Robo Blast 2") -set(CPACK_PACKAGE_VENDOR "Sonic Team Jr.") +set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Sonic Robo Blast 2" CACHE STRING "Program name for display purposes") +set(CPACK_PACKAGE_VENDOR "Sonic Team Jr." CACHE STRING "Vendor name for display purposes") #set(CPACK_PACKAGE_DESCRIPTION_FILE ) set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/LICENSE") set(CPACK_PACKAGE_VERSION_MAJOR ${SRB2_VERSION_MAJOR}) diff --git a/appveyor.yml b/appveyor.yml index f0f843fbb29dee5becc5d83404d91b557031107e..98da61dbf987652a76e4666eb41604c5e72bf6cb 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,4 +1,4 @@ -version: 2.1.23.{branch}-{build} +version: 2.1.24.{branch}-{build} os: MinGW environment: diff --git a/assets/.gitignore b/assets/.gitignore index 9ed61ca1ad2a899cddaa9311c3c0425e54cc68c5..d6e46a75b0f0d3aa04d5c319d41c456ef202bc54 100644 --- a/assets/.gitignore +++ b/assets/.gitignore @@ -1,5 +1,10 @@ -* -*.* +*.srb +*.pk3 +*.dta +*.wad +*.txt !README.txt !LICENSE.txt -!LICENSE-3RD-PARTY.txt \ No newline at end of file +!LICENSE-3RD-PARTY.txt +!CMakeLists.txt +!debian-template/* diff --git a/assets/CMakeLists.txt b/assets/CMakeLists.txt index 6edb3df130de0d7dd28c4d6d8431ea425a3fd227..68ff0fdf9fdd64134989b8a2a16fd7c74ff589a5 100644 --- a/assets/CMakeLists.txt +++ b/assets/CMakeLists.txt @@ -1,40 +1,58 @@ ## Assets Target Configuration ## -# MD5 generation -set(SRB2_ASSET_ALL - ${CMAKE_CURRENT_SOURCE_DIR}/srb2.srb - ${CMAKE_CURRENT_SOURCE_DIR}/player.dta - ${CMAKE_CURRENT_SOURCE_DIR}/rings.dta - ${CMAKE_CURRENT_SOURCE_DIR}/zones.dta - ${CMAKE_CURRENT_SOURCE_DIR}/patch.dta - ${CMAKE_CURRENT_SOURCE_DIR}/music.dta - ${CMAKE_CURRENT_SOURCE_DIR}/README.txt - ${CMAKE_CURRENT_SOURCE_DIR}/LICENSE.txt - ${CMAKE_CURRENT_SOURCE_DIR}/LICENSE-3RD-PARTY.txt -) +# For prepending the current source path, later +FUNCTION(PREPEND var prefix) + SET(listVar "") + FOREACH(f ${ARGN}) + LIST(APPEND listVar "${prefix}/${f}") + ENDFOREACH(f) + SET(${var} "${listVar}" PARENT_SCOPE) +ENDFUNCTION(PREPEND) + +set(SRB2_ASSET_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/installer" + CACHE STRING "Path to directory that contains all asset files for the installer.") set(SRB2_ASSET_HASHED - srb2.srb - player.dta - rings.dta - zones.dta - patch.dta +"srb2.srb;\ +player.dta;\ +rings.dta;\ +zones.dta;\ +patch.dta" + CACHE STRING "Asset filenames to apply MD5 checks. No spaces between entries!" +) + +set(SRB2_ASSET_DOCS +"README.txt;\ +LICENSE.txt;\ +LICENSE-3RD-PARTY.txt" + CACHE STRING "Documentation filenames. In OS X, these are packaged separately from other assets. No spaces between entries!" ) +PREPEND(SRB2_ASSET_DOCS ${SRB2_ASSET_DIRECTORY} ${SRB2_ASSET_DOCS}) + foreach(SRB2_ASSET ${SRB2_ASSET_HASHED}) - file(MD5 ${CMAKE_CURRENT_SOURCE_DIR}/${SRB2_ASSET} "SRB2_ASSET_${SRB2_ASSET}_HASH") + file(MD5 ${SRB2_ASSET_DIRECTORY}/${SRB2_ASSET} "SRB2_ASSET_${SRB2_ASSET}_HASH") set(SRB2_ASSET_${SRB2_ASSET}_HASH ${SRB2_ASSET_${SRB2_ASSET}_HASH} PARENT_SCOPE) endforeach() # Installation -if(CLANG) +if(${CMAKE_SYSTEM} MATCHES Darwin) get_target_property(outname SRB2SDL2 OUTPUT_NAME) - install(FILES ${SRB2_ASSET_ALL} + install(DIRECTORY "${SRB2_ASSET_DIRECTORY}/" DESTINATION "${outname}.app/Contents/Resources" ) + install(FILES ${SRB2_ASSET_DOCS} + DESTINATION . + OPTIONAL + ) else() - install(FILES ${SRB2_ASSET_ALL} + install(DIRECTORY "${SRB2_ASSET_DIRECTORY}/" DESTINATION . ) + # Docs are assumed to be located in SRB2_ASSET_DIRECTORY, so don't install again + #install(FILES ${SRB2_ASSET_DOCS} + # DESTINATION . + # OPTIONAL + #) endif() diff --git a/assets/debian/README.Debian b/assets/debian-template/README.Debian similarity index 59% rename from assets/debian/README.Debian rename to assets/debian-template/README.Debian index 68c952a4e8d0fa8dca227994afcb8d3bbd3cc38b..f3fe90030427b38888e2edb73312702580b52fef 100644 --- a/assets/debian/README.Debian +++ b/assets/debian-template/README.Debian @@ -12,9 +12,39 @@ with apt-key add. Thanks! -- Callum Dickinson <gcfreak_ag20@hotmail.com> Fri, 26 Nov 2010 18:25:31 +1300 +--------------- + + +Templating + +Note that you MUST run [repo-root]/debian_template.sh before running debuild +on these scripts! debian_template.sh fills these template files with working values. + +You should also set PACKAGE_NAME_EMAIL="John Doe <jdoe@example.com>" to match +the identity of the key you will use to sign the package. + + +Building for Launchpad PPA + +Run this step first: + + 1. source [repo-root]/debian_template.sh + * Initializes defaults for the package variables and fills in templates. + +Use these steps to prepare building a source package for Launchpad: + + 1. cd [repo-root]/assets/ + 2. debuild -T clean-all (optional; if you already have asset files, this clears them) + +Build the source package: + + 1. debuild -T build (this downloads the asset files from srb2.org if necessary) + 2. debuild -S (builds the source package for Launchpad, including the asset files) + + Signing for Launchpad PPA -First, follow the above instructions to generate a GnuPG key with your identity. You will need +First, follow Callum's instructions to generate a GnuPG key with your identity. You will need to publish the fingerprint of that key to Ubuntu's key server. https://help.ubuntu.com/community/GnuPrivacyGuardHowto#Uploading_the_key_to_Ubuntu_keyserver @@ -26,22 +56,18 @@ upload signed source packages and publish them onto your PPA. IF YOU UPLOAD A PACKAGE and Launchpad does NOT send you a confirmation or rejection email, that means your key is not set up correctly with your Launchpad account. +Finally, if your packages have not already been signed, follow these steps: -Building for Launchpad PPA + 1. cd .. + * Packages are located in the parent folder of where debuild was called + 2. debsign "srb2-data_[version]_source.changes" + * You may need to specify -k [key-fingerprint] -Use these steps to prepare building a source package for Launchpad: - - 1. Highly recommend copying the assets/ folder to outside your repo folder, or else the asset - files may be included in the main source package, when you build that. - 2. cd [wherever-your-assets-folder-is]/assets/ - 3. debuild -T clean (optional, if you already have asset files) - -Building the source package is a two-step process: - 1. debuild -T build (this downloads the asset files from srb2.org if necessary) - 2. debuild -S (builds the source package for Launchpad, including the asset files) +Uploading for Launchpad PPA -Then follow the instructions at <https://help.launchpad.net/Packaging/PPA/Uploading> to upload +Follow the instructions at <https://help.launchpad.net/Packaging/PPA/Uploading> to upload to your PPA and have Launchpad build your binary deb packages. + -- Marco Zafra <marco.a.zafra@gmail.com> Mon, 26 Nov 2018 21:13:00 -0500 diff --git a/assets/debian/README.source b/assets/debian-template/README.source similarity index 100% rename from assets/debian/README.source rename to assets/debian-template/README.source diff --git a/assets/debian-template/changelog b/assets/debian-template/changelog new file mode 100644 index 0000000000000000000000000000000000000000..64562e2a3140dbe67052291a8a7c2fab0a85f25e --- /dev/null +++ b/assets/debian-template/changelog @@ -0,0 +1,5 @@ +${PACKAGE_NAME}-data (${PACKAGE_VERSION}${PACKAGE_SUBVERSION}${PACKAGE_REVISION}) ${PACKAGE_DISTRO}; urgency=${PACKAGE_URGENCY} + + * ${PROGRAM_NAME} v${PROGRAM_VERSION} asset data + + -- ${PACKAGE_NAME_EMAIL} ${__PACKAGE_DATETIME} diff --git a/assets/debian/compat b/assets/debian-template/compat similarity index 100% rename from assets/debian/compat rename to assets/debian-template/compat diff --git a/assets/debian/control b/assets/debian-template/control similarity index 84% rename from assets/debian/control rename to assets/debian-template/control index 22d9643eedc665ced1dad165a878beabe98edb42..ae5c0ce67f7286bcc0b8f058f584747e6b1a6380 100644 --- a/assets/debian/control +++ b/assets/debian-template/control @@ -1,15 +1,15 @@ # SRB2-data Debian package control file. -Source: srb2-data +Source: ${PACKAGE_NAME}-data Section: games Priority: extra -Maintainer: Sonic Team Junior <stjr@srb2.org> +Maintainer: ${PACKAGE_GROUP_NAME_EMAIL} Build-Depends: debhelper (>= 7.0.50~), wget Standards-Version: 3.8.4 -Homepage: http://www.srb2.org +Homepage: ${PACKAGE_WEBSITE} -Package: srb2-data +Package: ${PACKAGE_NAME}-data Architecture: all Description: A cross-platform 3D Sonic fangame Sonic Robo Blast 2 is a 3D open-source Sonic the Hedgehog diff --git a/debian/copyright b/assets/debian-template/copyright similarity index 57% rename from debian/copyright rename to assets/debian-template/copyright index 97d606b0fb67b73eaae1858f43652006edfd91b6..cc47c453bf2b0ccc6db34c57a03dfe1ce2fc75a7 100644 --- a/debian/copyright +++ b/assets/debian-template/copyright @@ -1,18 +1,18 @@ This work was packaged for Debian by: - Marco Zafra <marco.a.zafra@gmail.com> Mon, 26 Nov 2018 14:31:00 -0500 + ${PACKAGE_NAME_EMAIL} ${__PACKAGE_DATETIME} It was downloaded from: - <http://srb2.org> + ${PACKAGE_WEBSITE} Upstream Author(s): - Sonic Team Junior <stjr@srb2.org> + ${PACKAGE_GROUP_NAME_EMAIL} Copyright: - Copyright (C) 1998-2018 Sonic Team Junior + Copyright (C) 1998-2018 by Sonic Team Junior License: @@ -21,7 +21,7 @@ License: The Debian packaging is: Copyright (C) 2010 Callum Dickinson <gcfreak_ag20@hotmail.com> - Copyright (C) 2010-2018 Sonic Team Junior <stjr@srb2.org> + Copyright (C) 2010-2018 by Sonic Team Junior <stjr@srb2.org> and is licensed under the GPL version 2, see "/usr/share/common-licenses/GPL-2". diff --git a/assets/debian/rules b/assets/debian-template/rules old mode 100755 new mode 100644 similarity index 70% rename from assets/debian/rules rename to assets/debian-template/rules index a34a3393f261cbf019e4ddd06d8e38db884f45c2..c2d19922d406ea891324d8f066d40b4fee1c193a --- a/assets/debian/rules +++ b/assets/debian-template/rules @@ -23,6 +23,16 @@ # ############################################################################# +############################################################################# +# +# !!!!!!!!!! DEPLOYER NOTE !!!!!!!!!! +# +# Variables to be templated are curly-braced ${PACKAGE_INSTALL_PATH} +# Variables used by the rules script are parenthese'd $(DATADIR) +# See [repo-root]/debian_template.sh +# +############################################################################# + # Uncomment this to turn on verbose mode. #export DH_VERBOSE=1 @@ -37,30 +47,32 @@ RM := rm -rf DIR := $(shell pwd) PACKAGE := $(shell cat $(DIR)/debian/control | grep 'Package:' | sed -e 's/Package: //g') -DATAFILES := srb2.srb zones.dta player.dta rings.dta music.dta patch.dta README.txt LICENSE.txt LICENSE-3RD-PARTY.txt +ARCHIVEPATH := ${ASSET_ARCHIVE_PATH} +ARCHIVEOPTIONALPATH := ${ASSET_ARCHIVE_OPTIONAL_PATH} +GETOPTIONALFILES := ${ASSET_FILES_OPTIONAL_GET} -DATADIR := usr/games/SRB2 +DATADIR := $(shell echo "${PACKAGE_INSTALL_PATH}" | sed -e 's/^\///') RESOURCEDIR := . +STAGINGDIR := $(RESOURCEDIR)/installer WGET := wget -P $(RESOURCEDIR) -c -nc build: $(MKDIR) $(DIR)/debian/tmp/$(DATADIR) > $(DIR)/debian/source/include-binaries - # This will need to be updated every time SRB2 official version is # Copy data files to their install locations, and add data files to include-binaries - for file in $(DATAFILES); do \ - if [ ! -f $(RESOURCEDIR)/$$file ]; then \ - $(WGET) http://alam.srb2.org/SRB2/2.1.21-Final/Resources/$$file; \ - fi; \ - if [ -f $(RESOURCEDIR)/$$file ]; then \ - $(INSTALL) $(RESOURCEDIR)/$$file $(DIR)/debian/tmp/$(DATADIR)/$$file; \ - echo $(RESOURCEDIR)/$$file >> $(DIR)/debian/source/include-binaries; \ + if [ ! -d $(STAGINGDIR) ]; then \ + mkdir -p "$(STAGINGDIR)"; \ + $(WGET) $(ARCHIVEPATH); \ + 7z x "$(RESOURCEDIR)/$(shell basename $(ARCHIVEPATH))" -aos; \ + if [ "$(GETOPTIONALFILES)" = "1" ]; then \ + $(WGET) $(ARCHIVEOPTIONALPATH); \ + 7z x "$(RESOURCEDIR)/$(shell basename $(ARCHIVEOPTIONALPATH))" -aos; \ fi; \ - if [ ! -f $(DIR)/debian/tmp/$(DATADIR)/$$file ]; then \ - echo $(DIR)/debian/tmp/$(DATADIR)/$$file not found and could not be downloaded!; \ - return 1; \ - fi; \ - done + fi + # Install asset directory and add asset file to include-binaries + cp -vr "$(STAGINGDIR)/." "$(DIR)/debian/tmp/$(DATADIR)" + find "$(STAGINGDIR)" >> $(DIR)/debian/source/include-binaries + binary-indep: # Generate install folder file diff --git a/assets/debian/source/format b/assets/debian-template/source/format similarity index 100% rename from assets/debian/source/format rename to assets/debian-template/source/format diff --git a/assets/debian/source/options b/assets/debian-template/source/options similarity index 100% rename from assets/debian/source/options rename to assets/debian-template/source/options diff --git a/assets/debian/changelog b/assets/debian/changelog deleted file mode 100644 index f3a92e1cdff72845820bcc8d2ef2cc2a119cb0d5..0000000000000000000000000000000000000000 --- a/assets/debian/changelog +++ /dev/null @@ -1,19 +0,0 @@ -srb2-data (2.1.21~7) trusty; urgency=high - - * Updated for SRB2 v2.1.21 - - -- Marco Zafra <marco.a.zafra@gmail.com> Mon, 26 Nov 2018 14:31:00 -0500 - - -srb2-data (2.1.14~1) unstable; urgency=low - - * Updated for SRB2 v2.1.14 - - -- Alam Arias <alam+debian@srb2.org> Sat, 6 Jan 2016 11:00:00 -0500 - - -srb2-data (2.0.6-2) maverick; urgency=high - - * Initial proper release.. - - -- Callum Dickinson <gcfreak_ag20@hotmail.com> Sat, 29 Jan 2011 01:18:42 +1300 diff --git a/debian/README.Debian b/debian-template/README.Debian similarity index 62% rename from debian/README.Debian rename to debian-template/README.Debian index 4b724816e2beee374009a34282c0061b85b2db0d..3aa52787ea82d786d8e3fcfbc4166fbf62ce982f 100644 --- a/debian/README.Debian +++ b/debian-template/README.Debian @@ -10,10 +10,38 @@ and give them to your users to install with apt-key add. Thanks! -- Callum Dickinson <gcfreak_ag20@hotmail.com> Fri, 26 Nov 2010 18:25:31 +1300 +--------------- + + +Templating + +Note that you MUST run [repo-root]/debian_template.sh before running debuild +on these scripts! debian_template.sh fills these template files with working values. + +You should also set PACKAGE_NAME_EMAIL="John Doe <jdoe@example.com>" to match +the identity of the key you will use to sign the package. + + +Building for Launchpad PPA + +Use these steps to prepare building a source package for Launchpad: + + 1. cd [repo-root] + 2. git reset --hard; git clean -fd; git clean -fx; + * Resets your repo folder to a committed state and removes untracked files + * If you built srb2-data in the assets/ folder, MAKE SURE THAT FOLDER DOES NOT HAVE ASSETS, + OR THEY MAY BE INCLUDED IN THE MAIN SOURCE PACKAGE! + +Build the source package: + + 1. source [repo-root]/debian_template.sh + * Initializes defaults for the package variables and fills in templates. + 2. debuild -S (builds the source package for Launchpad) + Signing for Launchpad PPA -First, follow the above instructions to generate a GnuPG key with your identity. You will need +First, follow Callum's instructions to generate a GnuPG key with your identity. You will need to publish the fingerprint of that key to Ubuntu's key server. https://help.ubuntu.com/community/GnuPrivacyGuardHowto#Uploading_the_key_to_Ubuntu_keyserver @@ -25,22 +53,18 @@ upload signed source packages and publish them onto your PPA. IF YOU UPLOAD A PACKAGE and Launchpad does NOT send you a confirmation or rejection email, that means your key is not set up correctly with your Launchpad account. +Finally, if your packages have not already been signed, follow these steps: -Building for Launchpad PPA + 1. cd .. + * Packages are located in the parent folder of where debuild was called + 2. debsign "srb2_[version]_source.changes" + * You may need to specify -k [key-fingerprint] -Use these steps to prepare building a source package for Launchpad: - 1. cd [srb2repo] - 2. git reset --hard; git clean -fd; git clean -fx; - * Resets your repo folder to a committed state and removes untracked files - * If you built srb2-data in the assets/ folder, MAKE SURE THAT FOLDER DOES NOT HAVE ASSETS, - OR THEY MAY BE INCLUDED IN THE MAIN SOURCE PACKAGE! +Uploading for Launchpad PPA -Building the source package takes just one step: - - 1. debuild -S (builds the source package for Launchpad) - -Then follow the instructions at <https://help.launchpad.net/Packaging/PPA/Uploading> to upload +Follow the instructions at <https://help.launchpad.net/Packaging/PPA/Uploading> to upload to your PPA and have Launchpad build your binary deb packages. + -- Marco Zafra <marco.a.zafra@gmail.com> Mon, 26 Nov 2018 21:13:00 -0500 diff --git a/debian/README.source b/debian-template/README.source similarity index 100% rename from debian/README.source rename to debian-template/README.source diff --git a/debian-template/changelog b/debian-template/changelog new file mode 100644 index 0000000000000000000000000000000000000000..fb08908cdfa720a114f2d8d01cfe6ca2993bdf87 --- /dev/null +++ b/debian-template/changelog @@ -0,0 +1,5 @@ +${PACKAGE_NAME} (${PACKAGE_VERSION}${PACKAGE_SUBVERSION}${PACKAGE_REVISION}) ${PACKAGE_DISTRO}; urgency=${PACKAGE_URGENCY} + + * ${PROGRAM_NAME} v${PROGRAM_VERSION} program build + + -- ${PACKAGE_NAME_EMAIL} ${__PACKAGE_DATETIME} diff --git a/debian/compat b/debian-template/compat similarity index 100% rename from debian/compat rename to debian-template/compat diff --git a/debian/control b/debian-template/control similarity index 65% rename from debian/control rename to debian-template/control index 0f2d8062bac4d1acc93d50c3f078fb16c43f987a..e1348d704e3187dfc0e70a7165d467a2c6354492 100644 --- a/debian/control +++ b/debian-template/control @@ -1,24 +1,30 @@ # SRB2 Debian package control file. -Source: srb2 +Source: ${PACKAGE_NAME} Section: games Priority: extra -Maintainer: Sonic Team Junior <stjr@srb2.org> +Maintainer: ${PACKAGE_GROUP_NAME_EMAIL} Build-Depends: debhelper (>= 7.0.50~), libsdl2-dev, libsdl2-mixer-dev, - libpng12-dev (>= 1.2.7) | libpng-dev, + libpng-dev | libpng16-dev | libpng12-dev (>= 1.2.7), zlib1g-dev, libgme-dev, libglu1-dev | libglu-dev, libosmesa6-dev | libgl-dev, nasm [i386] Standards-Version: 3.8.4 -Homepage: http://www.srb2.org +Homepage: ${PACKAGE_WEBSITE} -Package: srb2 +Package: ${PACKAGE_NAME} Architecture: any -Depends: ${shlibs:Depends}, ${misc:Depends}, srb2-data (>= 2.1.15), srb2-data (<= 2.1.23) +Depends: ${SHLIBS_DEPENDS}, ${MISC_DEPENDS}, + ${PACKAGE_NAME}-data (>> ${PACKAGE_ASSET_MINVERSION}), ${PACKAGE_NAME}-data (<< ${PACKAGE_ASSET_MAXVERSION}), + libsdl2-2.0-0, + libsdl2-mixer-2.0-0, + zlib1g, + libgme0, + libpng | libpng16-16 | libpng12-0 Description: A cross-platform 3D Sonic fangame Sonic Robo Blast 2 is a 3D open-source Sonic the Hedgehog fangame built using a modified version of the Doom Legacy @@ -28,10 +34,10 @@ Description: A cross-platform 3D Sonic fangame and quite a lot of the fun that the original Sonic games provided. -Package: srb2-dbg +Package: ${PACKAGE_NAME}-dbg Architecture: any -# FIXME: should be Depends: ${shlibs:Depends}, ${misc:Depends}, srb2-data (= 2.1.14), srb2 but dh_shlibdeps is being an asshat -Depends: libc6, ${misc:Depends}, srb2-data (>= 2.1.15), srb2-data (<= 2.1.23), srb2 +# FIXME: should be Depends: ${SHLIBS_DEPENDS}, ${MISC_DEPENDS}, srb2-data (= 2.1.14), srb2 but dh_shlibdeps is being an asshat +Depends: libc6, ${MISC_DEPENDS}, ${PACKAGE_NAME}-data (>> ${PACKAGE_ASSET_MINVERSION}), ${PACKAGE_NAME}-data (<< ${PACKAGE_ASSET_MAXVERSION}), ${PACKAGE_NAME} Description: A cross-platform 3D Sonic fangame Sonic Robo Blast 2 is a 3D open-source Sonic the Hedgehog fangame built using a modified version of the Doom Legacy diff --git a/assets/debian/copyright b/debian-template/copyright similarity index 57% rename from assets/debian/copyright rename to debian-template/copyright index 97d606b0fb67b73eaae1858f43652006edfd91b6..cc47c453bf2b0ccc6db34c57a03dfe1ce2fc75a7 100644 --- a/assets/debian/copyright +++ b/debian-template/copyright @@ -1,18 +1,18 @@ This work was packaged for Debian by: - Marco Zafra <marco.a.zafra@gmail.com> Mon, 26 Nov 2018 14:31:00 -0500 + ${PACKAGE_NAME_EMAIL} ${__PACKAGE_DATETIME} It was downloaded from: - <http://srb2.org> + ${PACKAGE_WEBSITE} Upstream Author(s): - Sonic Team Junior <stjr@srb2.org> + ${PACKAGE_GROUP_NAME_EMAIL} Copyright: - Copyright (C) 1998-2018 Sonic Team Junior + Copyright (C) 1998-2018 by Sonic Team Junior License: @@ -21,7 +21,7 @@ License: The Debian packaging is: Copyright (C) 2010 Callum Dickinson <gcfreak_ag20@hotmail.com> - Copyright (C) 2010-2018 Sonic Team Junior <stjr@srb2.org> + Copyright (C) 2010-2018 by Sonic Team Junior <stjr@srb2.org> and is licensed under the GPL version 2, see "/usr/share/common-licenses/GPL-2". diff --git a/debian/docs b/debian-template/docs similarity index 100% rename from debian/docs rename to debian-template/docs diff --git a/debian/rules b/debian-template/rules old mode 100755 new mode 100644 similarity index 87% rename from debian/rules rename to debian-template/rules index ff80d50bf2f2f881937f42d607d370b31b85e668..0a77624cb490639564b0212abc902dbfdda88be5 --- a/debian/rules +++ b/debian-template/rules @@ -23,6 +23,16 @@ # ############################################################################# +############################################################################# +# +# !!!!!!!!!! DEPLOYER NOTE !!!!!!!!!! +# +# Variables to be templated are curly-braced ${PACKAGE_INSTALL_PATH} +# Variables used by the rules script are parenthese'd $(PKGDIR) +# See [repo-root]/debian_template.sh +# +############################################################################# + # Uncomment this to turn on verbose mode. #export DH_VERBOSE=1 @@ -50,16 +60,16 @@ DIR := $(shell pwd) # FIXME: hate hate hate head/tail hack :( CONTROLF = $(DIR)/debian/control -PACKAGE = srb2 -DBGPKG = $(PACKAGE)-dbg -TITLE = Sonic Robo Blast 2 +PACKAGE = ${PACKAGE_NAME} +DBGPKG = ${PACKAGE}-dbg +TITLE = ${PROGRAM_NAME} SECTION = Games/Action -EXENAME = srb2 +EXENAME = ${PROGRAM_FILENAME} DBGNAME = debug/$(EXENAME) -PKGDIR = usr/games/SRB2 +PKGDIR = $(shell echo "${PACKAGE_INSTALL_PATH}" | sed -e 's/^\///') DBGDIR = usr/lib/debug/$(PKGDIR) -LINKDIR = usr/games +LINKDIR = $(shell echo "${PACKAGE_LINK_PATH}" | sed -e 's/^\///') PIXMAPS_DIR = usr/share/pixmaps DESKTOP_DIR = usr/share/applications PREFIX = $(shell test "$(CROSS_COMPILE_BUILD)" != "$(CROSS_COMPILE_HOST)" && echo "PREFIX=$(CROSS_COMPILE_HOST)") @@ -102,8 +112,8 @@ binary-arch: $(INSTALL) $(BINDIR)/$(EXENAME) $(DIR)/debian/tmp/$(PKGDIR)/$(PACKAGE) $(INSTALL) $(BINDIR)/$(DBGNAME) $(DIR)/debian/tmp/$(DBGDIR)/$(PACKAGE) # Install desktop file and banner image - $(INSTALL) $(DIR)/srb2.png $(DIR)/debian/tmp/usr/share/pixmaps - $(INSTALL) $(DIR)/debian/srb2.desktop $(DIR)/debian/tmp/usr/share/applications + $(INSTALL) $(DIR)/srb2.png $(DIR)/debian/tmp/usr/share/pixmaps/${PROGRAM_FILENAME}.png + $(INSTALL) $(DIR)/debian/srb2.desktop $(DIR)/debian/tmp/usr/share/applications/${PROGRAM_FILENAME}.desktop # add compiled binaries to include-binaries echo $(BINDIR)/$(EXENAME) >> $(DIR)/debian/source/include-binaries echo $(BINDIR)/$(EXENAME) >> $(DIR)/debian/source/include-binaries diff --git a/debian/source/format b/debian-template/source/format similarity index 100% rename from debian/source/format rename to debian-template/source/format diff --git a/debian/source/options b/debian-template/source/options similarity index 81% rename from debian/source/options rename to debian-template/source/options index 841c65a6f05e48766e4f9c6519222c25f9ecf7be..1ef771ddf4a618e4594d324addc38a0f3e401412 100644 --- a/debian/source/options +++ b/debian-template/source/options @@ -2,7 +2,7 @@ tar-ignore = "assets/*.srb" tar-ignore = "assets/*.pk3" tar-ignore = "assets/*.dta" tar-ignore = "assets/*.wad" -tar-ignore = "assets/debian/srb2-data/*" +tar-ignore = "assets/debian/${PACKAGE_NAME}-data/*" tar-ignore = "assets/debian/tmp/*" tar-ignore = "*.obj" tar-ignore = "*.dep" diff --git a/debian-template/srb2.desktop b/debian-template/srb2.desktop new file mode 100644 index 0000000000000000000000000000000000000000..07c7906e05c5b0b1690c5be817140ad5b628e341 --- /dev/null +++ b/debian-template/srb2.desktop @@ -0,0 +1,10 @@ +[Desktop Entry] +Name=${PROGRAM_NAME} +Comment=${PROGRAM_DESCRIPTION} +Encoding=UTF-8 +Exec=${PACKAGE_INSTALL_PATH}/${PROGRAM_FILENAME} +Icon=/usr/share/pixmaps/${PROGRAM_FILENAME}.png +Terminal=false +Type=Application +StartupNotify=false +Categories=Application;Game; diff --git a/debian/changelog b/debian/changelog deleted file mode 100644 index b06a78e2ba6fa055a57a2c397995b69e47b2a6d9..0000000000000000000000000000000000000000 --- a/debian/changelog +++ /dev/null @@ -1,12 +0,0 @@ -srb2 (2.1.23~9) trusty; urgency=high - - * SRB2 v2.1.23 release - - -- Marco Zafra <marco.a.zafra@gmail.com> Mon, 27 Nov 2018 16:45:00 -0500 - - -srb2 (2.0.6-5) maverick; urgency=high - - * Initial proper release.. - - -- Callum Dickinson <gcfreak_ag20@hotmail.com> Sat, 29 Jan 2011 01:18:42 +1300 diff --git a/debian/srb2.desktop b/debian/srb2.desktop deleted file mode 100644 index 3a1cac9f68e5dfb84a97ee4f3151af31ea64036a..0000000000000000000000000000000000000000 --- a/debian/srb2.desktop +++ /dev/null @@ -1,10 +0,0 @@ -[Desktop Entry] -Name=Sonic Robo Blast 2 -Comment=A free 3D Sonic the Hedgehog fangame closely inspired by the original Sonic games on the Sega Genesis. -Encoding=UTF-8 -Exec=/usr/games/SRB2/srb2 -Icon=/usr/share/pixmaps/srb2.png -Terminal=false -Type=Application -StartupNotify=false -Categories=Application;Game; diff --git a/debian_template.sh b/debian_template.sh new file mode 100644 index 0000000000000000000000000000000000000000..c1af3c19f0a3a66e46389b6a0ec67d9b43c11cfb --- /dev/null +++ b/debian_template.sh @@ -0,0 +1,166 @@ +#!/bin/bash + +# Deployer for Travis-CI +# Debian package templating +# +# Call this script BEFORE running debuild! +# source ./debian_template.sh [clean] [main/asset] +# +# Before running this script, +# you should also set PACKAGE_NAME_EMAIL="John Doe <jdoe@example.com>" to match +# the identity of the key you will use to sign the package. +# + +# Get script's actual path +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" + +# Recursive function for directory crawling +# $1 = Directory root to crawl +# $2 = Code to eval on file +# $3 = Code to eval on directory +# Exposes $dirtails, $dirlevel, and $dirtailname +dirlevel=0 # initialize +dirtails=() + +# Utility function to make dira/dirb/dirc string +makedirtailname () { + dirtailname="" + for tail in $dirtails; do + if [[ "$dirtailname" == "" ]]; then + dirtailname="/$tail"; + else + dirtailname="$dirtailname/$tail"; + fi; + done; +} + +evaldirectory () { + if [ -d "$1" ]; then + # Set contextual variables + # dirtails is an array of directory basenames after the crawl root + if (( $dirlevel > 0 )); then + dirtails+=( "$(basename $1)" ); + else + dirtails=(); + fi; + dirlevel=$((dirlevel+1)); + + # Generate directory path after the crawl root + makedirtailname; + + # Eval our directory with the latest contextual info + # Don't eval on root + if (( $dirlevel > 1 )) && [[ "$3" != "" ]]; then + eval "$3"; + fi; + + # Iterate entries + for name in $1/*; do + if [ -d "$name" ]; then + # Name is a directory, but don't eval yet + # Recurse so our vars are updated + evaldirectory "$name" "$2" "$3"; + + # Decrement our directory level and remove a dirtail + unset 'dirtails[ ${#dirtails[@]}-1 ]'; + dirlevel=$((dirlevel-1)); + makedirtailname; + else + # Name is a file + if [ -f "$name" ] && [[ "$2" != "" ]]; then + eval "$2"; + fi; + fi; + done; + + # Reset our variables; we're done iterating + if (( $dirlevel == 1 )); then + dirlevel=0; + fi; + fi; +} + +# +# Initialize package parameter defaults +# +if [[ "$__DEBIAN_PARAMETERS_INITIALIZED" != "1" ]]; then + . ${DIR}/deployer/travis/deployer_defaults.sh; +fi; + +# Clean up after ourselves; we only expect to run this script once +# during buildboting +__DEBIAN_PARAMETERS_INITIALIZED=0 + +# for envsubst +export __PACKAGE_DATETIME="$(date '+%a, %d %b %Y %H:%M:%S %z')" +export __PACKAGE_DATETIME_DIGIT="$(date -u '+%Y%m%d%H%M%S')" + +if [[ "$PACKAGE_REVISION" == "" ]]; then + PACKAGE_REVISION="-$__PACKAGE_DATETIME_DIGIT"; + __PACKAGE_REVISION_BY_DATE=1; + export PACKAGE_REVISION=${PACKAGE_REVISION}; # for envsubst +fi; + +# +# Clean the old debian/ directories +# +if [[ "$1" == "clean" ]]; then + toclean=$2; +else + toclean=$1; +fi; + +if [[ "$toclean" == "" ]] || [[ "$toclean" == "main" ]]; then + echo "Cleaning main package scripts"; + if [[ ! -f ${DIR}/debian ]]; then + rm -rf ${DIR}/debian; + fi; +fi; +if [[ "$toclean" == "" ]] || [[ "$toclean" == "asset" ]]; then + echo "Cleaning asset package scripts"; + if [[ ! -f ${DIR}/assets/debian ]]; then + rm -rf ${DIR}/assets/debian; + fi; +fi; + +# +# Make new templates +# +if [[ "$1" != "clean" ]]; then + totemplate=$1; + + # HACK: ${shlibs:Depends} in the templates make the templating fail + # So just define replacemment variables + export SHLIBS_DEPENDS=${SHLIBS_DEPENDS}; + export MISC_DEPENDS=${MISC_DEPENDS}; + export DEBFILEVAR='$$file'; # used in assets/debian/rules + + # Package parameters are exported for envsubst in deployer_defaults.sh + + if [[ "$totemplate" == "" ]] || [[ "$totemplate" == "main" ]]; then + echo "Generating main package scripts"; + fromroot=${DIR}/debian-template; + toroot=${DIR}/debian; + mkdir ${toroot}; + + evaldirectory ${fromroot} \ + "cat \$name | envsubst > ${toroot}\${dirtailname}/\$( basename \$name )" \ + "mkdir \"${toroot}\${dirtailname}\""; + fi; + + if [[ "$totemplate" == "" ]] || [[ "$totemplate" == "asset" ]]; then + echo "Generating asset package scripts"; + fromroot=${DIR}/assets/debian-template; + toroot=${DIR}/assets/debian; + mkdir ${toroot}; + + # Root dir to crawl; file eval; directory eval + evaldirectory ${fromroot} \ + "cat \$name | envsubst > ${toroot}\${dirtailname}/\$( basename \$name )" \ + "mkdir \"${toroot}\${dirtailname}\""; + fi; +fi; + +if [[ "$__DPL_ACTIVE" != "1" ]] && [[ "$__PACKAGE_REVISION_BY_DATE" == "1" ]]; then + unset PACKAGE_REVISION; # so we can reset the date on subsequent runs +fi; diff --git a/deployer/travis/deployer.sh b/deployer/travis/deployer.sh new file mode 100644 index 0000000000000000000000000000000000000000..c88155d217956def89f50fe5673b56a9b5fb35c6 --- /dev/null +++ b/deployer/travis/deployer.sh @@ -0,0 +1,157 @@ +#!/bin/bash + +# Deployer for Travis-CI +# Initialization +# +# Performs validity checks to ensure that Deployer is allowed to run +# e.g., is an FTP hostname specified? Are we whitelisted by OSNAMES and BRANCHES? +# +# Set these environment variables in your Travis-CI settings, where they are stored securely. +# See other shell scripts for more options. +# +# DPL_ENABLED = 1 (leave blank to disable) +# DPL_TAG_ENABLED = 1 (run Deployer on all tags) +# DPL_JOB_ENABLE_ALL = 1 (run Deployer on all jobs; leave blank to act on specific jobs, see below) +# DPL_JOBNAMES = name1,name2 (whitelist of job names to allow uploading; leave blank to upload from all jobs) +# DPL_OSNAMES = osx (whitelist of OS names to allow uploading; leave blank to upload from all OSes) +# DPL_BRANCHES = master,branch1,branch2 (whitelist of branches to upload; leave blank to upload all branches) +# +# To enable Deployer on specific jobs, set _DPL_JOB_ENABLED=1 for that job. Example: +# - matrix: +# - os: osx +# env: +# - _DPL_JOB_ENABLED=1 +# +# DO NOT set __DPL_ACTIVE, because that would bypass these validity checks. + +# Validate Deployer state +if [[ "$DPL_ENABLED" == "1" ]] && [[ "$TRAVIS_PULL_REQUEST" == "false" ]]; then + # Test for base eligibility: + # Are we in a deployer branch? Or + # Are we in a release tag AND DPL_TAG_ENABLED=1? + if [[ $TRAVIS_BRANCH == *"deployer"* ]]; then + __DPL_BASE_ELIGIBLE=1; + __DPL_TERMINATE_EARLY_ELIGIBLE=1; + fi; + + if [[ "$TRAVIS_TAG" != "" ]] && [[ "$DPL_TAG_ENABLED" == "1" ]]; then + __DPL_BASE_ELIGIBLE=1; + __DPL_TAG_ELIGIBLE=1; + __DPL_TERMINATE_EARLY_ELIGIBLE=1; + fi; + + # Logging message for trigger word + if [[ "$__DPL_TAG_ELIGIBLE" != "1" ]] && [[ "$DPL_TRIGGER" != "" ]]; then + echo "Testing for trigger $DPL_TRIGGER, commit message: $TRAVIS_COMMIT_MESSAGE"; + echo "[${DPL_TRIGGER}]"; + echo "[${DPL_TRIGGER}-${_DPL_JOB_NAME}]"; + echo "[${DPL_TRIGGER}-${TRAVIS_OS_NAME}]"; + fi; + + # + # Search for the trigger word + # Force enable if release tags are eligible + # + if [[ "$__DPL_TAG_ELIGIBLE" == "1" ]] || [[ "$DPL_TRIGGER" == "" ]] \ + || [[ $TRAVIS_COMMIT_MESSAGE == *"[$DPL_TRIGGER]"* ]] \ + || [[ $TRAVIS_COMMIT_MESSAGE == *"[${DPL_TRIGGER}-${_DPL_JOB_NAME}]"* ]] \ + || [[ $TRAVIS_COMMIT_MESSAGE == *"[${DPL_TRIGGER}-${TRAVIS_OS_NAME}]"* ]]; then + # + # Whitelist by branch name + # Force enable if release tags are eligible + # + if [[ "$__DPL_TAG_ELIGIBLE" == "1" ]] || [[ "$DPL_BRANCHES" == "" ]] || [[ $DPL_BRANCHES == *"$TRAVIS_BRANCH"* ]]; then + # Set this so we only early-terminate builds when we are specifically deploying + # Trigger string and branch are encompassing conditions; the rest are job-specific + # This check only matters for deployer branches and when DPL_TERMINATE_TESTS=1, + # because we're filtering non-deployer jobs. + # + # __DPL_TRY_TERMINATE_EARLY is invalidated in .travis.yml if __DPL_ACTIVE=1 + if [[ "$__DPL_TERMINATE_EARLY_ELIGIBLE" == "1" ]] && [[ "$DPL_TERMINATE_TESTS" == "1" ]]; then + __DPL_TRY_TERMINATE_EARLY=1; + fi; + + # + # Is the job enabled for deployment? + # + if [[ "$DPL_JOB_ENABLE_ALL" == "1" ]] || [[ "$_DPL_JOB_ENABLED" == "1" ]]; then + # + # Whitelist by job names + # + if [[ "$DPL_JOBNAMES" == "" ]] || [[ "$_DPL_JOB_NAME" == "" ]] || [[ $DPL_JOBNAMES == *"$_DPL_JOB_NAME"* ]]; then + # + # Whitelist by OS names + # + if [[ "$DPL_OSNAMES" == "" ]] || [[ $DPL_OSNAMES == *"$TRAVIS_OS_NAME"* ]]; then + # Base Deployer is eligible for becoming active + + # Are we building for Linux? + if [[ "$_DPL_PACKAGE_BINARY" == "1" ]] || [[ "$_DPL_PACKAGE_SOURCE" == "1" ]]; then + if [[ "$_DPL_PACKAGE_MAIN" == "1" ]] || [[ "$_DPL_PACKAGE_ASSET" == "1" ]]; then + if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then + __DPL_DEBIAN_ACTIVE=1; + fi; + fi; + fi; + + # Now check for deployment targets + if [[ "$_DPL_FTP_TARGET" == "1" ]] && [[ "$DPL_FTP_HOSTNAME" != "" ]]; then + if [[ "$TRAVIS_OS_HOST" == "linux" ]] && [[ "$DPL_FTP_PROTOCOL" == "ftp" ]]; then + echo "Non-secure FTP will not work on Linux Travis-CI jobs!"; + echo "Try SFTP or another target. Details:"; + echo "https://blog.travis-ci.com/2018-07-23-the-tale-of-ftp-at-travis-ci"; + else + if [[ "$__DPL_DEBIAN_ACTIVE" == "1" ]] || [[ "$_DPL_PACKAGE_BINARY" == "1" ]] || [[ "$_DPL_BINARY" == "1" ]]; then + echo "Deployer FTP target is enabled"; + __DPL_FTP_ACTIVE=1; + else + echo "Deployer FTP target cannot be enabled: You must specify _DPL_PACKAGE_BINARY=1,"; + echo "and/or _DPL_BINARY=1 in your job's environment variables."; + fi; + fi; + fi; + + if [[ "$_DPL_DPUT_TARGET" == "1" ]] && [[ "$__DPL_DEBIAN_ACTIVE" == "1" ]] \ + && [[ "$DPL_DPUT_INCOMING" != "" ]]; then + if [[ "$DPL_DPUT_METHOD" == "ftp" ]]; then + echo "DPUT will not work with non-secure FTP on Linux Travis-CI jobs!"; + echo "Try SFTP or another method for DPUT. Details:"; + echo "https://blog.travis-ci.com/2018-07-23-the-tale-of-ftp-at-travis-ci"; + else + echo "Deployer DPUT target is enabled"; + __DPL_DPUT_ACTIVE=1; + fi; + fi; + + # If any deployment targets are active, then so is the Deployer at large + if [[ "$__DPL_FTP_ACTIVE" == "1" ]] || [[ "$__DPL_DPUT_ACTIVE" == "1" ]]; then + __DPL_ACTIVE=1; + fi; + fi; + fi; + fi; + fi; + else + if [[ "$DPL_TRIGGER" != "" ]]; then + echo "Testing for global trigger [$DPL_TRIGGER, commit message: $TRAVIS_COMMIT_MESSAGE"; + fi; + if [[ "$DPL_TRIGGER" != "" ]] && [[ $TRAVIS_COMMIT_MESSAGE == *"[$DPL_TRIGGER"* ]]; then + if [[ "$__DPL_TAG_ELIGIBLE" == "1" ]] || [[ "$DPL_BRANCHES" == "" ]] || [[ $DPL_BRANCHES == *"$TRAVIS_BRANCH"* ]]; then + # This check only matters for deployer branches and when DPL_TERMINATE_TESTS=1, + # because we're filtering non-deployer jobs. + if [[ "$__DPL_TERMINATE_EARLY_ELIGIBLE" == "1" ]] && [[ "$DPL_TERMINATE_TESTS" == "1" ]]; then + # Assume that some job received the trigger, so mark this for early termination + __DPL_TRY_TERMINATE_EARLY=1; + fi; + fi; + fi; + fi; +fi; + +if [[ "$__DPL_TRY_TERMINATE_EARLY" == "1" ]] && [[ "$__DPL_ACTIVE" != "1" ]]; then + echo "Deployer is active in another job"; +fi; + +if [[ "$__DPL_TRY_TERMINATE_EARLY" != "1" ]] && [[ "$__DPL_ACTIVE" != "1" ]]; then + echo "Deployer is not active"; +fi; diff --git a/deployer/travis/deployer_build.sh b/deployer/travis/deployer_build.sh new file mode 100644 index 0000000000000000000000000000000000000000..3817f025de4151d573222d7f980f9e1e0d758702 --- /dev/null +++ b/deployer/travis/deployer_build.sh @@ -0,0 +1,190 @@ +#!/bin/bash + +# Deployer for Travis-CI +# Build Script +# +# Builds the required targets depending on which sub-modules are enabled + +if [[ "$__DPL_FTP_ACTIVE" == "1" ]] || [[ "$__DPL_DPUT_ACTIVE" == "1" ]]; then + if [[ "$__DPL_DEBIAN_ACTIVE" == "1" ]]; then + echo "Building Debian package(s)" + + sudo apt-get install devscripts debhelper fakeroot secure-delete expect; + + # Build source packages first, since they zip up the entire source folder, + # binaries and all + if [[ "$_DPL_PACKAGE_MAIN" == "1" ]]; then + . ../debian_template.sh main; + OLDPWD=$PWD; # [repo]/build + cd ..; # repo root + + if [[ "$_DPL_PACKAGE_SOURCE" == "1" ]]; then + echo "Building main source Debian package"; + expect <(cat <<EOD +spawn debuild -S -us -uc; +expect "continue anyway? (y/n)" +send "y\r" +interact +EOD +); + fi; + + if [[ "$_DPL_PACKAGE_BINARY" == "1" ]]; then + echo "Building main binary Debian package"; + expect <(cat <<EOD +spawn debuild -us -uc; +expect "continue anyway? (y/n)" +send "y\r" +interact +EOD +); + fi; + + cd $OLDPWD; + fi; + + # Also an asset package + if [[ "$_DPL_PACKAGE_ASSET" == "1" ]]; then + . ../debian_template.sh asset; + OLDPWD=$PWD; # [repo]/build + cd ../assets; + + # make sure the asset files exist, download them if they don't + #echo "Checking asset files for asset Debian package"; + #debuild -T build; + + if [[ "$_DPL_PACKAGE_SOURCE" == "1" ]]; then + echo "Building asset source Debian package"; + expect <(cat <<EOD +spawn debuild -S -us -uc; +expect "continue anyway? (y/n)" +send "y\r" +interact +EOD +); + fi; + + if [[ "$_DPL_PACKAGE_BINARY" == "1" ]]; then + echo "Building asset binary Debian package"; + expect <(cat <<EOD +spawn debuild -us -uc; +expect "continue anyway? (y/n)" +send "y\r" +interact +EOD +); + fi; + + cd $OLDPWD; + fi; + + # Now sign our packages + if [[ "$DPL_PGP_KEY_PRIVATE" != "" ]] && [[ "$DPL_PGP_KEY_PASSPHRASE" != "" ]]; then + # Get the key to sign + # Do this AFTER debuild so that we can specify the passphrase in command line + echo "$DPL_PGP_KEY_PRIVATE" | base64 --decode > key.asc; + echo "$DPL_PGP_KEY_PASSPHRASE" > phrase.txt; + gpg --import key.asc; + + if [[ "$_DPL_PACKAGE_MAIN" == "1" ]]; then + echo "Signing main package(s)"; + + PACKAGEFILENAME=${PACKAGE_NAME}_${PACKAGE_VERSION}${PACKAGE_SUBVERSION}${PACKAGE_REVISION}; + PACKAGEDBGFILENAME=${PACKAGE_NAME}-dbg_${PACKAGE_VERSION}${PACKAGE_SUBVERSION}${PACKAGE_REVISION}; + #PACKAGENIGHTLYFILENAME=${PACKAGE_NAME}-nightly_${PACKAGE_VERSION}${PACKAGE_SUBVERSION}${PACKAGE_REVISION}; + #PACKAGENIGHTLYDBGFILENAME=${PACKAGE_NAME}-nightly-dbg_${PACKAGE_VERSION}${PACKAGE_SUBVERSION}${PACKAGE_REVISION}; + #PACKAGEPATCHFILENAME=${PACKAGE_NAME}-patch_${PACKAGE_VERSION}${PACKAGE_SUBVERSION}${PACKAGE_REVISION}; + #PACKAGEPATCHDBGFILENAME=${PACKAGE_NAME}-patch-dbg_${PACKAGE_VERSION}${PACKAGE_SUBVERSION}${PACKAGE_REVISION}; + #PACKAGEPATCHNIGHTLYFILENAME=${PACKAGE_NAME}-patch-nightly_${PACKAGE_VERSION}${PACKAGE_SUBVERSION}${PACKAGE_REVISION}; + #PACKAGEPATCHNIGHTLYDBGFILENAME=${PACKAGE_NAME}-patch-nightly-dbg_${PACKAGE_VERSION}${PACKAGE_SUBVERSION}${PACKAGE_REVISION}; + + PACKAGEFILENAMES=( + $PACKAGEFILENAME + $PACKAGEDBGFILENAME + #$PACKAGENIGHTLYFILENAME + #$PACKAGENIGHTLYDBGFILENAME + #$PACKAGEPATCHFILENAME + #$PACKAGEPATCHDBGFILENAME + #$PACKAGEPATCHNIGHTLYFILENAME + #$PACKAGEPATCHNIGHTLYDBGFILENAME + ); + + # Main packages are in parent of root repo folder + OLDPWD=$PWD; # [repo]/build + cd ../..; # parent of repo root + + for n in ${PACKAGEFILENAMES}; do + for f in ./$n*.changes; do + debsign --no-re-sign -p"gpg --passphrase-file $OLDPWD/phrase.txt --batch" "$f"; + done; + done; + + cd $OLDPWD; + fi; + + if [[ "$_DPL_PACKAGE_ASSET" == "1" ]]; then + echo "Signing asset package(s)"; + + PACKAGEFILENAME=${PACKAGE_NAME}-data_${PACKAGE_VERSION}${PACKAGE_SUBVERSION}${PACKAGE_REVISION}; + #PACKAGENIGHTLYFILENAME=${PACKAGE_NAME}-nightly-data_${PACKAGE_VERSION}${PACKAGE_SUBVERSION}${PACKAGE_REVISION}; + #PACKAGEPATCHFILENAME=${PACKAGE_NAME}-patch-data_${PACKAGE_VERSION}${PACKAGE_SUBVERSION}${PACKAGE_REVISION}; + #PACKAGEPATCHNIGHTLYFILENAME=${PACKAGE_NAME}-patch-nightly-data_${PACKAGE_VERSION}${PACKAGE_SUBVERSION}${PACKAGE_REVISION}; + + PACKAGEFILENAMES=( + $PACKAGEFILENAME + #$PACKAGENIGHTLYFILENAME + #$PACKAGEPATCHFILENAME + #$PACKAGEPATCHNIGHTLYFILENAME + ) + + # Asset packages are in root repo folder + OLDPWD=$PWD; # [repo]/build + cd ..; # repo root + + for n in ${PACKAGEFILENAMES}; do + for f in ./$n*.changes; do + debsign --no-re-sign -p"gpg --passphrase-file $OLDPWD/phrase.txt --batch" "$f"; + done; + done; + + cd $OLDPWD; + fi; + + # Delete the keys :eyes: + srm key.asc; + srm phrase.txt; + fi; + fi; + + # all other OSes + if [[ "$TRAVIS_OS_NAME" != "linux" ]]; then + # + # Check for binary building + # + if [[ "$_DPL_BINARY" == "1" ]]; then + echo "Building a Binary"; + make -k; + fi; + + # + # Check for package building + # + if [[ "$_DPL_PACKAGE_BINARY" == "1" ]]; then + echo "Building a Package"; + + # Make an OSX package; superuser is required for library bundling + # + # HACK: OSX packaging can't write libraries to .app package unless we're superuser + # because the original library files don't have WRITE permission + # Bug may be sidestepped by using CHMOD_BUNDLE_ITEMS=TRUE + # But I don't know where this is set. Not `cmake -D...` because this var is ignored. + # https://cmake.org/Bug/view.php?id=9284 + if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then + sudo make -k package; + else + # Some day, when Windows is supported, we'll just make a standard package + make -k package; + fi; + fi; + fi; +fi; diff --git a/deployer/travis/deployer_defaults.sh b/deployer/travis/deployer_defaults.sh new file mode 100644 index 0000000000000000000000000000000000000000..bccb7409ac2750564d3a75433e12ff747ad21ae7 --- /dev/null +++ b/deployer/travis/deployer_defaults.sh @@ -0,0 +1,105 @@ +#!/bin/bash + +# Deployer for Travis-CI +# Default Variables +# +# Here are all of the user-set variables used by Deployer. +# See the "Cross-platform deployment" page on SRB2 Wiki for documentation. + +# Core Parameters +: ${DPL_ENABLED} # Enable Deployer behavior; must be set for any deployment activity +: ${DPL_TAG_ENABLED} # Trigger Deployer for all tag releases +: ${DPL_JOB_ENABLE_ALL} # Enable all jobs for deployment +: ${DPL_TERMINATE_TESTS} # Terminate all build test jobs (used in .travis.yml) +: ${DPL_TRIGGER} # Use a [word] in the commit message to trigger Deployer +: ${DPL_JOBNAMES} # Trigger Deployer by job name +: ${DPL_OSNAMES} # Trigger Deployer by OS name (osx,linux) +: ${DPL_BRANCHES} # Trigger Deployer by git branch name + +# Job Parameters +: ${_DPL_JOB_ENABLED} # Enable Deployer for this specific job. DPL_ENABLED must be set too. +: ${_DPL_JOB_NAME} # Identifier for the job, used for logging and trigger word matching +: ${_DPL_FTP_TARGET} # Deploy to FTP +: ${_DPL_DPUT_TARGET} # Deploy to DPUT +: ${_DPL_PACKAGE_SOURCE} # Build packages into a Source distribution. Linux only. +: ${_DPL_PACKAGE_BINARY} # Build packages into a Binary distribution. +: ${_DPL_PACKAGE_MAIN:=1} # Build main installation package. Linux only; OS X assumes this. +: ${_DPL_PACKAGE_ASSET} # Build asset installation package. Linux only. + +# Asset File Parameters +: ${ASSET_ARCHIVE_PATH:=https://github.com/mazmazz/SRB2/releases/download/SRB2_assets/SRB2-v2122-assets.7z} +: ${ASSET_ARCHIVE_OPTIONAL_PATH:=https://github.com/mazmazz/SRB2/releases/download/SRB2_assets/SRB2-v2122-optional-assets.7z} +: ${ASSET_FILES_HASHED:=srb2.srb zones.dta player.dta rings.dta patch.dta} +: ${ASSET_FILES_DOCS:=README.txt LICENSE.txt LICENSE-3RD-PARTY.txt} +: ${ASSET_FILES_OPTIONAL_GET:=0} + +# FTP Parameters +: ${DPL_FTP_PROTOCOL} +: ${DPL_FTP_USER} +: ${DPL_FTP_PASS} +: ${DPL_FTP_HOSTNAME} +: ${DPL_FTP_PORT} +: ${DPL_FTP_PATH} + +# DPUT Parameters +: ${DPL_DPUT_DOMAIN:=ppa.launchpad.net} +: ${DPL_DPUT_METHOD:=sftp} +: ${DPL_DPUT_INCOMING} +: ${DPL_DPUT_LOGIN:=anonymous} +: ${DPL_SSH_KEY_PRIVATE} # Base64-encoded private key file. Used to sign repository uploads +: ${DPL_SSH_KEY_PASSPHRASE} # Decodes the private key file. + +# Package Parameters +: ${PACKAGE_NAME:=srb2} +: ${PACKAGE_VERSION:=2.1.23} +: ${PACKAGE_SUBVERSION} # Highly recommended to set this to reflect the distro series target (e.g., ~18.04bionic) +: ${PACKAGE_REVISION} # Defaults to UTC timestamp +: ${PACKAGE_INSTALL_PATH:=/usr/games/SRB2} +: ${PACKAGE_LINK_PATH:=/usr/games} +: ${PACKAGE_DISTRO:=trusty} +: ${PACKAGE_URGENCY:=high} +: ${PACKAGE_NAME_EMAIL:=Sonic Team Junior <stjr@srb2.org>} +: ${PACKAGE_GROUP_NAME_EMAIL:=Sonic Team Junior <stjr@srb2.org>} +: ${PACKAGE_WEBSITE:=<http://www.srb2.org>} + +: ${PACKAGE_ASSET_MINVERSION:=2.1.21} # Number this the version BEFORE the actual required version, because we do a > check +: ${PACKAGE_ASSET_MAXVERSION:=2.1.24} # Number this the version AFTER the actual required version, because we do a < check + +: ${PROGRAM_NAME:=Sonic Robo Blast 2} +: ${PROGRAM_VENDOR:=Sonic Team Junior} +: ${PROGRAM_VERSION:=2.1.23} +: ${PROGRAM_DESCRIPTION:=A free 3D Sonic the Hedgehog fangame closely inspired by the original Sonic games on the Sega Genesis.} +: ${PROGRAM_FILENAME:=srb2} + +: ${DPL_PGP_KEY_PRIVATE} # Base64-encoded private key file. Used to sign Debian packages +: ${DPL_PGP_KEY_PASSPHRASE} # Decodes the private key file. + +# Export Asset and Package Parameters for envsubst templating + +export ASSET_ARCHIVE_PATH="${ASSET_ARCHIVE_PATH}" +export ASSET_ARCHIVE_OPTIONAL_PATH="${ASSET_ARCHIVE_OPTIONAL_PATH}" +export ASSET_FILES_HASHED="${ASSET_FILES_HASHED}" +export ASSET_FILES_DOCS="${ASSET_FILES_DOCS}" +export ASSET_FILES_OPTIONAL_GET="${ASSET_FILES_OPTIONAL_GET}" + +export PACKAGE_NAME="${PACKAGE_NAME}" +export PACKAGE_VERSION="${PACKAGE_VERSION}" +export PACKAGE_SUBVERSION="${PACKAGE_SUBVERSION}" # in case we have this +export PACKAGE_REVISION="${PACKAGE_REVISION}" +export PACKAGE_ASSET_MINVERSION="${PACKAGE_ASSET_MINVERSION}" +export PACKAGE_ASSET_MAXVERSION="${PACKAGE_ASSET_MAXVERSION}" +export PACKAGE_INSTALL_PATH="${PACKAGE_INSTALL_PATH}" +export PACKAGE_LINK_PATH="${PACKAGE_LINK_PATH}" +export PACKAGE_DISTRO="${PACKAGE_DISTRO}" +export PACKAGE_URGENCY="${PACKAGE_URGENCY}" +export PACKAGE_NAME_EMAIL="${PACKAGE_NAME_EMAIL}" +export PACKAGE_GROUP_NAME_EMAIL="${PACKAGE_GROUP_NAME_EMAIL}" +export PACKAGE_WEBSITE="${PACKAGE_WEBSITE}" + +export PROGRAM_NAME="${PROGRAM_NAME}" +export PROGRAM_VERSION="${PROGRAM_VERSION}" +export PROGRAM_DESCRIPTION="${PROGRAM_DESCRIPTION}" +export PROGRAM_FILENAME="${PROGRAM_FILENAME}" + +# This file is called in debian_template.sh, so mark our completion so we don't run it again +__DEBIAN_PARAMETERS_INITIALIZED=1 diff --git a/deployer/travis/deployer_dput.sh b/deployer/travis/deployer_dput.sh new file mode 100644 index 0000000000000000000000000000000000000000..863a928cdf01b7a141144f01be2f9b0b664ccf66 --- /dev/null +++ b/deployer/travis/deployer_dput.sh @@ -0,0 +1,133 @@ +#!/bin/bash + +# Deployer for Travis-CI +# DPUT uploader (e.g., Launchpad PPA) +# + +if [[ "$__DPL_DPUT_ACTIVE" == "1" ]]; then + # Install APT dependencies + # paramiko required for ssh + sudo apt-get install python-paramiko expect dput; # python-pip + #pip install paramiko; + + # Output the DPUT config + # Dput only works if you're using secure FTP, so that's what we default to. + cat > "./dput.cf" << EOM +[deployer] +fqdn = ${DPL_DPUT_DOMAIN} +method = ${DPL_DPUT_METHOD} +incoming = ${DPL_DPUT_INCOMING} +login = ${DPL_DPUT_LOGIN} +allow_unsigned_uploads = 0 +EOM + + # Output SSH config + # Don't let SSH prompt us for untrusted hosts + cat >> "./ssh_config" << EOM + +Host * + StrictHostKeyChecking no + UserKnownHostsFile=/dev/null + PubKeyAuthentication yes + IdentityFile ${PWD}/key.private + IdentitiesOnly yes +EOM + sudo sh -c "cat < ${PWD}/ssh_config >> /etc/ssh/ssh_config"; + + # Get the private key + echo "$DPL_SSH_KEY_PRIVATE" | base64 --decode > key.private; + chmod 700 ./key.private; + + if [[ "$_DPL_PACKAGE_MAIN" == "1" ]]; then + PACKAGEFILENAME=${PACKAGE_NAME}_${PACKAGE_VERSION}${PACKAGE_SUBVERSION}${PACKAGE_REVISION}; + PACKAGEDBGFILENAME=${PACKAGE_NAME}-dbg_${PACKAGE_VERSION}${PACKAGE_SUBVERSION}${PACKAGE_REVISION}; + #PACKAGENIGHTLYFILENAME=${PACKAGE_NAME}-nightly_${PACKAGE_VERSION}${PACKAGE_SUBVERSION}${PACKAGE_REVISION}; + #PACKAGENIGHTLYDBGFILENAME=${PACKAGE_NAME}-nightly-dbg_${PACKAGE_VERSION}${PACKAGE_SUBVERSION}${PACKAGE_REVISION}; + #PACKAGEPATCHFILENAME=${PACKAGE_NAME}-patch_${PACKAGE_VERSION}${PACKAGE_SUBVERSION}${PACKAGE_REVISION}; + #PACKAGEPATCHDBGFILENAME=${PACKAGE_NAME}-patch-dbg_${PACKAGE_VERSION}${PACKAGE_SUBVERSION}${PACKAGE_REVISION}; + #PACKAGEPATCHNIGHTLYFILENAME=${PACKAGE_NAME}-patch-nightly_${PACKAGE_VERSION}${PACKAGE_SUBVERSION}${PACKAGE_REVISION}; + #PACKAGEPATCHNIGHTLYDBGFILENAME=${PACKAGE_NAME}-patch-nightly-dbg_${PACKAGE_VERSION}${PACKAGE_SUBVERSION}${PACKAGE_REVISION}; + + PACKAGEFILENAMES=( + $PACKAGEFILENAME + $PACKAGEDBGFILENAME + #$PACKAGENIGHTLYFILENAME + #$PACKAGENIGHTLYDBGFILENAME + #$PACKAGEPATCHFILENAME + #$PACKAGEPATCHDBGFILENAME + #$PACKAGEPATCHNIGHTLYFILENAME + #$PACKAGEPATCHNIGHTLYDBGFILENAME + ); + + # Main packages are in parent of root repo folder + OLDPWD=$PWD; # [repo]/build + cd ../..; + + # Enter passphrase if required + for n in ${PACKAGEFILENAMES}; do + for f in $n*.changes; do + # Binary builds also generate source builds, so exclude the source + # builds if desired + if [[ "$_DPL_PACKAGE_SOURCE" != "1" ]]; then + if [[ "$f" == *"_source"* ]] || [[ "$f" == *".tar.xz"* ]]; then + continue; + fi; + fi; + + expect <(cat <<EOD +spawn dput -c "${OLDPWD}/dput.cf" deployer "$f"; +expect "Enter passphrase for key" +send "${DPL_SSH_KEY_PASSPHRASE}\r" +interact +EOD +); + done; + done; + + # Go back to [repo]/build folder + cd $OLDPWD; + fi; + + if [[ "$_DPL_PACKAGE_ASSET" == "1" ]]; then + PACKAGEFILENAME=${PACKAGE_NAME}-data_${PACKAGE_VERSION}${PACKAGE_SUBVERSION}${PACKAGE_REVISION}; + #PACKAGENIGHTLYFILENAME=${PACKAGE_NAME}-nightly-data_${PACKAGE_VERSION}${PACKAGE_SUBVERSION}${PACKAGE_REVISION}; + #PACKAGEPATCHFILENAME=${PACKAGE_NAME}-patch-data_${PACKAGE_VERSION}${PACKAGE_SUBVERSION}${PACKAGE_REVISION}; + #PACKAGEPATCHNIGHTLYFILENAME=${PACKAGE_NAME}-patch-nightly-data_${PACKAGE_VERSION}${PACKAGE_SUBVERSION}${PACKAGE_REVISION}; + + PACKAGEFILENAMES=( + $PACKAGEFILENAME + #$PACKAGENIGHTLYFILENAME + #$PACKAGEPATCHFILENAME + #$PACKAGEPATCHNIGHTLYFILENAME + ) + + # Asset packages are in root repo folder + OLDPWD=$PWD; # [repo]/build + cd ..; + + # Enter passphrase if required + for n in ${PACKAGEFILENAMES}; do + for f in $n*.changes; do + # Binary builds also generate source builds, so exclude the source + # builds if desired + if [[ "$_DPL_PACKAGE_SOURCE" != "1" ]]; then + if [[ "$f" == *"_source"* ]] || [[ "$f" == *".tar.xz"* ]]; then + continue; + fi; + fi; + expect <(cat <<EOD +spawn dput -c "${OLDPWD}/dput.cf" deployer "$f"; +expect "Enter passphrase for key" +send "${DPL_SSH_KEY_PASSPHRASE}\r" +interact +EOD +); + done; + done; + + # Go back to [repo]/build folder + cd $OLDPWD; + fi; + + srm ./key.private; +fi; diff --git a/deployer/travis/deployer_ftp.sh b/deployer/travis/deployer_ftp.sh new file mode 100644 index 0000000000000000000000000000000000000000..1f6bd08b597d3c65c545b340de63df2b82208824 --- /dev/null +++ b/deployer/travis/deployer_ftp.sh @@ -0,0 +1,137 @@ +#!/bin/bash + +# Deployer for Travis-CI +# FTP Uploader +# +# Package files are uploaded to, e.g., ftp://username:password@example.com:21/path/to/upload/STJr/SRB2/master/460873812-151.1 +# With file `commit.txt` and folder(s) `bin` and `package` +# +# Set these environment variables in your Travis-CI settings, where they are stored securely. +# See other shell scripts for more options. +# +# DPL_FTP_PROTOCOL = ftp (ftp or sftp or ftps or however your FTP URI begins) +# DPL_FTP_USER = username +# DPL_FTP_PASS = password +# DPL_FTP_HOSTNAME = example.com +# DPL_FTP_PORT = 21 +# DPL_FTP_PATH = path/to/upload (do not add trailing slash) + +if [[ "$__DPL_FTP_ACTIVE" == "1" ]]; then + if [[ "$TRAVIS_JOB_NAME" != "" ]]; then + JOBNAME=$TRAVIS_JOB_NAME; + else + if [[ "$_DPL_JOB_NAME" != "" ]]; then + JOBNAME=$_DPL_JOB_NAME; + else + JOBNAME=$TRAVIS_OS_NAME; + fi; + fi; + + # Generate commit.txt file + echo "Travis-CI Build $TRAVIS_OS_NAME - $TRAVIS_REPO_SLUG/$TRAVIS_BRANCH - $TRAVIS_JOB_NUMBER - $JOBNAME" > "commit.txt"; + echo "Job ID $TRAVIS_JOB_ID" >> "commit.txt"; + echo "" >> "commit.txt"; + echo "Commit $TRAVIS_COMMIT" >> "commit.txt"; + echo "$TRAVIS_COMMIT_MESSAGE" >> "commit.txt"; + echo "" >> "commit.txt"; + + # Initialize FTP parameters + if [[ "$DPL_FTP_PORT" == "" ]]; then + DPL_FTP_PORT=21; + fi; + if [[ "$DPL_FTP_PROTOCOL" == "" ]]; then + DPL_FTP_PROTOCOL=ftp; + fi; + __DPL_FTP_LOCATION=$DPL_FTP_PROTOCOL://$DPL_FTP_HOSTNAME:$DPL_FTP_PORT/$DPL_FTP_PATH/$TRAVIS_REPO_SLUG/$TRAVIS_BRANCH/$TRAVIS_JOB_ID-$TRAVIS_JOB_NUMBER-$JOBNAME; + + # Upload to FTP! + echo "Uploading to FTP..."; + curl --ftp-create-dirs -T "commit.txt" -u $DPL_FTP_USER:$DPL_FTP_PASS "$__DPL_FTP_LOCATION/commit.txt"; + + if [[ "$__DPL_DEBIAN_ACTIVE" == "1" ]]; then + if [[ "$_DPL_PACKAGE_MAIN" == "1" ]]; then + PACKAGEFILENAME=${PACKAGE_NAME}_${PACKAGE_VERSION}${PACKAGE_SUBVERSION}${PACKAGE_REVISION}; + PACKAGEDBGFILENAME=${PACKAGE_NAME}-dbg_${PACKAGE_VERSION}${PACKAGE_SUBVERSION}${PACKAGE_REVISION}; + #PACKAGENIGHTLYFILENAME=${PACKAGE_NAME}-nightly_${PACKAGE_VERSION}${PACKAGE_SUBVERSION}${PACKAGE_REVISION}; + #PACKAGENIGHTLYDBGFILENAME=${PACKAGE_NAME}-nightly-dbg_${PACKAGE_VERSION}${PACKAGE_SUBVERSION}${PACKAGE_REVISION}; + #PACKAGEPATCHFILENAME=${PACKAGE_NAME}-patch_${PACKAGE_VERSION}${PACKAGE_SUBVERSION}${PACKAGE_REVISION}; + #PACKAGEPATCHDBGFILENAME=${PACKAGE_NAME}-patch-dbg_${PACKAGE_VERSION}${PACKAGE_SUBVERSION}${PACKAGE_REVISION}; + #PACKAGEPATCHNIGHTLYFILENAME=${PACKAGE_NAME}-patch-nightly_${PACKAGE_VERSION}${PACKAGE_SUBVERSION}${PACKAGE_REVISION}; + #PACKAGEPATCHNIGHTLYDBGFILENAME=${PACKAGE_NAME}-patch-nightly-dbg_${PACKAGE_VERSION}${PACKAGE_SUBVERSION}${PACKAGE_REVISION}; + + PACKAGEFILENAMES=( + $PACKAGEFILENAME + $PACKAGEDBGFILENAME + #$PACKAGENIGHTLYFILENAME + #$PACKAGENIGHTLYDBGFILENAME + #$PACKAGEPATCHFILENAME + #$PACKAGEPATCHDBGFILENAME + #$PACKAGEPATCHNIGHTLYFILENAME + #$PACKAGEPATCHNIGHTLYDBGFILENAME + ); + + # Main packages are in parent of root repo folder + OLDPWD=$PWD; # [repo]/build + cd ../..; + + for n in ${PACKAGEFILENAMES}; do + for f in ./$n*; do + # Binary builds also generate source builds, so exclude the source + # builds if desired + if [[ "$_DPL_PACKAGE_SOURCE" != "1" ]]; then + if [[ "$f" == *"_source"* ]] || [[ "$f" == *".tar.xz"* ]]; then + continue; + fi; + fi; + curl --ftp-create-dirs -T "$f" -u $DPL_FTP_USER:$DPL_FTP_PASS "$__DPL_FTP_LOCATION/package/main/$f"; + done; + done; + + # Go back to [repo]/build folder + cd $OLDPWD; + fi; + + if [[ "$_DPL_PACKAGE_ASSET" == "1" ]]; then + PACKAGEFILENAME=${PACKAGE_NAME}-data_${PACKAGE_VERSION}${PACKAGE_SUBVERSION}${PACKAGE_REVISION}; + #PACKAGENIGHTLYFILENAME=${PACKAGE_NAME}-nightly-data_${PACKAGE_VERSION}${PACKAGE_SUBVERSION}${PACKAGE_REVISION}; + #PACKAGEPATCHFILENAME=${PACKAGE_NAME}-patch-data_${PACKAGE_VERSION}${PACKAGE_SUBVERSION}${PACKAGE_REVISION}; + #PACKAGEPATCHNIGHTLYFILENAME=${PACKAGE_NAME}-patch-nightly-data_${PACKAGE_VERSION}${PACKAGE_SUBVERSION}${PACKAGE_REVISION}; + + PACKAGEFILENAMES=( + $PACKAGEFILENAME + #$PACKAGENIGHTLYFILENAME + #$PACKAGEPATCHFILENAME + #$PACKAGEPATCHNIGHTLYFILENAME + ) + + # Asset packages are in root repo folder + OLDPWD=$PWD; # [repo]/build + cd ..; + + for n in ${PACKAGEFILENAMES}; do + for f in ./$n*; do + # Binary builds also generate source builds, so exclude the source + # builds if desired + if [[ "$_DPL_PACKAGE_SOURCE" != "1" ]]; then + if [[ "$f" == *"_source"* ]] || [[ "$f" == *".tar.xz"* ]]; then + continue; + fi; + fi; + curl --ftp-create-dirs -T "$f" -u $DPL_FTP_USER:$DPL_FTP_PASS "$__DPL_FTP_LOCATION/package/asset/$f"; + done; + done; + + # Go back to [repo]/build folder + cd $OLDPWD; + fi; + else + if [[ "$_DPL_BINARY" == "1" ]]; then + find bin -type f -exec curl -u $DPL_FTP_USER:$DPL_FTP_PASS --ftp-create-dirs -T {} $__DPL_FTP_LOCATION/{} \;; + fi; + + if [[ "$_DPL_PACKAGE_BINARY" == "1" ]]; then + sudo rm -r package/_CPack_Packages + find package -type f -exec curl -u $DPL_FTP_USER:$DPL_FTP_PASS --ftp-create-dirs -T {} $__DPL_FTP_LOCATION/{} \;; + fi; + fi; +fi diff --git a/libs/libgme.props b/libs/libgme.props new file mode 100644 index 0000000000000000000000000000000000000000..209f6b9a88219d178e1d4ab066c94dd18539df25 --- /dev/null +++ b/libs/libgme.props @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ImportGroup Label="PropertySheets" /> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Platform)' == 'Win32' OR '$(Platform)' == 'x64'"> + <IncludePath>$(SolutionDir)libs\gme\include;$(IncludePath)</IncludePath> + <LibraryPath Condition="'$(Platform)' == 'Win32'">$(SolutionDir)libs\gme\win32;$(LibraryPath)</LibraryPath> + <LibraryPath Condition="'$(Platform)' == 'x64'">$(SolutionDir)libs\gme\win64;$(LibraryPath)</LibraryPath> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Platform)' == 'Win32' OR '$(Platform)' == 'x64'"> + <Link> + <AdditionalDependencies>libgme.dll.a;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemGroup /> +</Project> \ No newline at end of file diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index a6fab34ff621af052079ac5c8acb145f7ab8f65e..9e319d100eea7a864d301599cd28785328ab93b3 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -123,6 +123,7 @@ set(SRB2_CORE_RENDER_SOURCES r_sky.c r_splats.c r_things.c + r_portal.c r_bsp.h r_data.h @@ -136,6 +137,7 @@ set(SRB2_CORE_RENDER_SOURCES r_splats.h r_state.h r_things.h + r_portal.h ) set(SRB2_CORE_GAME_SOURCES diff --git a/src/Makefile b/src/Makefile index 5407a4d5ea9dee14be42ff8cda8f30d4240c4274..b8d91fcccdfb364044a3501e2cce0230a68a5406 100644 --- a/src/Makefile +++ b/src/Makefile @@ -455,6 +455,7 @@ OBJS:=$(i_main_o) \ $(OBJDIR)/r_sky.o \ $(OBJDIR)/r_splats.o \ $(OBJDIR)/r_things.o \ + $(OBJDIR)/r_portal.o \ $(OBJDIR)/screen.o \ $(OBJDIR)/v_video.o \ $(OBJDIR)/s_sound.o \ diff --git a/src/hardware/hw_draw.c b/src/hardware/hw_draw.c index c43cfe82a96196ce3ae58ee3720bab4f610a23fd..dd9fa8423b21897fc8894d37bfd4e59486be171f 100644 --- a/src/hardware/hw_draw.c +++ b/src/hardware/hw_draw.c @@ -1266,21 +1266,24 @@ UINT8 *HWR_GetScreenshot(void) return buf; } -boolean HWR_Screenshot(const char *lbmname) +boolean HWR_Screenshot(const char *pathname) { boolean ret; UINT8 *buf = malloc(vid.width * vid.height * 3 * sizeof (*buf)); if (!buf) + { + CONS_Debug(DBG_RENDER, "HWR_Screenshot: Failed to allocate memory\n"); return false; + } // returns 24bit 888 RGB HWD.pfnReadRect(0, 0, vid.width, vid.height, vid.width * 3, (void *)buf); #ifdef USE_PNG - ret = M_SavePNG(lbmname, buf, vid.width, vid.height, false); + ret = M_SavePNG(pathname, buf, vid.width, vid.height, NULL); #else - ret = saveTGA(lbmname, buf, vid.width, vid.height); + ret = saveTGA(pathname, buf, vid.width, vid.height); #endif free(buf); return ret; diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index b1811eb4500558549bd11ec59edca619ae2f548f..c79452bb56f4e65a99b7588728b9fb8747639e0a 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -6194,7 +6194,7 @@ void HWR_RenderPlayerView(INT32 viewnumber, player_t *player) } // note: sets viewangle, viewx, viewy, viewz - R_SetupFrame(player, false); // This can stay false because it is only used to set viewsky in r_main.c, which isn't used here + R_SetupFrame(player); // copy view cam position for local use dup_viewx = viewx; diff --git a/src/hardware/hw_main.h b/src/hardware/hw_main.h index ced8f837da26f899bbf612e01e96eff235fbe580..fdfc1d25722712d7f11740492d54483639d21bf1 100644 --- a/src/hardware/hw_main.h +++ b/src/hardware/hw_main.h @@ -39,8 +39,6 @@ void HWR_RenderSkyboxView(INT32 viewnumber, player_t *player); void HWR_RenderPlayerView(INT32 viewnumber, player_t *player); void HWR_DrawViewBorder(INT32 clearlines); void HWR_DrawFlatFill(INT32 x, INT32 y, INT32 w, INT32 h, lumpnum_t flatlumpnum); -UINT8 *HWR_GetScreenshot(void); -boolean HWR_Screenshot(const char *lbmname); void HWR_InitTextureMapping(void); void HWR_SetViewSize(void); void HWR_DrawPatch(GLPatch_t *gpatch, INT32 x, INT32 y, INT32 option); @@ -54,6 +52,9 @@ void HWR_DrawFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 color); void HWR_DrawConsoleFill(INT32 x, INT32 y, INT32 w, INT32 h, UINT32 color, INT32 options); // Lat: separate flags from color since color needs to be an uint to work right. void HWR_DrawPic(INT32 x,INT32 y,lumpnum_t lumpnum); +UINT8 *HWR_GetScreenshot(void); +boolean HWR_Screenshot(const char *pathname); + void HWR_AddCommands(void); void HWR_CorrectSWTricks(void); void transform(float *cx, float *cy, float *cz); diff --git a/src/info.h b/src/info.h index 3e4243bdb43eff29f4976ba0cdbf707dc662262e..13abfa5f60249d91afd05bc0fba7b35376f41a44 100644 --- a/src/info.h +++ b/src/info.h @@ -267,7 +267,7 @@ void A_SaloonDoorSpawn(); void A_MinecartSparkThink(); // ratio of states to sprites to mobj types is roughly 6 : 1 : 1 -#define NUMMOBJFREESLOTS 256 +#define NUMMOBJFREESLOTS 512 #define NUMSPRITEFREESLOTS NUMMOBJFREESLOTS #define NUMSTATEFREESLOTS (NUMMOBJFREESLOTS*8) diff --git a/src/m_misc.c b/src/m_misc.c index c967548c65b54560ddf3efbc1d40bae731df0062..621d705f9084131b2af359655a60b5a8f13ac809 100644 --- a/src/m_misc.c +++ b/src/m_misc.c @@ -30,6 +30,7 @@ #include "g_game.h" #include "m_misc.h" #include "hu_stuff.h" +#include "st_stuff.h" #include "v_video.h" #include "z_zone.h" #include "g_input.h" @@ -609,6 +610,23 @@ void M_SaveConfig(const char *filename) fclose(f); } +// ========================================================================== +// SCREENSHOTS +// ========================================================================== +static UINT8 screenshot_palette[768]; +static void M_CreateScreenShotPalette(void) +{ + size_t i, j; + for (i = 0, j = 0; i < 768; i += 3, j++) + { + RGBA_t locpal = ((cv_screenshot_colorprofile.value) + ? pLocalPalette[(max(st_palette,0)*256)+j] + : pMasterPalette[(max(st_palette,0)*256)+j]); + screenshot_palette[i] = locpal.s.red; + screenshot_palette[i+1] = locpal.s.green; + screenshot_palette[i+2] = locpal.s.blue; + } +} #if NUMSCREENS > 2 static const char *Newsnapshotfile(const char *pathname, const char *ext) @@ -677,25 +695,20 @@ static void PNG_warn(png_structp PNG, png_const_charp pngtext) CONS_Debug(DBG_RENDER, "libpng warning at %p: %s", PNG, pngtext); } -static void M_PNGhdr(png_structp png_ptr, png_infop png_info_ptr, PNG_CONST png_uint_32 width, PNG_CONST png_uint_32 height, const boolean palette) +static void M_PNGhdr(png_structp png_ptr, png_infop png_info_ptr, PNG_CONST png_uint_32 width, PNG_CONST png_uint_32 height, PNG_CONST png_byte *palette) { const png_byte png_interlace = PNG_INTERLACE_NONE; //PNG_INTERLACE_ADAM7 if (palette) { png_colorp png_PLTE = png_malloc(png_ptr, sizeof(png_color)*256); //palette + const png_byte *pal = palette; png_uint_16 i; - - RGBA_t *pal = ((cv_screenshot_colorprofile.value) - ? pLocalPalette - : pMasterPalette); - for (i = 0; i < 256; i++) { - png_PLTE[i].red = pal[i].s.red; - png_PLTE[i].green = pal[i].s.green; - png_PLTE[i].blue = pal[i].s.blue; + png_PLTE[i].red = *pal; pal++; + png_PLTE[i].green = *pal; pal++; + png_PLTE[i].blue = *pal; pal++; } - png_set_IHDR(png_ptr, png_info_ptr, width, height, 8, PNG_COLOR_TYPE_PALETTE, png_interlace, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); png_write_info_before_PLTE(png_ptr, png_info_ptr); @@ -968,7 +981,7 @@ static void M_PNGfix_acTL(png_structp png_ptr, png_infop png_info_ptr, #endif } -static boolean M_SetupaPNG(png_const_charp filename, boolean palette) +static boolean M_SetupaPNG(png_const_charp filename, png_bytep pal) { apng_FILE = fopen(filename,"wb+"); // + mode for reading if (!apng_FILE) @@ -1020,7 +1033,7 @@ static boolean M_SetupaPNG(png_const_charp filename, boolean palette) png_set_compression_strategy(apng_ptr, cv_zlib_strategya.value); png_set_compression_window_bits(apng_ptr, cv_zlib_window_bitsa.value); - M_PNGhdr(apng_ptr, apng_info_ptr, vid.width, vid.height, palette); + M_PNGhdr(apng_ptr, apng_info_ptr, vid.width, vid.height, pal); M_PNGText(apng_ptr, apng_info_ptr, true); @@ -1044,6 +1057,7 @@ static boolean M_SetupaPNG(png_const_charp filename, boolean palette) static inline moviemode_t M_StartMovieAPNG(const char *pathname) { #ifdef USE_APNG + UINT8 *palette; const char *freename = NULL; boolean ret = false; @@ -1059,10 +1073,8 @@ static inline moviemode_t M_StartMovieAPNG(const char *pathname) return MM_OFF; } - if (rendermode == render_soft) - ret = M_SetupaPNG(va(pandf,pathname,freename), true); - else - ret = M_SetupaPNG(va(pandf,pathname,freename), false); + if (rendermode == render_soft) M_CreateScreenShotPalette(); + ret = M_SetupaPNG(va(pandf,pathname,freename), (palette = screenshot_palette)); if (!ret) { @@ -1265,13 +1277,14 @@ void M_StopMovie(void) * \param data The image data. * \param width Width of the picture. * \param height Height of the picture. - * \param palette Palette of image data + * \param palette Palette of image data. * \note if palette is NULL, BGR888 format */ -boolean M_SavePNG(const char *filename, void *data, int width, int height, const boolean palette) +boolean M_SavePNG(const char *filename, void *data, int width, int height, const UINT8 *palette) { png_structp png_ptr; png_infop png_info_ptr; + PNG_CONST png_byte *PLTE = (const png_byte *)palette; #ifdef PNG_SETJMP_SUPPORTED #ifdef USE_FAR_KEYWORD jmp_buf jmpbuf; @@ -1286,8 +1299,7 @@ boolean M_SavePNG(const char *filename, void *data, int width, int height, const return false; } - png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, - PNG_error, PNG_warn); + png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, PNG_error, PNG_warn); if (!png_ptr) { CONS_Debug(DBG_RENDER, "M_SavePNG: Error on initialize libpng\n"); @@ -1334,7 +1346,7 @@ boolean M_SavePNG(const char *filename, void *data, int width, int height, const png_set_compression_strategy(png_ptr, cv_zlib_strategy.value); png_set_compression_window_bits(png_ptr, cv_zlib_window_bits.value); - M_PNGhdr(png_ptr, png_info_ptr, width, height, palette); + M_PNGhdr(png_ptr, png_info_ptr, width, height, PLTE); M_PNGText(png_ptr, png_info_ptr, false); @@ -1381,7 +1393,7 @@ typedef struct * \param palette Palette of image data */ #if NUMSCREENS > 2 -static boolean WritePCXfile(const char *filename, const UINT8 *data, int width, int height) +static boolean WritePCXfile(const char *filename, const UINT8 *data, int width, int height, const UINT8 *pal) { int i; size_t length; @@ -1425,15 +1437,11 @@ static boolean WritePCXfile(const char *filename, const UINT8 *data, int width, // write color table { - RGBA_t *pal = ((cv_screenshot_colorprofile.value) - ? pLocalPalette - : pMasterPalette); - for (i = 0; i < 256; i++) { - *pack++ = pal[i].s.red; - *pack++ = pal[i].s.green; - *pack++ = pal[i].s.blue; + *pack++ = *pal; pal++; + *pack++ = *pal; pal++; + *pack++ = *pal; pal++; } } @@ -1453,9 +1461,8 @@ void M_ScreenShot(void) } /** Takes a screenshot. - * The screenshot is saved as "srb2xxxx.pcx" (or "srb2xxxx.tga" in hardware - * rendermode) where xxxx is the lowest four-digit number for which a file - * does not already exist. + * The screenshot is saved as "srb2xxxx.png" where xxxx is the lowest + * four-digit number for which a file does not already exist. * * \sa HWR_ScreenShot */ @@ -1469,6 +1476,10 @@ void M_DoScreenShot(void) // Don't take multiple screenshots, obviously takescreenshot = false; + // how does one take a screenshot without a render system? + if (rendermode == render_none) + return; + if (cv_screenshot_option.value == 0) pathname = usehome ? srb2home : srb2path; else if (cv_screenshot_option.value == 1) @@ -1479,16 +1490,13 @@ void M_DoScreenShot(void) pathname = cv_screenshot_folder.string; #ifdef USE_PNG - if (rendermode != render_none) - freename = Newsnapshotfile(pathname,"png"); + freename = Newsnapshotfile(pathname,"png"); #else if (rendermode == render_soft) freename = Newsnapshotfile(pathname,"pcx"); - else if (rendermode != render_none) + else if (rendermode == render_opengl) freename = Newsnapshotfile(pathname,"tga"); #endif - else - I_Error("Can't take a screenshot without a render system"); if (rendermode == render_soft) { @@ -1502,16 +1510,16 @@ void M_DoScreenShot(void) // save the pcx file #ifdef HWRENDER - if (rendermode != render_soft) + if (rendermode == render_opengl) ret = HWR_Screenshot(va(pandf,pathname,freename)); else #endif - if (rendermode != render_none) { + M_CreateScreenShotPalette(); #ifdef USE_PNG - ret = M_SavePNG(va(pandf,pathname,freename), linear, vid.width, vid.height, true); + ret = M_SavePNG(va(pandf,pathname,freename), linear, vid.width, vid.height, screenshot_palette); #else - ret = WritePCXfile(va(pandf,pathname,freename), linear, vid.width, vid.height); + ret = WritePCXfile(va(pandf,pathname,freename), linear, vid.width, vid.height, screenshot_palette); #endif } @@ -1519,14 +1527,14 @@ failure: if (ret) { if (moviemode != MM_SCREENSHOT) - CONS_Printf(M_GetText("screen shot %s saved in %s\n"), freename, pathname); + CONS_Printf(M_GetText("Screen shot %s saved in %s\n"), freename, pathname); } else { if (freename) - CONS_Printf(M_GetText("Couldn't create screen shot %s in %s\n"), freename, pathname); + CONS_Alert(CONS_ERROR, M_GetText("Couldn't create screen shot %s in %s\n"), freename, pathname); else - CONS_Printf(M_GetText("Couldn't create screen shot (all 10000 slots used!) in %s\n"), pathname); + CONS_Alert(CONS_ERROR, M_GetText("Couldn't create screen shot in %s (all 10000 slots used!)\n"), pathname); if (moviemode == MM_SCREENSHOT) M_StopMovie(); diff --git a/src/m_misc.h b/src/m_misc.h index 28d9cd5a508919ed80c857cb5a9b83245bcc7bdf..6ac92dbcc085324c5c5bcba48c8f22fd2824c85f 100644 --- a/src/m_misc.h +++ b/src/m_misc.h @@ -58,7 +58,7 @@ void FIL_ForceExtension(char *path, const char *extension); boolean FIL_CheckExtension(const char *in); #ifdef HAVE_PNG -boolean M_SavePNG(const char *filename, void *data, int width, int height, const boolean palette); +boolean M_SavePNG(const char *filename, void *data, int width, int height, const UINT8 *palette); #endif extern boolean takescreenshot; diff --git a/src/p_setup.c b/src/p_setup.c index 0602865a9dfe876573dbf74f90dc00dac0f2cd46..af4f1f9dd6989322f85704951b79248400b2a4a6 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -3147,7 +3147,6 @@ boolean P_SetupLevel(boolean skipprecip) savedata.lives = 0; } - skyVisible = skyVisible1 = skyVisible2 = true; // assume the skybox is visible on level load. if (loadprecip) // uglier hack { // to make a newly loaded level start on the second frame. INT32 buf = gametic % BACKUPTICS; diff --git a/src/p_spec.c b/src/p_spec.c index f8aefb9c8d871d97556951cd5970c5bde69fb138..e47b5cc036edf8a44657666479ff13ac612bfc09 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -7746,22 +7746,11 @@ static void P_SpawnScrollers(void) for (i = 0; i < numlines; i++, l++) { - fixed_t dx = l->dx; // direction and speed of scrolling - fixed_t dy = l->dy; + fixed_t dx = l->dx >> SCROLL_SHIFT; // direction and speed of scrolling + fixed_t dy = l->dy >> SCROLL_SHIFT; INT32 control = -1, accel = 0; // no control sector or acceleration INT32 special = l->special; - // If front texture X offset provided, override the amount with it. - if (sides[l->sidenum[0]].textureoffset != 0) - { - fixed_t len = sides[l->sidenum[0]].textureoffset; - fixed_t h = FixedHypot(dx, dy); - dx = FixedMul(FixedDiv(dx, h), len); - dy = FixedMul(FixedDiv(dy, h), len); - } - dx = dx >> SCROLL_SHIFT; - dy = dy >> SCROLL_SHIFT; - // These types are same as the ones they get set to except that the // first side's sector's heights cause scrolling when they change, and // this linedef controls the direction and speed of the scrolling. The @@ -7796,14 +7785,8 @@ static void P_SpawnScrollers(void) case 513: // scroll effect ceiling case 533: // scroll and carry objects on ceiling - if (l->tag == 0) - Add_Scroller(sc_ceiling, -dx, dy, control, l->frontsector - sectors, accel, l->flags & ML_NOCLIMB); - else - { - for (s = -1; (s = P_FindSectorFromLineTag(l, s)) >= 0 ;) - Add_Scroller(sc_ceiling, -dx, dy, control, s, accel, l->flags & ML_NOCLIMB); - } - + for (s = -1; (s = P_FindSectorFromLineTag(l, s)) >= 0 ;) + Add_Scroller(sc_ceiling, -dx, dy, control, s, accel, l->flags & ML_NOCLIMB); if (special != 533) break; /* FALLTHRU */ @@ -7811,26 +7794,14 @@ static void P_SpawnScrollers(void) case 523: // carry objects on ceiling dx = FixedMul(dx, CARRYFACTOR); dy = FixedMul(dy, CARRYFACTOR); - - if (l->tag == 0) - Add_Scroller(sc_carry_ceiling, dx, dy, control, l->frontsector - sectors, accel, l->flags & ML_NOCLIMB); - else - { - for (s = -1; (s = P_FindSectorFromLineTag(l, s)) >= 0 ;) - Add_Scroller(sc_carry_ceiling, dx, dy, control, s, accel, l->flags & ML_NOCLIMB); - } + for (s = -1; (s = P_FindSectorFromLineTag(l, s)) >= 0 ;) + Add_Scroller(sc_carry_ceiling, dx, dy, control, s, accel, l->flags & ML_NOCLIMB); break; case 510: // scroll effect floor case 530: // scroll and carry objects on floor - if (l->tag == 0) - Add_Scroller(sc_floor, -dx, dy, control, l->frontsector - sectors, accel, l->flags & ML_NOCLIMB); - else - { - for (s = -1; (s = P_FindSectorFromLineTag(l, s)) >= 0 ;) - Add_Scroller(sc_floor, -dx, dy, control, s, accel, l->flags & ML_NOCLIMB); - } - + for (s = -1; (s = P_FindSectorFromLineTag(l, s)) >= 0 ;) + Add_Scroller(sc_floor, -dx, dy, control, s, accel, l->flags & ML_NOCLIMB); if (special != 530) break; /* FALLTHRU */ @@ -7838,14 +7809,8 @@ static void P_SpawnScrollers(void) case 520: // carry objects on floor dx = FixedMul(dx, CARRYFACTOR); dy = FixedMul(dy, CARRYFACTOR); - - if (l->tag == 0) - Add_Scroller(sc_carry, dx, dy, control, l->frontsector - sectors, accel, l->flags & ML_NOCLIMB); - else - { - for (s = -1; (s = P_FindSectorFromLineTag(l, s)) >= 0 ;) - Add_Scroller(sc_carry, dx, dy, control, s, accel, l->flags & ML_NOCLIMB); - } + for (s = -1; (s = P_FindSectorFromLineTag(l, s)) >= 0 ;) + Add_Scroller(sc_carry, dx, dy, control, s, accel, l->flags & ML_NOCLIMB); break; // scroll wall according to linedef @@ -9208,77 +9173,43 @@ static void P_SpawnPushers(void) line_t *l = lines; register INT32 s; mobj_t *thing; - pushertype_e pushertype; - fixed_t dx, dy; for (i = 0; i < numlines; i++, l++) - { switch (l->special) { - case 541: // wind - pushertype = p_wind; - break; - - case 544: // current - pushertype = p_current; - break; - case 547: // push/pull - if (l->tag == 0) - { - s = l->frontsector - sectors; - if ((thing = P_GetPushThing(s)) != NULL) // No MT_P* means no effect - Add_Pusher(p_push, l->dx, l->dy, thing, s, -1, l->flags & ML_NOCLIMB, l->flags & ML_EFFECT4); - } - else + case 541: // wind + for (s = -1; (s = P_FindSectorFromLineTag(l, s)) >= 0 ;) + Add_Pusher(p_wind, l->dx, l->dy, NULL, s, -1, l->flags & ML_NOCLIMB, l->flags & ML_EFFECT4); + break; + case 544: // current + for (s = -1; (s = P_FindSectorFromLineTag(l, s)) >= 0 ;) + Add_Pusher(p_current, l->dx, l->dy, NULL, s, -1, l->flags & ML_NOCLIMB, l->flags & ML_EFFECT4); + break; + case 547: // push/pull for (s = -1; (s = P_FindSectorFromLineTag(l, s)) >= 0 ;) { - if ((thing = P_GetPushThing(s)) != NULL) // No MT_P* means no effect + thing = P_GetPushThing(s); + if (thing) // No MT_P* means no effect Add_Pusher(p_push, l->dx, l->dy, thing, s, -1, l->flags & ML_NOCLIMB, l->flags & ML_EFFECT4); } - - continue; - - case 545: // current up - pushertype = p_upcurrent; - break; - - case 546: // current down - pushertype = p_downcurrent; - break; - - case 542: // wind up - pushertype = p_upwind; - break; - - case 543: // wind down - pushertype = p_downwind; - break; - - default: - continue; - } - - dx = l->dx; - dy = l->dy; - - // Obtain versor and scale it up according to texture offset, if provided; line length is ignored in this case. - - if (sides[l->sidenum[0]].textureoffset != 0) - { - fixed_t len = sides[l->sidenum[0]].textureoffset; - fixed_t h = FixedHypot(dx, dy); - dx = FixedMul(FixedDiv(dx, h), len); - dy = FixedMul(FixedDiv(dy, h), len); - } - - if (l->tag == 0) - Add_Pusher(pushertype, dx, dy, NULL, l->frontsector - sectors, -1, l->flags & ML_NOCLIMB, l->flags & ML_EFFECT4); - else - { - for (s = -1; (s = P_FindSectorFromLineTag(l, s)) >= 0 ;) - Add_Pusher(pushertype, dx, dy, NULL, s, -1, l->flags & ML_NOCLIMB, l->flags & ML_EFFECT4); + break; + case 545: // current up + for (s = -1; (s = P_FindSectorFromLineTag(l, s)) >= 0 ;) + Add_Pusher(p_upcurrent, l->dx, l->dy, NULL, s, -1, l->flags & ML_NOCLIMB, l->flags & ML_EFFECT4); + break; + case 546: // current down + for (s = -1; (s = P_FindSectorFromLineTag(l, s)) >= 0 ;) + Add_Pusher(p_downcurrent, l->dx, l->dy, NULL, s, -1, l->flags & ML_NOCLIMB, l->flags & ML_EFFECT4); + break; + case 542: // wind up + for (s = -1; (s = P_FindSectorFromLineTag(l, s)) >= 0 ;) + Add_Pusher(p_upwind, l->dx, l->dy, NULL, s, -1, l->flags & ML_NOCLIMB, l->flags & ML_EFFECT4); + break; + case 543: // wind down + for (s = -1; (s = P_FindSectorFromLineTag(l, s)) >= 0 ;) + Add_Pusher(p_downwind, l->dx, l->dy, NULL, s, -1, l->flags & ML_NOCLIMB, l->flags & ML_EFFECT4); + break; } - } } static void P_SearchForDisableLinedefs(void) diff --git a/src/r_bsp.c b/src/r_bsp.c index 22abaeb88e8783e4b67c8efdcd695e3a004d9095..d521d9f4d4943a6ea5e341738a20e2100dadb91b 100644 --- a/src/r_bsp.c +++ b/src/r_bsp.c @@ -15,6 +15,7 @@ #include "g_game.h" #include "r_local.h" #include "r_state.h" +#include "r_portal.h" // Add seg portals #include "r_splats.h" #include "p_local.h" // camera @@ -26,11 +27,11 @@ side_t *sidedef; line_t *linedef; sector_t *frontsector; sector_t *backsector; -boolean portalline; // is curline a portal seg? // very ugly realloc() of drawsegs at run-time, I upped it to 512 // instead of 256.. and someone managed to send me a level with // 896 drawsegs! So too bad here's a limit removal a-la-Boom +drawseg_t *curdrawsegs = NULL; /**< This is used to handle multiple lists for masked drawsegs. */ drawseg_t *drawsegs = NULL; drawseg_t *ds_p = NULL; @@ -459,7 +460,7 @@ static void R_AddLine(seg_t *line) line2 = P_FindSpecialLineFromTag(40, line->linedef->tag, line2); if (line2 >= 0) // found it! { - R_AddPortal(line->linedef-lines, line2, x1, x2); // Remember the lines for later rendering + Portal_Add2Lines(line->linedef-lines, line2, x1, x2); // Remember the lines for later rendering //return; // Don't fill in that space now! goto clipsolid; } @@ -1377,13 +1378,5 @@ void R_RenderBSPNode(INT32 bspnum) bspnum = bsp->children[side^1]; } - // PORTAL CULLING - if (portalcullsector) { - sector_t *sect = subsectors[bspnum & ~NF_SUBSECTOR].sector; - if (sect != portalcullsector) - return; - portalcullsector = NULL; - } - R_Subsector(bspnum == -1 ? 0 : bspnum & ~NF_SUBSECTOR); } diff --git a/src/r_bsp.h b/src/r_bsp.h index e3662e2e6ad23f6c25efed2ceb44f861a2dd15eb..825be6064b078ba0f5c0966b1d726c72e2546c07 100644 --- a/src/r_bsp.h +++ b/src/r_bsp.h @@ -29,6 +29,7 @@ extern boolean portalline; // is curline a portal seg? extern INT32 checkcoord[12][4]; +extern drawseg_t *curdrawsegs; extern drawseg_t *drawsegs; extern drawseg_t *ds_p; extern INT32 doorclosed; @@ -38,7 +39,6 @@ void R_ClearClipSegs(void); void R_PortalClearClipSegs(INT32 start, INT32 end); void R_ClearDrawSegs(void); void R_RenderBSPNode(INT32 bspnum); -void R_AddPortal(INT32 line1, INT32 line2, INT32 x1, INT32 x2); #ifdef POLYOBJECTS void R_SortPolyObjects(subsector_t *sub); diff --git a/src/r_main.c b/src/r_main.c index 23dc39d62f5c31753ee240a237d89d581035df02..273d13a56bb26165b8749f557898ae201009cf63 100644 --- a/src/r_main.c +++ b/src/r_main.c @@ -30,6 +30,7 @@ #include "p_spec.h" // skyboxmo #include "z_zone.h" #include "m_random.h" // quake camera shake +#include "r_portal.h" #ifdef HWRENDER #include "hardware/hw_main.h" @@ -65,37 +66,9 @@ size_t loopcount; fixed_t viewx, viewy, viewz; angle_t viewangle, aimingangle; fixed_t viewcos, viewsin; -boolean viewsky, skyVisible; -boolean skyVisible1, skyVisible2; // saved values of skyVisible for P1 and P2, for splitscreen sector_t *viewsector; player_t *viewplayer; -// PORTALS! -// You can thank and/or curse JTE for these. -UINT8 portalrender; -sector_t *portalcullsector; -typedef struct portal_pair -{ - INT32 line1; - INT32 line2; - UINT8 pass; - struct portal_pair *next; - - fixed_t viewx; - fixed_t viewy; - fixed_t viewz; - angle_t viewangle; - - INT32 start; - INT32 end; - INT16 *ceilingclip; - INT16 *floorclip; - fixed_t *frontscale; -} portal_pair; -portal_pair *portal_base, *portal_cap; -line_t *portalclipline; -INT32 portalclipstart, portalclipend; - // // precalculated math tables // @@ -764,7 +737,7 @@ static void R_SetupFreelook(void) #undef AIMINGTODY -void R_SetupFrame(player_t *player, boolean skybox) +void R_SetupFrame(player_t *player) { camera_t *thiscam; boolean chasecam = false; @@ -794,7 +767,6 @@ void R_SetupFrame(player_t *player, boolean skybox) else if (!chasecam) thiscam->chase = false; - viewsky = !skybox; if (player->awayviewtics) { // cut-away view stuff @@ -883,7 +855,6 @@ void R_SkyboxFrame(player_t *player) thiscam = &camera; // cut-away view stuff - viewsky = true; viewmobj = skyboxmo[0]; #ifdef PARANOIA if (!viewmobj) @@ -1010,17 +981,8 @@ void R_SkyboxFrame(player_t *player) R_SetupFreelook(); } -#define ANGLED_PORTALS - -static void R_PortalFrame(line_t *start, line_t *dest, portal_pair *portal) +static void R_PortalFrame(portal_t *portal) { - vertex_t dest_c, start_c; -#ifdef ANGLED_PORTALS - // delta angle - angle_t dangle = R_PointToAngle2(0,0,dest->dx,dest->dy) - R_PointToAngle2(start->dx,start->dy,0,0); -#endif - - //R_SetupFrame(player, false); viewx = portal->viewx; viewy = portal->viewy; viewz = portal->viewz; @@ -1029,94 +991,35 @@ static void R_PortalFrame(line_t *start, line_t *dest, portal_pair *portal) viewsin = FINESINE(viewangle>>ANGLETOFINESHIFT); viewcos = FINECOSINE(viewangle>>ANGLETOFINESHIFT); - portalcullsector = dest->frontsector; - viewsector = dest->frontsector; - portalclipline = dest; portalclipstart = portal->start; portalclipend = portal->end; - // Offset the portal view by the linedef centers - - // looking glass center - start_c.x = (start->v1->x + start->v2->x) / 2; - start_c.y = (start->v1->y + start->v2->y) / 2; - - // other side center - dest_c.x = (dest->v1->x + dest->v2->x) / 2; - dest_c.y = (dest->v1->y + dest->v2->y) / 2; - - // Heights! - viewz += dest->frontsector->floorheight - start->frontsector->floorheight; - - // calculate the difference in position and rotation! -#ifdef ANGLED_PORTALS - if (dangle == 0) -#endif - { // the entrance goes straight opposite the exit, so we just need to mess with the offset. - viewx += dest_c.x - start_c.x; - viewy += dest_c.y - start_c.y; - return; + if (portal->clipline != -1) + { + portalclipline = &lines[portal->clipline]; + viewsector = portalclipline->frontsector; } - -#ifdef ANGLED_PORTALS - viewangle += dangle; - viewsin = FINESINE(viewangle>>ANGLETOFINESHIFT); - viewcos = FINECOSINE(viewangle>>ANGLETOFINESHIFT); - //CONS_Printf("dangle == %u\n", AngleFixed(dangle)>>FRACBITS); - - // ???? + else { - fixed_t disttopoint; - angle_t angtopoint; - - disttopoint = R_PointToDist2(start_c.x, start_c.y, viewx, viewy); - angtopoint = R_PointToAngle2(start_c.x, start_c.y, viewx, viewy); - angtopoint += dangle; - - viewx = dest_c.x+FixedMul(FINECOSINE(angtopoint>>ANGLETOFINESHIFT), disttopoint); - viewy = dest_c.y+FixedMul(FINESINE(angtopoint>>ANGLETOFINESHIFT), disttopoint); + portalclipline = NULL; + viewsector = R_PointInSubsector(viewx, viewy)->sector; } -#endif } -void R_AddPortal(INT32 line1, INT32 line2, INT32 x1, INT32 x2) +static void Mask_Pre (maskcount_t* m) { - portal_pair *portal = Z_Malloc(sizeof(portal_pair), PU_LEVEL, NULL); - INT16 *ceilingclipsave = Z_Malloc(sizeof(INT16)*(x2-x1), PU_LEVEL, NULL); - INT16 *floorclipsave = Z_Malloc(sizeof(INT16)*(x2-x1), PU_LEVEL, NULL); - fixed_t *frontscalesave = Z_Malloc(sizeof(fixed_t)*(x2-x1), PU_LEVEL, NULL); - - portal->line1 = line1; - portal->line2 = line2; - portal->pass = portalrender+1; - portal->next = NULL; - - R_PortalStoreClipValues(x1, x2, ceilingclipsave, floorclipsave, frontscalesave); - - portal->ceilingclip = ceilingclipsave; - portal->floorclip = floorclipsave; - portal->frontscale = frontscalesave; - - portal->start = x1; - portal->end = x2; - - portalline = true; // this tells R_StoreWallRange that curline is a portal seg - - portal->viewx = viewx; - portal->viewy = viewy; - portal->viewz = viewz; - portal->viewangle = viewangle; + m->drawsegs[0] = ds_p - drawsegs; + m->vissprites[0] = visspritecount; + m->viewx = viewx; + m->viewy = viewy; + m->viewz = viewz; + m->viewsector = viewsector; +} - if (!portal_base) - { - portal_base = portal; - portal_cap = portal; - } - else - { - portal_cap->next = portal; - portal_cap = portal; - } +static void Mask_Post (maskcount_t* m) +{ + m->drawsegs[1] = ds_p - drawsegs; + m->vissprites[1] = visspritecount; } // ================ @@ -1131,8 +1034,8 @@ void R_AddPortal(INT32 line1, INT32 line2, INT32 x1, INT32 x2) void R_RenderPlayerView(player_t *player) { - portal_pair *portal; - const boolean skybox = (skyboxmo[0] && cv_skybox.value); + UINT8 nummasks = 1; + maskcount_t* masks = malloc(sizeof(maskcount_t)); if (cv_homremoval.value && player == &players[displayplayer]) // if this is display player 1 { @@ -1142,38 +1045,7 @@ void R_RenderPlayerView(player_t *player) V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 32+(timeinmap&15)); } - // load previous saved value of skyVisible for the player - if (splitscreen && player == &players[secondarydisplayplayer]) - skyVisible = skyVisible2; - else - skyVisible = skyVisible1; - - portalrender = 0; - portal_base = portal_cap = NULL; - - if (skybox && skyVisible) - { - R_SkyboxFrame(player); - - R_ClearClipSegs(); - R_ClearDrawSegs(); - R_ClearPlanes(); - R_ClearSprites(); -#ifdef FLOORSPLATS - R_ClearVisibleFloorSplats(); -#endif - - R_RenderBSPNode((INT32)numnodes - 1); - R_ClipSprites(); - R_DrawPlanes(); -#ifdef FLOORSPLATS - R_DrawVisibleFloorSplats(); -#endif - R_DrawMasked(); - } - - R_SetupFrame(player, skybox); - skyVisible = false; + R_SetupFrame(player); framecount++; validcount++; @@ -1185,19 +1057,21 @@ void R_RenderPlayerView(player_t *player) #ifdef FLOORSPLATS R_ClearVisibleFloorSplats(); #endif + Portal_InitList(); // check for new console commands. NetUpdate(); // The head node is the last node output. + Mask_Pre(&masks[nummasks - 1]); + curdrawsegs = ds_p; //profile stuff --------------------------------------------------------- #ifdef TIMING mytotal = 0; ProfZeroTimer(); #endif R_RenderBSPNode((INT32)numnodes - 1); - R_ClipSprites(); #ifdef TIMING RDMSR(0x10, &mycount); mytotal += mycount; // 64bit add @@ -1205,54 +1079,66 @@ void R_RenderPlayerView(player_t *player) CONS_Debug(DBG_RENDER, "RenderBSPNode: 0x%d %d\n", *((INT32 *)&mytotal + 1), (INT32)mytotal); #endif //profile stuff --------------------------------------------------------- + Mask_Post(&masks[nummasks - 1]); + + R_ClipSprites(drawsegs, NULL); + + + // Add skybox portals caused by sky visplanes. + if (cv_skybox.value && skyboxmo[0]) + Portal_AddSkyboxPortals(); - // PORTAL RENDERING - for(portal = portal_base; portal; portal = portal_base) + // Portal rendering. Hijacks the BSP traversal. + if (portal_base) { - // render the portal - CONS_Debug(DBG_RENDER, "Rendering portal from line %d to %d\n", portal->line1, portal->line2); - portalrender = portal->pass; + portal_t *portal; + + for(portal = portal_base; portal; portal = portal_base) + { + portalrender = portal->pass; // Recursiveness depth. + + R_ClearFFloorClips(); + + // Apply the viewpoint stored for the portal. + R_PortalFrame(portal); - R_PortalFrame(&lines[portal->line1], &lines[portal->line2], portal); + // Hack in the clipsegs to delimit the starting + // clipping for sprites and possibly other similar + // future items. + R_PortalClearClipSegs(portal->start, portal->end); - R_PortalClearClipSegs(portal->start, portal->end); + // Hack in the top/bottom clip values for the window + // that were previously stored. + Portal_ClipApply(portal); - R_PortalRestoreClipValues(portal->start, portal->end, portal->ceilingclip, portal->floorclip, portal->frontscale); + validcount++; - validcount++; + masks = realloc(masks, (++nummasks)*sizeof(maskcount_t)); - R_RenderBSPNode((INT32)numnodes - 1); - R_ClipSprites(); - //R_DrawPlanes(); - //R_DrawMasked(); + Mask_Pre(&masks[nummasks - 1]); + curdrawsegs = ds_p; - // okay done. free it. - portalcullsector = NULL; // Just in case... - portal_base = portal->next; - Z_Free(portal->ceilingclip); - Z_Free(portal->floorclip); - Z_Free(portal->frontscale); - Z_Free(portal); + // Render the BSP from the new viewpoint, and clip + // any sprites with the new clipsegs and window. + R_RenderBSPNode((INT32)numnodes - 1); + Mask_Post(&masks[nummasks - 1]); + + R_ClipSprites(ds_p - (masks[nummasks - 1].drawsegs[1] - masks[nummasks - 1].drawsegs[0]), portal); + + Portal_Remove(portal); + } } - // END PORTAL RENDERING R_DrawPlanes(); #ifdef FLOORSPLATS R_DrawVisibleFloorSplats(); #endif + // draw mid texture and sprite // And now 3D floors/sides! - R_DrawMasked(); + R_DrawMasked(masks, nummasks); - // Check for new console commands. - NetUpdate(); - - // save value to skyVisible1 or skyVisible2 - // this is so that P1 can't affect whether P2 can see a skybox or not, or vice versa - if (splitscreen && player == &players[secondarydisplayplayer]) - skyVisible2 = skyVisible; - else - skyVisible1 = skyVisible; + free(masks); } // ========================================================================= diff --git a/src/r_main.h b/src/r_main.h index 6ae5aa221667569b4b59987b37c4002219958f0c..1d82a01b961bbcd91952abd8a8191fcc4f5dd310 100644 --- a/src/r_main.h +++ b/src/r_main.h @@ -94,7 +94,7 @@ void R_ExecuteSetViewSize(void); void R_SkyboxFrame(player_t *player); -void R_SetupFrame(player_t *player, boolean skybox); +void R_SetupFrame(player_t *player); // Called by G_Drawer. void R_RenderPlayerView(player_t *player); diff --git a/src/r_plane.c b/src/r_plane.c index 0ef4c2c05bd9f579af6c5269f91cad68f3c68230..2f6f97240a0418f3608d1901a8406b80716cf10f 100644 --- a/src/r_plane.c +++ b/src/r_plane.c @@ -23,6 +23,8 @@ #include "r_state.h" #include "r_splats.h" // faB(21jan):testing #include "r_sky.h" +#include "r_portal.h" + #include "v_video.h" #include "w_wad.h" #include "z_zone.h" @@ -43,9 +45,8 @@ //#define QUINCUNX //SoM: 3/23/2000: Use Boom visplane hashing. -#define MAXVISPLANES 512 -static visplane_t *visplanes[MAXVISPLANES]; +visplane_t *visplanes[MAXVISPLANES]; static visplane_t *freetail; static visplane_t **freehead = &freetail; @@ -112,50 +113,6 @@ void R_InitPlanes(void) // FIXME: unused } -// R_PortalStoreClipValues -// Saves clipping values for later. -Red -void R_PortalStoreClipValues(INT32 start, INT32 end, INT16 *ceil, INT16 *floor, fixed_t *scale) -{ - INT32 i; - for (i = 0; i < end-start; i++) - { - *ceil = ceilingclip[start+i]; - ceil++; - *floor = floorclip[start+i]; - floor++; - *scale = frontscale[start+i]; - scale++; - } -} - -// R_PortalRestoreClipValues -// Inverse of the above. Restores the old value! -void R_PortalRestoreClipValues(INT32 start, INT32 end, INT16 *ceil, INT16 *floor, fixed_t *scale) -{ - INT32 i; - for (i = 0; i < end-start; i++) - { - ceilingclip[start+i] = *ceil; - ceil++; - floorclip[start+i] = *floor; - floor++; - frontscale[start+i] = *scale; - scale++; - } - - // HACKS FOLLOW - for (i = 0; i < start; i++) - { - floorclip[i] = -1; - ceilingclip[i] = (INT16)viewheight; - } - for (i = end; i < vid.width; i++) - { - floorclip[i] = -1; - ceilingclip[i] = (INT16)viewheight; - } -} - // // R_MapPlane // @@ -348,6 +305,23 @@ void R_MapPlane(INT32 y, INT32 x1, INT32 x2) #endif } +void R_ClearFFloorClips (void) +{ + INT32 i, p; + + // opening / clipping determination + for (i = 0; i < viewwidth; i++) + { + for (p = 0; p < MAXFFLOORS; p++) + { + ffloor[p].f_clip[i] = (INT16)viewheight; + ffloor[p].c_clip[i] = -1; + } + } + + numffloors = 0; +} + // // R_ClearPlanes // At begining of frame. @@ -370,8 +344,6 @@ void R_ClearPlanes(void) } } - numffloors = 0; - for (i = 0; i < MAXVISPLANES; i++) for (*freehead = visplanes[i], visplanes[i] = NULL; freehead && *freehead ;) @@ -723,16 +695,6 @@ static void R_DrawSkyPlane(visplane_t *pl) INT32 x; INT32 angle; - // If we're not supposed to draw the sky (e.g. for skyboxes), don't do anything! - // This probably utterly ruins sky rendering for FOFs and polyobjects, unfortunately - if (!viewsky) - { - // Mark that the sky was visible here for next tic - // (note: this is a hack and it sometimes can cause HOMs to appear for a tic IIRC) - skyVisible = true; - return; - } - // Reset column drawer function (note: couldn't we just call walldrawerfunc directly?) // (that is, unless we'll need to switch drawers in future for some reason) wallcolfunc = walldrawerfunc; diff --git a/src/r_plane.h b/src/r_plane.h index 6e6a6d49d0522a6aa6b0d9facd35754f5744af14..238fde1827846f0be8278f6ee6a78e21aaf2c52b 100644 --- a/src/r_plane.h +++ b/src/r_plane.h @@ -18,6 +18,8 @@ #include "r_data.h" #include "p_polyobj.h" +#define MAXVISPLANES 512 + // // Now what is a visplane, anyway? // Simple: kinda floor/ceiling polygon optimised for SRB2 rendering. @@ -53,6 +55,7 @@ typedef struct visplane_s #endif } visplane_t; +extern visplane_t *visplanes[MAXVISPLANES]; extern visplane_t *floorplane; extern visplane_t *ceilingplane; @@ -72,9 +75,8 @@ extern fixed_t *yslope; extern lighttable_t **planezlight; void R_InitPlanes(void); -void R_PortalStoreClipValues(INT32 start, INT32 end, INT16 *ceil, INT16 *floor, fixed_t *scale); -void R_PortalRestoreClipValues(INT32 start, INT32 end, INT16 *ceil, INT16 *floor, fixed_t *scale); void R_ClearPlanes(void); +void R_ClearFFloorClips (void); void R_MapPlane(INT32 y, INT32 x1, INT32 x2); void R_MakeSpans(INT32 x, INT32 t1, INT32 b1, INT32 t2, INT32 b2); @@ -122,4 +124,6 @@ typedef struct planemgr_s extern visffloor_t ffloor[MAXFFLOORS]; extern INT32 numffloors; + +void Portal_AddSkyboxPortals (void); #endif diff --git a/src/r_portal.c b/src/r_portal.c new file mode 100644 index 0000000000000000000000000000000000000000..ea24cd91c49b420df663e847cdbebb651a3f36db --- /dev/null +++ b/src/r_portal.c @@ -0,0 +1,333 @@ +// SONIC ROBO BLAST 2 +//----------------------------------------------------------------------------- +// Copyright (C) 1993-1996 by id Software, Inc. +// Copyright (C) 1998-2000 by DooM Legacy Team. +// Copyright (C) 1999-2018 by Sonic Team Junior. +// +// This program is free software distributed under the +// terms of the GNU General Public License, version 2. +// See the 'LICENSE' file for more details. +//----------------------------------------------------------------------------- +/// \file r_portal.c +/// \brief Software renderer portals. + +#include "r_portal.h" +#include "r_plane.h" +#include "r_main.h" +#include "doomstat.h" +#include "p_spec.h" // Skybox viewpoints +#include "z_zone.h" +#include "r_things.h" +#include "r_sky.h" + +UINT8 portalrender; /**< When rendering a portal, it establishes the depth of the current BSP traversal. */ + +// Linked list for portals. +portal_t *portal_base, *portal_cap; + +line_t *portalclipline; +INT32 portalclipstart, portalclipend; + +boolean portalline; // is curline a portal seg? + +void Portal_InitList (void) +{ + portalrender = 0; + portal_base = portal_cap = NULL; +} + +/** Store the clipping window for a portal in its given range. + * + * The window is copied from the current window at the time + * the function is called, so it is useful for converting one-sided + * lines into portals. + */ +void Portal_ClipRange (portal_t* portal) +{ + INT32 start = portal->start; + INT32 end = portal->end; + INT16 *ceil = portal->ceilingclip; + INT16 *floor = portal->floorclip; + fixed_t *scale = portal->frontscale; + + INT32 i; + for (i = 0; i < end-start; i++) + { + *ceil = ceilingclip[start+i]; + ceil++; + *floor = floorclip[start+i]; + floor++; + *scale = frontscale[start+i]; + scale++; + } +} + +/** Apply the clipping window from a portal. + */ +void Portal_ClipApply (const portal_t* portal) +{ + INT32 i; + INT32 start = portal->start; + INT32 end = portal->end; + INT16 *ceil = portal->ceilingclip; + INT16 *floor = portal->floorclip; + fixed_t *scale = portal->frontscale; + + for (i = 0; i < end-start; i++) + { + ceilingclip[start+i] = *ceil; + ceil++; + floorclip[start+i] = *floor; + floor++; + frontscale[start+i] = *scale; + scale++; + } + + // HACKS FOLLOW + for (i = 0; i < start; i++) + { + floorclip[i] = -1; + ceilingclip[i] = (INT16)viewheight; + } + for (i = end; i < vid.width; i++) + { + floorclip[i] = -1; + ceilingclip[i] = (INT16)viewheight; + } +} + +static portal_t* Portal_Add (const INT16 x1, const INT16 x2) +{ + portal_t *portal = Z_Malloc(sizeof(portal_t), PU_LEVEL, NULL); + INT16 *ceilingclipsave = Z_Malloc(sizeof(INT16)*(x2-x1 + 1), PU_LEVEL, NULL); + INT16 *floorclipsave = Z_Malloc(sizeof(INT16)*(x2-x1 + 1), PU_LEVEL, NULL); + fixed_t *frontscalesave = Z_Malloc(sizeof(fixed_t)*(x2-x1 + 1), PU_LEVEL, NULL); + + // Linked list. + if (!portal_base) + { + portal_base = portal; + portal_cap = portal; + } + else + { + portal_cap->next = portal; + portal_cap = portal; + } + portal->next = NULL; + + // Store clipping values so they can be restored once the portal is rendered. + portal->ceilingclip = ceilingclipsave; + portal->floorclip = floorclipsave; + portal->frontscale = frontscalesave; + portal->start = x1; + portal->end = x2; + + // Increase recursion level. + portal->pass = portalrender+1; + + return portal; +} + +void Portal_Remove (portal_t* portal) +{ + portal_base = portal->next; + Z_Free(portal->ceilingclip); + Z_Free(portal->floorclip); + Z_Free(portal->frontscale); + Z_Free(portal); +} + +/** Creates a portal out of two lines and a determined screen range. + * + * line1 determines the entrance, and line2 the exit. + * x1 and x2 determine the screen's column bounds. + + * The view's offset from the entry line center is obtained, + * and then rotated&translated to the exit line's center. + * When the portal renders, it will create the illusion of + * the two lines being seamed together. + */ +void Portal_Add2Lines (const INT32 line1, const INT32 line2, const INT32 x1, const INT32 x2) +{ + portal_t* portal = Portal_Add(x1, x2); + + // Offset the portal view by the linedef centers + line_t* start = &lines[line1]; + line_t* dest = &lines[line2]; + + angle_t dangle = R_PointToAngle2(0,0,dest->dx,dest->dy) - R_PointToAngle2(start->dx,start->dy,0,0); + + fixed_t disttopoint; + angle_t angtopoint; + + vertex_t dest_c, start_c; + + // looking glass center + start_c.x = (start->v1->x + start->v2->x) / 2; + start_c.y = (start->v1->y + start->v2->y) / 2; + + // other side center + dest_c.x = (dest->v1->x + dest->v2->x) / 2; + dest_c.y = (dest->v1->y + dest->v2->y) / 2; + + disttopoint = R_PointToDist2(start_c.x, start_c.y, viewx, viewy); + angtopoint = R_PointToAngle2(start_c.x, start_c.y, viewx, viewy); + angtopoint += dangle; + + portal->viewx = dest_c.x + FixedMul(FINECOSINE(angtopoint>>ANGLETOFINESHIFT), disttopoint); + portal->viewy = dest_c.y + FixedMul(FINESINE(angtopoint>>ANGLETOFINESHIFT), disttopoint); + portal->viewz = viewz + dest->frontsector->floorheight - start->frontsector->floorheight; + portal->viewangle = viewangle + dangle; + + portal->clipline = line2; + + Portal_ClipRange(portal); + + portalline = true; // this tells R_StoreWallRange that curline is a portal seg +} + +/** Store the clipping window for a portal using a visplane. + * + * Since visplanes top/bottom windows work in an identical way, + * it can just be copied almost directly. + */ +static void Portal_ClipVisplane (const visplane_t* plane, portal_t* portal) +{ + INT16 start = portal->start; + INT16 end = portal->end; + INT32 i; + + for (i = 0; i < end - start; i++) + { + // Invalid column. + if (plane->top[i + start] == 65535) + { + portal->ceilingclip[i] = -1; + portal->floorclip[i] = -1; + continue; + } + portal->ceilingclip[i] = plane->top[i + start] - 1; + portal->floorclip[i] = plane->bottom[i + start] + 1; + portal->frontscale[i] = INT32_MAX; + } +} + +extern INT32 viewwidth; + +static boolean TrimVisplaneBounds (const visplane_t* plane, INT16* start, INT16* end) +{ + *start = plane->minx; + *end = plane->maxx + 1; + + // Visplanes have 1-px pads on their sides (extra columns). + // Trim them, else it may render out of bounds. + if (*end > viewwidth) + *end = viewwidth; + + if (!(*start < *end)) + return true; + + + /** Trims a visplane's horizontal gap to match its render area. + * + * Visplanes' minx/maxx may sometimes exceed the area they're + * covering. This merely adjusts the boundaries to the next + * valid area. + */ + + while (plane->bottom[*start] == 0 && plane->top[*start] == 65535 && *start < *end) + { + (*start)++; + } + + + while (plane->bottom[*end - 1] == 0 && plane->top[*start] == 65535 && *end > *start) + { + (*end)--; + } + + return false; +} + +/** Creates a skybox portal out of a visplane. + * + * Applies the necessary offsets and rotation to give + * a depth illusion to the skybox. + */ +void Portal_AddSkybox (const visplane_t* plane) +{ + INT16 start, end; + mapheader_t *mh; + portal_t* portal; + + if (TrimVisplaneBounds(plane, &start, &end)) + return; + + portal = Portal_Add(start, end); + + Portal_ClipVisplane(plane, portal); + + portal->viewx = skyboxmo[0]->x; + portal->viewy = skyboxmo[0]->y; + portal->viewz = skyboxmo[0]->z; + portal->viewangle = viewangle + skyboxmo[0]->angle; + + mh = mapheaderinfo[gamemap-1]; + + // If a relative viewpoint exists, offset the viewpoint. + if (skyboxmo[1]) + { + fixed_t x = 0, y = 0; + angle_t ang = skyboxmo[0]->angle>>ANGLETOFINESHIFT; + + if (mh->skybox_scalex > 0) + x = (viewx - skyboxmo[1]->x) / mh->skybox_scalex; + else if (mh->skybox_scalex < 0) + x = (viewx - skyboxmo[1]->x) * -mh->skybox_scalex; + + if (mh->skybox_scaley > 0) + y = (viewy - skyboxmo[1]->y) / mh->skybox_scaley; + else if (mh->skybox_scaley < 0) + y = (viewy - skyboxmo[1]->y) * -mh->skybox_scaley; + + // Apply transform to account for the skybox viewport angle. + portal->viewx += FixedMul(x,FINECOSINE(ang)) - FixedMul(y, FINESINE(ang)); + portal->viewy += FixedMul(x, FINESINE(ang)) + FixedMul(y,FINECOSINE(ang)); + } + + if (mh->skybox_scalez > 0) + portal->viewz += viewz / mh->skybox_scalez; + else if (mh->skybox_scalez < 0) + portal->viewz += viewz * -mh->skybox_scalez; + + portal->clipline = -1; +} + +/** Creates portals for the currently existing sky visplanes. + * The visplanes are also removed and cleared from the list. + */ +void Portal_AddSkyboxPortals (void) +{ + visplane_t *pl; + INT32 i; + UINT16 count = 0; + + for (i = 0; i < MAXVISPLANES; i++, pl++) + { + for (pl = visplanes[i]; pl; pl = pl->next) + { + if (pl->picnum == skyflatnum) + { + Portal_AddSkybox(pl); + + pl->minx = 0; + pl->maxx = -1; + + count++; + } + } + } + + CONS_Debug(DBG_RENDER, "Skybox portals: %d\n", count); +} diff --git a/src/r_portal.h b/src/r_portal.h new file mode 100644 index 0000000000000000000000000000000000000000..e8f9119e84a6eddc41e2bf651cf1ac408772bc2d --- /dev/null +++ b/src/r_portal.h @@ -0,0 +1,59 @@ +// SONIC ROBO BLAST 2 +//----------------------------------------------------------------------------- +// Copyright (C) 1993-1996 by id Software, Inc. +// Copyright (C) 1998-2000 by DooM Legacy Team. +// Copyright (C) 1999-2018 by Sonic Team Junior. +// +// This program is free software distributed under the +// terms of the GNU General Public License, version 2. +// See the 'LICENSE' file for more details. +//----------------------------------------------------------------------------- +/// \file r_portal.h +/// \brief Software renderer portal struct, functions, linked list extern. + +#ifndef __R_PORTAL__ +#define __R_PORTAL__ + +#include "r_data.h" +#include "r_plane.h" // visplanes + +/** Portal structure for the software renderer. + */ +typedef struct portal_s +{ + struct portal_s *next; + + // Viewport. + fixed_t viewx; + fixed_t viewy; + fixed_t viewz; + angle_t viewangle; + + UINT8 pass; /**< Keeps track of the portal's recursion depth. */ + INT32 clipline; /**< Optional clipline for line-based portals. */ + + // Clipping information. + INT32 start; /**< First horizontal pixel coordinate to draw at. */ + INT32 end; /**< Last horizontal pixel coordinate to draw at. */ + INT16 *ceilingclip; /**< Temporary screen top clipping array. */ + INT16 *floorclip; /**< Temporary screen bottom clipping array. */ + fixed_t *frontscale;/**< Temporary screen bottom clipping array. */ +} portal_t; + +extern portal_t* portal_base; +extern portal_t* portal_cap; +extern UINT8 portalrender; + +extern line_t *portalclipline; +extern INT32 portalclipstart, portalclipend; + +void Portal_InitList (void); +void Portal_Remove (portal_t* portal); +void Portal_Add2Lines (const INT32 line1, const INT32 line2, const INT32 x1, const INT32 x2); +void Portal_AddSkybox (const visplane_t* plane); + +void Portal_ClipRange (portal_t* portal); +void Portal_ClipApply (const portal_t* portal); + +void Portal_AddSkyboxPortals (void); +#endif diff --git a/src/r_segs.c b/src/r_segs.c index 03c5fb6e53fd0cc370e441bdcd0ea5c953c14823..6eb81ce7a4a64a78a3cda0765bd64149fc0eb280 100644 --- a/src/r_segs.c +++ b/src/r_segs.c @@ -15,6 +15,7 @@ #include "r_local.h" #include "r_sky.h" +#include "r_portal.h" #include "r_splats.h" #include "w_wad.h" @@ -1737,6 +1738,7 @@ void R_StoreWallRange(INT32 start, INT32 stop) if (ds_p == drawsegs+maxdrawsegs) { + size_t curpos = curdrawsegs - drawsegs; size_t pos = ds_p - drawsegs; size_t newmax = maxdrawsegs ? maxdrawsegs*2 : 128; if (firstseg) @@ -1744,6 +1746,7 @@ void R_StoreWallRange(INT32 start, INT32 stop) drawsegs = Z_Realloc(drawsegs, newmax*sizeof (*drawsegs), PU_STATIC, NULL); ds_p = drawsegs + pos; maxdrawsegs = newmax; + curdrawsegs = drawsegs + curpos; if (firstseg) firstseg = drawsegs + (size_t)firstseg; } diff --git a/src/r_state.h b/src/r_state.h index 9c8ce51d6841fd487b97e10a31be682c9893fcc2..da9425bdf0405160810e7102a4d53ce1241eb881 100644 --- a/src/r_state.h +++ b/src/r_state.h @@ -80,14 +80,8 @@ extern side_t *sides; // extern fixed_t viewx, viewy, viewz; extern angle_t viewangle, aimingangle; -extern boolean viewsky, skyVisible; -extern boolean skyVisible1, skyVisible2; // saved values of skyVisible for P1 and P2, for splitscreen extern sector_t *viewsector; extern player_t *viewplayer; -extern UINT8 portalrender; -extern sector_t *portalcullsector; -extern line_t *portalclipline; -extern INT32 portalclipstart, portalclipend; extern consvar_t cv_allowmlook; extern consvar_t cv_maxportals; diff --git a/src/r_things.c b/src/r_things.c index e8d679b5397704fb3a5c95d9e805ae2c43247e4d..f5482683fd8c312a6dbce63c92c721ef55687521 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -24,6 +24,7 @@ #include "i_video.h" // rendermode #include "r_things.h" #include "r_plane.h" +#include "r_portal.h" #include "p_tick.h" #include "p_local.h" #include "p_slopes.h" @@ -444,7 +445,7 @@ void R_AddSpriteDefs(UINT16 wadnum) // // GAME FUNCTIONS // -static UINT32 visspritecount; +UINT32 visspritecount; static UINT32 clippedvissprites; static vissprite_t *visspritechunks[MAXVISSPRITES >> VISSPRITECHUNKBITS] = {NULL}; @@ -1249,7 +1250,7 @@ static void R_ProjectSprite(mobj_t *thing) } // PORTAL SPRITE CLIPPING - if (portalrender) + if (portalrender && portalclipline) { if (x2 < portalclipstart || x1 > portalclipend) return; @@ -1351,8 +1352,8 @@ static void R_ProjectSprite(mobj_t *thing) { if (vis->x1 < portalclipstart) vis->x1 = portalclipstart; - if (vis->x2 > portalclipend) - vis->x2 = portalclipend; + if (vis->x2 >= portalclipend) + vis->x2 = portalclipend-1; } vis->xscale = xscale; //SoM: 4/17/2000 @@ -1517,7 +1518,7 @@ static void R_ProjectPrecipitationSprite(precipmobj_t *thing) return; // PORTAL SPRITE CLIPPING - if (portalrender) + if (portalrender && portalclipline) { if (x2 < portalclipstart || x1 > portalclipend) return; @@ -1569,8 +1570,8 @@ static void R_ProjectPrecipitationSprite(precipmobj_t *thing) { if (vis->x1 < portalclipstart) vis->x1 = portalclipstart; - if (vis->x2 > portalclipend) - vis->x2 = portalclipend; + if (vis->x2 >= portalclipend) + vis->x2 = portalclipend-1; } vis->xscale = xscale; //SoM: 4/17/2000 @@ -1696,9 +1697,7 @@ void R_AddSprites(sector_t *sec, INT32 lightlevel) // // R_SortVisSprites // -static vissprite_t vsprsortedhead; - -void R_SortVisSprites(void) +static void R_SortVisSprites(vissprite_t* vsprsortedhead, UINT32 start, UINT32 end) { UINT32 i, linkedvissprites = 0; vissprite_t *ds, *dsprev, *dsnext, *dsfirst; @@ -1707,20 +1706,17 @@ void R_SortVisSprites(void) fixed_t bestscale; INT32 bestdispoffset; - if (!visspritecount) - return; - unsorted.next = unsorted.prev = &unsorted; - dsfirst = R_GetVisSprite(0); + dsfirst = R_GetVisSprite(start); // The first's prev and last's next will be set to // nonsense, but are fixed in a moment - for (i = 0, dsnext = dsfirst, ds = NULL; i < visspritecount; i++) + for (i = start, dsnext = dsfirst, ds = NULL; i < end; i++) { dsprev = ds; ds = dsnext; - if (i < visspritecount - 1) dsnext = R_GetVisSprite(i + 1); + if (i < end - 1) dsnext = R_GetVisSprite(i + 1); ds->next = dsnext; ds->prev = dsprev; @@ -1798,8 +1794,8 @@ void R_SortVisSprites(void) } // pull the vissprites out by scale - vsprsortedhead.next = vsprsortedhead.prev = &vsprsortedhead; - for (i = 0; i < visspritecount-linkedvissprites; i++) + vsprsortedhead->next = vsprsortedhead->prev = vsprsortedhead; + for (i = start; i < end-linkedvissprites; i++) { bestscale = bestdispoffset = INT32_MAX; for (ds = unsorted.next; ds != &unsorted; ds = ds->next) @@ -1824,10 +1820,10 @@ void R_SortVisSprites(void) } best->next->prev = best->prev; best->prev->next = best->next; - best->next = &vsprsortedhead; - best->prev = vsprsortedhead.prev; - vsprsortedhead.prev->next = best; - vsprsortedhead.prev = best; + best->next = vsprsortedhead; + best->prev = vsprsortedhead->prev; + vsprsortedhead->prev->next = best; + vsprsortedhead->prev = best; } } @@ -1837,28 +1833,28 @@ void R_SortVisSprites(void) static drawnode_t *R_CreateDrawNode(drawnode_t *link); static drawnode_t nodebankhead; -static drawnode_t nodehead; -static void R_CreateDrawNodes(void) +static void R_CreateDrawNodes(maskcount_t* mask, drawnode_t* head, boolean tempskip) { drawnode_t *entry; drawseg_t *ds; INT32 i, p, best, x1, x2; fixed_t bestdelta, delta; vissprite_t *rover; + static vissprite_t vsprsortedhead; drawnode_t *r2; visplane_t *plane; INT32 sintersect; fixed_t scale = 0; // Add the 3D floors, thicksides, and masked textures... - for (ds = ds_p; ds-- > drawsegs ;) + for (ds = drawsegs + mask->drawsegs[1]; ds-- > drawsegs + mask->drawsegs[0];) { if (ds->numthicksides) { for (i = 0; i < ds->numthicksides; i++) { - entry = R_CreateDrawNode(&nodehead); + entry = R_CreateDrawNode(head); entry->thickseg = ds; entry->ffloor = ds->thicksides[i]; } @@ -1873,7 +1869,7 @@ static void R_CreateDrawNodes(void) ; else { // Put it in! - entry = R_CreateDrawNode(&nodehead); + entry = R_CreateDrawNode(head); entry->plane = plane; entry->seg = ds; } @@ -1882,7 +1878,7 @@ static void R_CreateDrawNodes(void) #endif if (ds->maskedtexturecol) { - entry = R_CreateDrawNode(&nodehead); + entry = R_CreateDrawNode(head); entry->seg = ds; } if (ds->numffloorplanes) @@ -1913,7 +1909,7 @@ static void R_CreateDrawNodes(void) } if (best != -1) { - entry = R_CreateDrawNode(&nodehead); + entry = R_CreateDrawNode(head); entry->plane = ds->ffloorplanes[best]; entry->seg = ds; ds->ffloorplanes[best] = NULL; @@ -1924,6 +1920,9 @@ static void R_CreateDrawNodes(void) } } + if (tempskip) + return; + #ifdef POLYOBJECTS_PLANES // find all the remaining polyobject planes and add them on the end of the list // probably this is a terrible idea if we wanted them to be sorted properly @@ -1940,17 +1939,19 @@ static void R_CreateDrawNodes(void) PolyObjects[i].visplane = NULL; continue; } - entry = R_CreateDrawNode(&nodehead); + entry = R_CreateDrawNode(head); entry->plane = plane; // note: no seg is set, for what should be obvious reasons PolyObjects[i].visplane = NULL; } #endif - if (visspritecount == 0) + // No vissprites in this mask? + if (mask->vissprites[1] - mask->vissprites[0] == 0) return; - R_SortVisSprites(); + R_SortVisSprites(&vsprsortedhead, mask->vissprites[0], mask->vissprites[1]); + for (rover = vsprsortedhead.prev; rover != &vsprsortedhead; rover = rover->prev) { if (rover->szt > vid.height || rover->sz < 0) @@ -1958,7 +1959,7 @@ static void R_CreateDrawNodes(void) sintersect = (rover->x1 + rover->x2) / 2; - for (r2 = nodehead.next; r2 != &nodehead; r2 = r2->next) + for (r2 = head->next; r2 != head; r2 = r2->next) { if (r2->plane) { @@ -2097,9 +2098,9 @@ static void R_CreateDrawNodes(void) } } } - if (r2 == &nodehead) + if (r2 == head) { - entry = R_CreateDrawNode(&nodehead); + entry = R_CreateDrawNode(head); entry->sprite = rover; } } @@ -2141,25 +2142,24 @@ static void R_DoneWithNode(drawnode_t *node) (node->prev = &nodebankhead)->next = node; } -static void R_ClearDrawNodes(void) +static void R_ClearDrawNodes(drawnode_t* head) { drawnode_t *rover; drawnode_t *next; - for (rover = nodehead.next; rover != &nodehead ;) + for (rover = head->next; rover != head;) { next = rover->next; R_DoneWithNode(rover); rover = next; } - nodehead.next = nodehead.prev = &nodehead; + head->next = head->prev = head; } void R_InitDrawNodes(void) { nodebankhead.next = nodebankhead.prev = &nodebankhead; - nodehead.next = nodehead.prev = &nodehead; } // @@ -2185,7 +2185,7 @@ static void R_DrawPrecipitationSprite(vissprite_t *spr) // R_ClipSprites // Clips vissprites without drawing, so that portals can work. -Red -void R_ClipSprites(void) +void R_ClipSprites(drawseg_t* dsstart, portal_t* portal) { vissprite_t *spr; for (; clippedvissprites < visspritecount; clippedvissprites++) @@ -2211,7 +2211,7 @@ void R_ClipSprites(void) // and buggy, by going past LEFT end of array: // for (ds = ds_p-1; ds >= drawsegs; ds--) old buggy code - for (ds = ds_p; ds-- > drawsegs ;) + for (ds = ds_p; ds-- > dsstart;) { // determine if the drawseg obscures the sprite if (ds->x1 > spr->x2 || @@ -2223,33 +2223,36 @@ void R_ClipSprites(void) continue; } - if (ds->portalpass > 0 && ds->portalpass <= portalrender) - continue; // is a portal + if (ds->portalpass != 66) + { + if (ds->portalpass > 0 && ds->portalpass <= portalrender) + continue; // is a portal - r1 = ds->x1 < spr->x1 ? spr->x1 : ds->x1; - r2 = ds->x2 > spr->x2 ? spr->x2 : ds->x2; + if (ds->scale1 > ds->scale2) + { + lowscale = ds->scale2; + scale = ds->scale1; + } + else + { + lowscale = ds->scale1; + scale = ds->scale2; + } - if (ds->scale1 > ds->scale2) - { - lowscale = ds->scale2; - scale = ds->scale1; - } - else - { - lowscale = ds->scale1; - scale = ds->scale2; + if (scale < spr->sortscale || + (lowscale < spr->sortscale && + !R_PointOnSegSide (spr->gx, spr->gy, ds->curline))) + { + // masked mid texture? + /*if (ds->maskedtexturecol) + R_RenderMaskedSegRange (ds, r1, r2);*/ + // seg is behind sprite + continue; + } } - if (scale < spr->sortscale || - (lowscale < spr->sortscale && - !R_PointOnSegSide (spr->gx, spr->gy, ds->curline))) - { - // masked mid texture? - /*if (ds->maskedtexturecol) - R_RenderMaskedSegRange (ds, r1, r2);*/ - // seg is behind sprite - continue; - } + r1 = ds->x1 < spr->x1 ? spr->x1 : ds->x1; + r2 = ds->x2 > spr->x2 ? spr->x2 : ds->x2; // clip this piece of the sprite silhouette = ds->silhouette; @@ -2367,20 +2370,29 @@ void R_ClipSprites(void) //Fab : 26-04-98: was -1, now clips against console bottom spr->cliptop[x] = (INT16)con_clipviewtop; } + + if (portal) + { + for (x = spr->x1; x <= spr->x2; x++) + { + if (spr->clipbot[x] > portal->floorclip[x - portal->start]) + spr->clipbot[x] = portal->floorclip[x - portal->start]; + if (spr->cliptop[x] < portal->ceilingclip[x - portal->start]) + spr->cliptop[x] = portal->ceilingclip[x - portal->start]; + } + } } } // // R_DrawMasked // -void R_DrawMasked(void) +static void R_DrawMaskedList (drawnode_t* head) { drawnode_t *r2; drawnode_t *next; - R_CreateDrawNodes(); - - for (r2 = nodehead.next; r2 != &nodehead; r2 = r2->next) + for (r2 = head->next; r2 != head; r2 = r2->next) { if (r2->plane) { @@ -2432,7 +2444,38 @@ void R_DrawMasked(void) r2 = next; } } - R_ClearDrawNodes(); +} + +void R_DrawMasked(maskcount_t* masks, UINT8 nummasks) +{ + drawnode_t heads[nummasks]; /**< Drawnode lists; as many as number of views/portals. */ + INT8 i; + + for (i = 0; i < nummasks; i++) + { + heads[i].next = heads[i].prev = &heads[i]; + + viewx = masks[i].viewx; + viewy = masks[i].viewy; + viewz = masks[i].viewz; + viewsector = masks[i].viewsector; + + R_CreateDrawNodes(&masks[i], &heads[i], false); + } + + //for (i = 0; i < nummasks; i++) + // CONS_Printf("Mask no.%d:\ndrawsegs: %d\n vissprites: %d\n\n", i, masks[i].drawsegs[1] - masks[i].drawsegs[0], masks[i].vissprites[1] - masks[i].vissprites[0]); + + for (; nummasks > 0; nummasks--) + { + viewx = masks[nummasks - 1].viewx; + viewy = masks[nummasks - 1].viewy; + viewz = masks[nummasks - 1].viewz; + viewsector = masks[nummasks - 1].viewsector; + + R_DrawMaskedList(&heads[nummasks - 1]); + R_ClearDrawNodes(&heads[nummasks - 1]); + } } // ========================================================================== diff --git a/src/r_things.h b/src/r_things.h index 1003103ca94e80a9b9362d767e3ffab194c7ad1a..d287df8328293374265873a9d5e1602a3181f60f 100644 --- a/src/r_things.h +++ b/src/r_things.h @@ -16,6 +16,7 @@ #include "sounds.h" #include "r_plane.h" +#include "r_portal.h" // "Left" and "Right" character symbols for additional rotation functionality #define ROT_L ('L' - '0') @@ -45,7 +46,6 @@ extern fixed_t windowbottom; void R_DrawMaskedColumn(column_t *column); void R_DrawFlippedMaskedColumn(column_t *column, INT32 texheight); -void R_SortVisSprites(void); //faB: find sprites in wadfile, replace existing, add new ones // (only sprites from namelist are added or replaced) @@ -55,8 +55,21 @@ void R_AddSpriteDefs(UINT16 wadnum); void R_AddSprites(sector_t *sec, INT32 lightlevel); void R_InitSprites(void); void R_ClearSprites(void); -void R_ClipSprites(void); -void R_DrawMasked(void); +void R_ClipSprites(drawseg_t* dsstart, portal_t* portal); + +/** Used to count the amount of masked elements + * per portal to later group them in separate + * drawnode lists. + */ +typedef struct +{ + size_t drawsegs[2]; + size_t vissprites[2]; + fixed_t viewx, viewy, viewz; /**< View z stored at the time of the BSP traversal for the view/portal. Masked sorting/drawing needs it. */ + sector_t* viewsector; +} maskcount_t; + +void R_DrawMasked(maskcount_t* masks, UINT8 nummasks); // ----------- // SKINS STUFF @@ -207,6 +220,7 @@ typedef struct drawnode_s extern INT32 numskins; extern skin_t skins[MAXSKINS]; +extern UINT32 visspritecount; void SetPlayerSkin(INT32 playernum,const char *skinname); void SetPlayerSkinByNum(INT32 playernum,INT32 skinnum); // Tails 03-16-2002 diff --git a/src/sdl/CMakeLists.txt b/src/sdl/CMakeLists.txt index 7f8f052bab673069732a7b01bee833cb3348eb55..de2157055839476d8599db462d22e2d7cdeb1b20 100644 --- a/src/sdl/CMakeLists.txt +++ b/src/sdl/CMakeLists.txt @@ -153,7 +153,7 @@ if(${SDL2_FOUND}) ${ZLIB_LIBRARIES} ${OPENGL_LIBRARIES} ) - set_target_properties(SRB2SDL2 PROPERTIES OUTPUT_NAME "Sonic Robo Blast 2") + set_target_properties(SRB2SDL2 PROPERTIES OUTPUT_NAME "${CPACK_PACKAGE_DESCRIPTION_SUMMARY}") else() target_link_libraries(SRB2SDL2 PRIVATE ${SDL2_LIBRARIES} @@ -337,10 +337,19 @@ if(${SDL2_FOUND}) # Mac bundle fixup + # HACK: THIS IS IMPORTANT! See the escaped \${CMAKE_INSTALL_PREFIX}? This + # makes it so that var is evaluated LATER during cpack, not right now! + # This fixes the quirk where the bundled libraries don't land in the final package + # https://cmake.org/pipermail/cmake/2011-March/043532.html + # + # HOWEVER: ${CPACK_PACKAGE_DESCRIPTION_SUMMARY} is NOT escaped, because that var + # is only available to us at this step. Read the link: ${CMAKE_INSTALL_PREFIX} at + # this current step points to the CMAKE build folder, NOT the folder that CPACK uses. + # Therefore, it makes sense to escape that var, but not the other. if(${CMAKE_SYSTEM} MATCHES Darwin) install(CODE " include(BundleUtilities) - fixup_bundle(\"${CMAKE_INSTALL_PREFIX}/Sonic Robo Blast 2.app\" + fixup_bundle(\"\${CMAKE_INSTALL_PREFIX}/${CPACK_PACKAGE_DESCRIPTION_SUMMARY}.app\" \"\" /Library/Frameworks )" diff --git a/src/sdl/Srb2SDL-vc10.vcxproj b/src/sdl/Srb2SDL-vc10.vcxproj index e43772179562d95f87de7cf5d3b1734840288e4d..ee5df4dcb1f3cfa706b579f0111e02c9c0b78985 100644 --- a/src/sdl/Srb2SDL-vc10.vcxproj +++ b/src/sdl/Srb2SDL-vc10.vcxproj @@ -93,6 +93,7 @@ <Import Project="..\..\libs\libpng.props" /> <Import Project="..\..\libs\SDL2.props" /> <Import Project="..\..\libs\SDL_mixer.props" /> + <Import Project="..\..\libs\libgme.props" /> <Import Project="Srb2SDL.props" /> </ImportGroup> <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> diff --git a/src/sdl/Srb2SDL.props b/src/sdl/Srb2SDL.props index 260f81eed79d762e0f079810d30ea0e0d35d4dcb..75839a5b2cb9c4efaf589ffa98845f1fd56aaf76 100644 --- a/src/sdl/Srb2SDL.props +++ b/src/sdl/Srb2SDL.props @@ -5,7 +5,10 @@ <PropertyGroup /> <ItemDefinitionGroup> <ClCompile> - <PreprocessorDefinitions>USE_WGL_SWAP;DIRECTFULLSCREEN;HAVE_SDL;HWRENDER;HW3SOUND;HAVE_FILTER;HAVE_MIXER;SDLMAIN;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <!-- x86/x64 defines: has specific libraries that ARM does not --> + <PreprocessorDefinitions Condition="'$(Platform)' == 'Win32' OR '$(Platform)' == 'x64'">HAVE_ZLIB;HAVE_LIBGME;USE_WGL_SWAP;DIRECTFULLSCREEN;HAVE_SDL;HWRENDER;HW3SOUND;HAVE_FILTER;HAVE_MIXER;SDLMAIN;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <!-- ARM defines --> + <PreprocessorDefinitions Condition="'$(Platform)' != 'Win32' AND '$(Platform)' != 'x64'">USE_WGL_SWAP;DIRECTFULLSCREEN;HAVE_SDL;HWRENDER;HW3SOUND;HAVE_FILTER;HAVE_MIXER;SDLMAIN;%(PreprocessorDefinitions)</PreprocessorDefinitions> </ClCompile> </ItemDefinitionGroup> <ItemGroup /> diff --git a/src/sdl/macosx/Srb2mac.xcodeproj/project.pbxproj b/src/sdl/macosx/Srb2mac.xcodeproj/project.pbxproj index a8ecbf7f85984eaeb63a1b3254f001da6c0d0f32..878db3d8de37b4a8cfb19a8a95dcfaa99559ceda 100644 --- a/src/sdl/macosx/Srb2mac.xcodeproj/project.pbxproj +++ b/src/sdl/macosx/Srb2mac.xcodeproj/project.pbxproj @@ -1219,7 +1219,7 @@ C01FCF4B08A954540054247B /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { - CURRENT_PROJECT_VERSION = 2.1.23; + CURRENT_PROJECT_VERSION = 2.1.24; GCC_PREPROCESSOR_DEFINITIONS = ( "$(inherited)", NORMALSRB2, @@ -1231,7 +1231,7 @@ C01FCF4C08A954540054247B /* Release */ = { isa = XCBuildConfiguration; buildSettings = { - CURRENT_PROJECT_VERSION = 2.1.23; + CURRENT_PROJECT_VERSION = 2.1.24; GCC_ENABLE_FIX_AND_CONTINUE = NO; GCC_GENERATE_DEBUGGING_SYMBOLS = NO; GCC_PREPROCESSOR_DEFINITIONS = ( diff --git a/src/sounds.h b/src/sounds.h index 489e2882695c0377d481526b34096325d6a0a53a..47530912133953fafcd166198a5166ab5bbb192a 100644 --- a/src/sounds.h +++ b/src/sounds.h @@ -42,7 +42,7 @@ typedef enum } skinsound_t; // free sfx for S_AddSoundFx() -#define NUMSFXFREESLOTS 800 // Matches SOC Editor. +#define NUMSFXFREESLOTS 1600 // Matches SOC Editor. #define NUMSKINSFXSLOTS (MAXSKINS*NUMSKINSOUNDS) // diff --git a/src/st_stuff.c b/src/st_stuff.c index 9ad04b5ce4c1b17b6728728a9d0d0f00ef59dac8..4509ed849fa0dbd09abb64f84c507ab047c5db97 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -190,7 +190,7 @@ void ST_Ticker(void) } // 0 is default, any others are special palettes. -static INT32 st_palette = 0; +INT32 st_palette = 0; void ST_doPaletteStuff(void) { diff --git a/src/st_stuff.h b/src/st_stuff.h index e1d8a8a92aae61045d602c9b37cee2b2db9e4337..aca4e60d2949aacc618d27a93c6b6fc3d92b291e 100644 --- a/src/st_stuff.h +++ b/src/st_stuff.h @@ -58,6 +58,7 @@ boolean ST_SameTeam(player_t *a, player_t *b); //-------------------- extern boolean st_overlay; // sb overlay on or off when fullscreen +extern INT32 st_palette; // 0 is default, any others are special palettes. extern lumpnum_t st_borderpatchnum; // patches, also used in intermission diff --git a/src/win32/Srb2win-vc10.vcxproj b/src/win32/Srb2win-vc10.vcxproj index 774ce5cbe8c7560c592f2b6b97e3db7864221347..acab2507a37d995112b6402e7c83ac0d6f0dd57a 100644 --- a/src/win32/Srb2win-vc10.vcxproj +++ b/src/win32/Srb2win-vc10.vcxproj @@ -91,6 +91,7 @@ <Import Project="..\..\libs\FMOD.props" /> <Import Project="..\..\libs\zlib.props" /> <Import Project="..\..\libs\libpng.props" /> + <Import Project="..\..\libs\libgme.props" /> <Import Project="SRB2Win.props" /> </ImportGroup> <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> diff --git a/src/win32/Srb2win.props b/src/win32/Srb2win.props index 44a30d50d4f71b3d8942a5730fc0300baa0a9f7c..fa152f0c97aa6894c289eadb388cb7b33fb153d2 100644 --- a/src/win32/Srb2win.props +++ b/src/win32/Srb2win.props @@ -5,7 +5,10 @@ <PropertyGroup /> <ItemDefinitionGroup> <ClCompile> - <PreprocessorDefinitions>_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <!-- x86/x64 defines: has specific libraries that ARM does not --> + <PreprocessorDefinitions Condition="'$(Platform)' == 'Win32' OR '$(Platform)' == 'x64'">HAVE_ZLIB;HAVE_LIBGME;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <!-- ARM defines --> + <PreprocessorDefinitions Condition="'$(Platform)' != 'Win32' AND '$(Platform)' != 'x64'">_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions> </ClCompile> <Link /> <Link>