Merge remote-tracking branch 'upstream/master' into flats-png

This commit is contained in:
Jaime Passos 2019-06-25 16:02:35 -03:00
commit 28566008b4
85 changed files with 3224 additions and 484 deletions

2
.gitignore vendored
View File

@ -19,3 +19,5 @@ Win32_LIB_ASM_Release
*.db *.db
*.opendb *.opendb
/.vs /.vs
/debian
/assets/debian

View File

@ -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 language: c
sudo: required sudo: required
dist: trusty dist: trusty
matrix: matrix:
include: 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 - os: linux
addons: addons:
apt: apt:
@ -16,6 +27,7 @@ matrix:
- gcc-4.4 - gcc-4.4
compiler: gcc-4.4 compiler: gcc-4.4
env: GCC44=1 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 #gcc-4.4 (Ubuntu/Linaro 4.4.7-8ubuntu1) 4.4.7
- os: linux - os: linux
addons: addons:
@ -29,6 +41,7 @@ matrix:
- gcc-4.6 - gcc-4.6
compiler: gcc-4.6 compiler: gcc-4.6
env: GCC46=1 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 #gcc-4.6 (Ubuntu/Linaro 4.6.4-6ubuntu2) 4.6.4
- os: linux - os: linux
addons: addons:
@ -42,10 +55,12 @@ matrix:
- gcc-4.7 - gcc-4.7
compiler: gcc-4.7 compiler: gcc-4.7
env: GCC47=1 env: GCC47=1
if: env(DPL_ENABLED) != "1" OR env(DPL_TERMINATE_TESTS) != "1" OR NOT branch =~ /^.*deployer.*$/
#gcc-4.7 #gcc-4.7
- os: linux - os: linux
compiler: gcc compiler: gcc
env: GCC48=1 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 #gcc (Ubuntu 4.8.4-2ubuntu1~14.04) 4.8.4
- os: linux - os: linux
addons: addons:
@ -61,6 +76,7 @@ matrix:
- gcc-4.8 - gcc-4.8
compiler: gcc-4.8 compiler: gcc-4.8
env: GCC48=1 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 #gcc-4.8 (Ubuntu 4.8.5-2ubuntu1~14.04.1) 4.8.5
- os: linux - os: linux
addons: addons:
@ -76,6 +92,7 @@ matrix:
- gcc-7 - gcc-7
compiler: gcc-7 compiler: gcc-7
env: WFLAGS="-Wno-tautological-compare -Wno-error=implicit-fallthrough -Wno-implicit-fallthrough" GCC72=1 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 #gcc-7 (Ubuntu 7.2.0-1ubuntu1~14.04) 7.2.0 20170802
- os: linux - os: linux
addons: addons:
@ -90,10 +107,12 @@ matrix:
- p7zip-full - p7zip-full
- gcc-8 - gcc-8
compiler: 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 #gcc-8 (Ubuntu 7.2.0-1ubuntu1~14.04) 8.1.0
- os: linux - os: linux
compiler: clang 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) #clang version 3.5.0 (tags/RELEASE_350/final)
- os: linux - os: linux
addons: addons:
@ -108,6 +127,7 @@ matrix:
- p7zip-full - p7zip-full
- clang-3.5 - clang-3.5
compiler: 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) #Ubuntu clang version 3.5.0-4ubuntu2~trusty2 (tags/RELEASE_350/final) (based on LLVM 3.5.0)
- os: linux - os: linux
addons: addons:
@ -123,6 +143,7 @@ matrix:
- p7zip-full - p7zip-full
- clang-3.6 - clang-3.6
compiler: 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) #Ubuntu clang version 3.6.2-svn240577-1~exp1 (branches/release_36) (based on LLVM 3.6.2)
- os: linux - os: linux
addons: addons:
@ -138,6 +159,7 @@ matrix:
- p7zip-full - p7zip-full
- clang-3.7 - clang-3.7
compiler: 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) #Ubuntu clang version 3.7.1-svn253571-1~exp1 (branches/release_37) (based on LLVM 3.7.1)
- os: linux - os: linux
addons: addons:
@ -153,6 +175,7 @@ matrix:
- p7zip-full - p7zip-full
- clang-3.8 - clang-3.8
compiler: 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) #clang version 3.8.1-svn271127-1~exp1 (branches/release_38)
- os: linux - os: linux
addons: addons:
@ -168,6 +191,7 @@ matrix:
- p7zip-full - p7zip-full
- clang-3.9 - clang-3.9
compiler: 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 #clang version 3.9.X
# - os: linux # - os: linux
# addons: # addons:
@ -183,6 +207,7 @@ matrix:
# - p7zip-full # - p7zip-full
# - clang-4.0 # - clang-4.0
# compiler: 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 # #clang version 4.0.X
# - os: linux # - os: linux
# addons: # addons:
@ -198,34 +223,325 @@ matrix:
# - p7zip-full # - p7zip-full
# - clang-5.0 # - clang-5.0
# compiler: 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 # #clang version 5.0.X
# - os: osx # - os: osx
# osx_image: beta-xcode6.1 # 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) # #Apple LLVM version 6.0 (clang-600.0.54) (based on LLVM 3.5svn)
# - os: osx # - os: osx
# osx_image: beta-xcode6.2 # osx_image: beta-xcode6.2
# compiler: gcc # 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) # #Apple LLVM version 6.0 (clang-600.0.57) (based on LLVM 3.5svn)
## - os: osx ## - os: osx
## osx_image: beta-xcode6.3 ## 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 ## #I think xcode.6.3 VM is broken, it does not boot
# - os: osx # - os: osx
# osx_image: xcode6.4 # 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) # #Apple LLVM version 6.1.0 (clang-602.0.53) (based on LLVM 3.6.0svn)
# - os: osx # - os: osx
# osx_image: xcode7 # 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) # #Apple LLVM version 7.0.0 (clang-700.0.72)
# - os: osx # - os: osx
# osx_image: xcode7.1 # 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) # #Apple LLVM version 7.0.0 (clang-700.1.76)
# - os: osx # - os: osx
# osx_image: xcode7.2 # 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) # #Apple LLVM version 7.0.2 (clang-700.1.81)
# - os: osx # - os: osx
# osx_image: xcode7.3 # 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) # #Apple LLVM version 7.3.0 (clang-703.0.31)
- os: osx - 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 #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: allow_failures:
- compiler: clang-3.5 - compiler: clang-3.5
- compiler: clang-3.6 - compiler: clang-3.6
@ -235,12 +551,14 @@ matrix:
- compiler: clang-4.0 - compiler: clang-4.0
- compiler: clang-5.0 - compiler: clang-5.0
cache: cache:
apt: true apt: true
ccache: true ccache: true
directories: directories:
- $HOME/srb2_cache - $HOME/srb2_cache
addons: addons:
apt: apt:
packages: packages:
@ -248,6 +566,7 @@ addons:
- libpng-dev - libpng-dev
- libgl1-mesa-dev - libgl1-mesa-dev
- libgme-dev - libgme-dev
- zlib1g-dev
- p7zip-full - p7zip-full
homebrew: homebrew:
taps: taps:
@ -260,18 +579,115 @@ addons:
update: true update: true
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
- mkdir build
- cd build
- export CFLAGS="-Wall -W -Werror $WFLAGS"
- export CCACHE_COMPRESS=true
- cmake .. -DCMAKE_BUILD_TYPE=Release
before_install: 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 # Initialize Deployer defaults
- 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 - . ./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 - mkdir -p $HOME/srb2_cache
script: make -k
before_script:
# 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
# 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}"
script:
# Build our Makefile from Cmake!
- if [[ "$__DPL_ACTIVE" == "1" ]]; then
. ../deployer/travis/deployer_build.sh;
else
make -k;
fi;
after_success:
# Run the upload scripts
# These do nothing if Deployer is not triggered
- . ../deployer/travis/deployer_ftp.sh
- . ../deployer/travis/deployer_dput.sh

View File

@ -1,6 +1,8 @@
cmake_minimum_required(VERSION 3.0) 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 project(SRB2
VERSION 2.1.23 VERSION 2.1.24
LANGUAGES C) LANGUAGES C)
if(${PROJECT_SOURCE_DIR} MATCHES ${PROJECT_BINARY_DIR}) 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(CMAKE_PDB_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin")
# Set EXE names so the assets CMakeLists can refer to its target # Set EXE names so the assets CMakeLists can refer to its target
set(SRB2_SDL2_EXE_NAME srb2) set(SRB2_SDL2_EXE_NAME srb2 CACHE STRING "Executable binary output name")
set(SRB2_WIN_EXE_NAME srb2dd) set(SRB2_WIN_EXE_NAME srb2dd CACHE STRING "Executable binary output name for DirectDraw build")
include_directories(${CMAKE_CURRENT_BINARY_DIR}/src) include_directories(${CMAKE_CURRENT_BINARY_DIR}/src)
@ -122,8 +124,8 @@ if(${CMAKE_SYSTEM} MATCHES "Darwin")
set(CPACK_GENERATOR "DragNDrop") set(CPACK_GENERATOR "DragNDrop")
endif() endif()
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Sonic Robo Blast 2") set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Sonic Robo Blast 2" CACHE STRING "Program name for display purposes")
set(CPACK_PACKAGE_VENDOR "Sonic Team Jr.") set(CPACK_PACKAGE_VENDOR "Sonic Team Jr." CACHE STRING "Vendor name for display purposes")
#set(CPACK_PACKAGE_DESCRIPTION_FILE ) #set(CPACK_PACKAGE_DESCRIPTION_FILE )
set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/LICENSE") set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/LICENSE")
set(CPACK_PACKAGE_VERSION_MAJOR ${SRB2_VERSION_MAJOR}) set(CPACK_PACKAGE_VERSION_MAJOR ${SRB2_VERSION_MAJOR})

View File

@ -1,4 +1,4 @@
version: 2.1.23.{branch}-{build} version: 2.1.24.{branch}-{build}
os: MinGW os: MinGW
environment: environment:

11
assets/.gitignore vendored
View File

@ -1,5 +1,10 @@
* *.srb
*.* *.pk3
*.dta
*.wad
*.txt
!README.txt !README.txt
!LICENSE.txt !LICENSE.txt
!LICENSE-3RD-PARTY.txt !LICENSE-3RD-PARTY.txt
!CMakeLists.txt
!debian-template/*

View File

@ -1,40 +1,58 @@
## Assets Target Configuration ## ## Assets Target Configuration ##
# MD5 generation # For prepending the current source path, later
set(SRB2_ASSET_ALL FUNCTION(PREPEND var prefix)
${CMAKE_CURRENT_SOURCE_DIR}/srb2.srb SET(listVar "")
${CMAKE_CURRENT_SOURCE_DIR}/player.dta FOREACH(f ${ARGN})
${CMAKE_CURRENT_SOURCE_DIR}/rings.dta LIST(APPEND listVar "${prefix}/${f}")
${CMAKE_CURRENT_SOURCE_DIR}/zones.dta ENDFOREACH(f)
${CMAKE_CURRENT_SOURCE_DIR}/patch.dta SET(${var} "${listVar}" PARENT_SCOPE)
${CMAKE_CURRENT_SOURCE_DIR}/music.dta ENDFUNCTION(PREPEND)
${CMAKE_CURRENT_SOURCE_DIR}/README.txt
${CMAKE_CURRENT_SOURCE_DIR}/LICENSE.txt set(SRB2_ASSET_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/installer"
${CMAKE_CURRENT_SOURCE_DIR}/LICENSE-3RD-PARTY.txt CACHE STRING "Path to directory that contains all asset files for the installer.")
)
set(SRB2_ASSET_HASHED set(SRB2_ASSET_HASHED
srb2.srb "srb2.srb;\
player.dta player.dta;\
rings.dta rings.dta;\
zones.dta zones.dta;\
patch.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}) 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) set(SRB2_ASSET_${SRB2_ASSET}_HASH ${SRB2_ASSET_${SRB2_ASSET}_HASH} PARENT_SCOPE)
endforeach() endforeach()
# Installation # Installation
if(CLANG) if(${CMAKE_SYSTEM} MATCHES Darwin)
get_target_property(outname SRB2SDL2 OUTPUT_NAME) get_target_property(outname SRB2SDL2 OUTPUT_NAME)
install(FILES ${SRB2_ASSET_ALL} install(DIRECTORY "${SRB2_ASSET_DIRECTORY}/"
DESTINATION "${outname}.app/Contents/Resources" DESTINATION "${outname}.app/Contents/Resources"
) )
install(FILES ${SRB2_ASSET_DOCS}
DESTINATION .
OPTIONAL
)
else() else()
install(FILES ${SRB2_ASSET_ALL} install(DIRECTORY "${SRB2_ASSET_DIRECTORY}/"
DESTINATION . DESTINATION .
) )
# Docs are assumed to be located in SRB2_ASSET_DIRECTORY, so don't install again
#install(FILES ${SRB2_ASSET_DOCS}
# DESTINATION .
# OPTIONAL
#)
endif() endif()

View File

@ -12,9 +12,39 @@ with apt-key add. Thanks!
-- Callum Dickinson <gcfreak_ag20@hotmail.com> Fri, 26 Nov 2010 18:25:31 +1300 -- 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 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. to publish the fingerprint of that key to Ubuntu's key server.
https://help.ubuntu.com/community/GnuPrivacyGuardHowto#Uploading_the_key_to_Ubuntu_keyserver 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 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. 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 Uploading for Launchpad PPA
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: Follow the instructions at <https://help.launchpad.net/Packaging/PPA/Uploading> to upload
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)
Then follow the instructions at <https://help.launchpad.net/Packaging/PPA/Uploading> to upload
to your PPA and have Launchpad build your binary deb packages. 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 -- Marco Zafra <marco.a.zafra@gmail.com> Mon, 26 Nov 2018 21:13:00 -0500

View File

@ -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}

View File

@ -1,15 +1,15 @@
# SRB2-data Debian package control file. # SRB2-data Debian package control file.
Source: srb2-data Source: ${PACKAGE_NAME}-data
Section: games Section: games
Priority: extra Priority: extra
Maintainer: Sonic Team Junior <stjr@srb2.org> Maintainer: ${PACKAGE_GROUP_NAME_EMAIL}
Build-Depends: debhelper (>= 7.0.50~), Build-Depends: debhelper (>= 7.0.50~),
wget wget
Standards-Version: 3.8.4 Standards-Version: 3.8.4
Homepage: http://www.srb2.org Homepage: ${PACKAGE_WEBSITE}
Package: srb2-data Package: ${PACKAGE_NAME}-data
Architecture: all Architecture: all
Description: A cross-platform 3D Sonic fangame Description: A cross-platform 3D Sonic fangame
Sonic Robo Blast 2 is a 3D open-source Sonic the Hedgehog Sonic Robo Blast 2 is a 3D open-source Sonic the Hedgehog

View File

@ -1,18 +1,18 @@
This work was packaged for Debian by: 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: It was downloaded from:
<http://srb2.org> ${PACKAGE_WEBSITE}
Upstream Author(s): Upstream Author(s):
Sonic Team Junior <stjr@srb2.org> ${PACKAGE_GROUP_NAME_EMAIL}
Copyright: Copyright:
Copyright (C) 1998-2018 Sonic Team Junior Copyright (C) 1998-2018 by Sonic Team Junior
License: License:
@ -21,7 +21,7 @@ License:
The Debian packaging is: The Debian packaging is:
Copyright (C) 2010 Callum Dickinson <gcfreak_ag20@hotmail.com> 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, and is licensed under the GPL version 2,
see "/usr/share/common-licenses/GPL-2". see "/usr/share/common-licenses/GPL-2".

42
assets/debian/rules → assets/debian-template/rules Executable file → Normal file
View File

@ -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. # Uncomment this to turn on verbose mode.
#export DH_VERBOSE=1 #export DH_VERBOSE=1
@ -37,30 +47,32 @@ RM := rm -rf
DIR := $(shell pwd) DIR := $(shell pwd)
PACKAGE := $(shell cat $(DIR)/debian/control | grep 'Package:' | sed -e 's/Package: //g') 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 := . RESOURCEDIR := .
STAGINGDIR := $(RESOURCEDIR)/installer
WGET := wget -P $(RESOURCEDIR) -c -nc WGET := wget -P $(RESOURCEDIR) -c -nc
build: build:
$(MKDIR) $(DIR)/debian/tmp/$(DATADIR) $(MKDIR) $(DIR)/debian/tmp/$(DATADIR)
> $(DIR)/debian/source/include-binaries > $(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 # Copy data files to their install locations, and add data files to include-binaries
for file in $(DATAFILES); do \ if [ ! -d $(STAGINGDIR) ]; then \
if [ ! -f $(RESOURCEDIR)/$$file ]; then \ mkdir -p "$(STAGINGDIR)"; \
$(WGET) http://alam.srb2.org/SRB2/2.1.21-Final/Resources/$$file; \ $(WGET) $(ARCHIVEPATH); \
7z x "$(RESOURCEDIR)/$(shell basename $(ARCHIVEPATH))" -aos; \
if [ "$(GETOPTIONALFILES)" = "1" ]; then \
$(WGET) $(ARCHIVEOPTIONALPATH); \
7z x "$(RESOURCEDIR)/$(shell basename $(ARCHIVEOPTIONALPATH))" -aos; \
fi; \ fi; \
if [ -f $(RESOURCEDIR)/$$file ]; then \ fi
$(INSTALL) $(RESOURCEDIR)/$$file $(DIR)/debian/tmp/$(DATADIR)/$$file; \ # Install asset directory and add asset file to include-binaries
echo $(RESOURCEDIR)/$$file >> $(DIR)/debian/source/include-binaries; \ cp -vr "$(STAGINGDIR)/." "$(DIR)/debian/tmp/$(DATADIR)"
fi; \ find "$(STAGINGDIR)" >> $(DIR)/debian/source/include-binaries
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
binary-indep: binary-indep:
# Generate install folder file # Generate install folder file

View File

@ -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

View File

@ -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 -- 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 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. to publish the fingerprint of that key to Ubuntu's key server.
https://help.ubuntu.com/community/GnuPrivacyGuardHowto#Uploading_the_key_to_Ubuntu_keyserver 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 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. 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] Uploading for Launchpad PPA
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!
Building the source package takes just one step: Follow the instructions at <https://help.launchpad.net/Packaging/PPA/Uploading> to upload
1. debuild -S (builds the source package for Launchpad)
Then follow the instructions at <https://help.launchpad.net/Packaging/PPA/Uploading> to upload
to your PPA and have Launchpad build your binary deb packages. 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 -- Marco Zafra <marco.a.zafra@gmail.com> Mon, 26 Nov 2018 21:13:00 -0500

View File

@ -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}

View File

@ -1,24 +1,30 @@
# SRB2 Debian package control file. # SRB2 Debian package control file.
Source: srb2 Source: ${PACKAGE_NAME}
Section: games Section: games
Priority: extra Priority: extra
Maintainer: Sonic Team Junior <stjr@srb2.org> Maintainer: ${PACKAGE_GROUP_NAME_EMAIL}
Build-Depends: debhelper (>= 7.0.50~), Build-Depends: debhelper (>= 7.0.50~),
libsdl2-dev, libsdl2-dev,
libsdl2-mixer-dev, libsdl2-mixer-dev,
libpng12-dev (>= 1.2.7) | libpng-dev, libpng-dev | libpng16-dev | libpng12-dev (>= 1.2.7),
zlib1g-dev, zlib1g-dev,
libgme-dev, libgme-dev,
libglu1-dev | libglu-dev, libglu1-dev | libglu-dev,
libosmesa6-dev | libgl-dev, libosmesa6-dev | libgl-dev,
nasm [i386] nasm [i386]
Standards-Version: 3.8.4 Standards-Version: 3.8.4
Homepage: http://www.srb2.org Homepage: ${PACKAGE_WEBSITE}
Package: srb2 Package: ${PACKAGE_NAME}
Architecture: any 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 Description: A cross-platform 3D Sonic fangame
Sonic Robo Blast 2 is a 3D open-source Sonic the Hedgehog Sonic Robo Blast 2 is a 3D open-source Sonic the Hedgehog
fangame built using a modified version of the Doom Legacy 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. and quite a lot of the fun that the original Sonic games provided.
Package: srb2-dbg Package: ${PACKAGE_NAME}-dbg
Architecture: any Architecture: any
# FIXME: should be Depends: ${shlibs:Depends}, ${misc:Depends}, srb2-data (= 2.1.14), srb2 but dh_shlibdeps is being an asshat # 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 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 Description: A cross-platform 3D Sonic fangame
Sonic Robo Blast 2 is a 3D open-source Sonic the Hedgehog Sonic Robo Blast 2 is a 3D open-source Sonic the Hedgehog
fangame built using a modified version of the Doom Legacy fangame built using a modified version of the Doom Legacy

View File

@ -1,18 +1,18 @@
This work was packaged for Debian by: 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: It was downloaded from:
<http://srb2.org> ${PACKAGE_WEBSITE}
Upstream Author(s): Upstream Author(s):
Sonic Team Junior <stjr@srb2.org> ${PACKAGE_GROUP_NAME_EMAIL}
Copyright: Copyright:
Copyright (C) 1998-2018 Sonic Team Junior Copyright (C) 1998-2018 by Sonic Team Junior
License: License:
@ -21,7 +21,7 @@ License:
The Debian packaging is: The Debian packaging is:
Copyright (C) 2010 Callum Dickinson <gcfreak_ag20@hotmail.com> 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, and is licensed under the GPL version 2,
see "/usr/share/common-licenses/GPL-2". see "/usr/share/common-licenses/GPL-2".

26
debian/rules → debian-template/rules Executable file → Normal file
View File

@ -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. # Uncomment this to turn on verbose mode.
#export DH_VERBOSE=1 #export DH_VERBOSE=1
@ -50,16 +60,16 @@ DIR := $(shell pwd)
# FIXME: hate hate hate head/tail hack :( # FIXME: hate hate hate head/tail hack :(
CONTROLF = $(DIR)/debian/control CONTROLF = $(DIR)/debian/control
PACKAGE = srb2 PACKAGE = ${PACKAGE_NAME}
DBGPKG = $(PACKAGE)-dbg DBGPKG = ${PACKAGE}-dbg
TITLE = Sonic Robo Blast 2 TITLE = ${PROGRAM_NAME}
SECTION = Games/Action SECTION = Games/Action
EXENAME = srb2 EXENAME = ${PROGRAM_FILENAME}
DBGNAME = debug/$(EXENAME) DBGNAME = debug/$(EXENAME)
PKGDIR = usr/games/SRB2 PKGDIR = $(shell echo "${PACKAGE_INSTALL_PATH}" | sed -e 's/^\///')
DBGDIR = usr/lib/debug/$(PKGDIR) DBGDIR = usr/lib/debug/$(PKGDIR)
LINKDIR = usr/games LINKDIR = $(shell echo "${PACKAGE_LINK_PATH}" | sed -e 's/^\///')
PIXMAPS_DIR = usr/share/pixmaps PIXMAPS_DIR = usr/share/pixmaps
DESKTOP_DIR = usr/share/applications DESKTOP_DIR = usr/share/applications
PREFIX = $(shell test "$(CROSS_COMPILE_BUILD)" != "$(CROSS_COMPILE_HOST)" && echo "PREFIX=$(CROSS_COMPILE_HOST)") 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)/$(EXENAME) $(DIR)/debian/tmp/$(PKGDIR)/$(PACKAGE)
$(INSTALL) $(BINDIR)/$(DBGNAME) $(DIR)/debian/tmp/$(DBGDIR)/$(PACKAGE) $(INSTALL) $(BINDIR)/$(DBGNAME) $(DIR)/debian/tmp/$(DBGDIR)/$(PACKAGE)
# Install desktop file and banner image # Install desktop file and banner image
$(INSTALL) $(DIR)/srb2.png $(DIR)/debian/tmp/usr/share/pixmaps $(INSTALL) $(DIR)/srb2.png $(DIR)/debian/tmp/usr/share/pixmaps/${PROGRAM_FILENAME}.png
$(INSTALL) $(DIR)/debian/srb2.desktop $(DIR)/debian/tmp/usr/share/applications $(INSTALL) $(DIR)/debian/srb2.desktop $(DIR)/debian/tmp/usr/share/applications/${PROGRAM_FILENAME}.desktop
# add compiled binaries to include-binaries # add compiled binaries to include-binaries
echo $(BINDIR)/$(EXENAME) >> $(DIR)/debian/source/include-binaries echo $(BINDIR)/$(EXENAME) >> $(DIR)/debian/source/include-binaries
echo $(BINDIR)/$(EXENAME) >> $(DIR)/debian/source/include-binaries echo $(BINDIR)/$(EXENAME) >> $(DIR)/debian/source/include-binaries

View File

@ -2,7 +2,7 @@ tar-ignore = "assets/*.srb"
tar-ignore = "assets/*.pk3" tar-ignore = "assets/*.pk3"
tar-ignore = "assets/*.dta" tar-ignore = "assets/*.dta"
tar-ignore = "assets/*.wad" tar-ignore = "assets/*.wad"
tar-ignore = "assets/debian/srb2-data/*" tar-ignore = "assets/debian/${PACKAGE_NAME}-data/*"
tar-ignore = "assets/debian/tmp/*" tar-ignore = "assets/debian/tmp/*"
tar-ignore = "*.obj" tar-ignore = "*.obj"
tar-ignore = "*.dep" tar-ignore = "*.dep"

View File

@ -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;

12
debian/changelog vendored
View File

@ -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

10
debian/srb2.desktop vendored
View File

@ -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;

166
debian_template.sh Normal file
View File

@ -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;

157
deployer/travis/deployer.sh Normal file
View File

@ -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;

View File

@ -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;

View File

@ -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

View File

@ -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;

View File

@ -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

16
libs/libgme.props Normal file
View File

@ -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>

View File

@ -96,6 +96,37 @@ boolean I_SetSongSpeed(float speed)
return false; return false;
} }
/// ------------------------
// MUSIC SEEKING
/// ------------------------
UINT32 I_GetSongLength(void)
{
return 0;
}
boolean I_SetSongLoopPoint(UINT32 looppoint)
{
(void)looppoint;
return false;
}
UINT32 I_GetSongLoopPoint(void)
{
return 0;
}
boolean I_SetSongPosition(UINT32 position)
{
(void)position;
return false;
}
UINT32 I_GetSongPosition(void)
{
return 0;
}
/// ------------------------ /// ------------------------
// MUSIC PLAYBACK // MUSIC PLAYBACK
/// ------------------------ /// ------------------------
@ -140,3 +171,44 @@ void I_SetMusicVolume(INT32 volume)
{ {
(void)volume; (void)volume;
} }
/// ------------------------
// MUSIC FADING
/// ------------------------
void I_SetInternalMusicVolume(UINT8 volume)
{
(void)volume;
}
void I_StopFadingSong(void)
{
}
boolean I_FadeSongFromVolume(UINT8 target_volume, UINT8 source_volume, UINT32 ms, void (*callback)(void));
{
(void)target_volume;
(void)source_volume;
(void)ms;
return false;
}
boolean I_FadeSong(UINT8 target_volume, UINT32 ms, void (*callback)(void));
{
(void)target_volume;
(void)ms;
return false;
}
boolean I_FadeOutStopSong(UINT32 ms)
{
(void)ms;
return false;
}
boolean I_FadeInPlaySong(UINT32 ms, boolean looping)
{
(void)ms;
(void)looping;
return false;
}

View File

@ -2056,17 +2056,11 @@ static void CL_ConnectToServer(boolean viams)
if (i != -1) if (i != -1)
{ {
INT32 j; UINT8 num = serverlist[i].info.gametype;
const char *gametypestr = NULL; const char *gametypestr = NULL;
CONS_Printf(M_GetText("Connecting to: %s\n"), serverlist[i].info.servername); CONS_Printf(M_GetText("Connecting to: %s\n"), serverlist[i].info.servername);
for (j = 0; gametype_cons_t[j].strvalue; j++) if (num < NUMGAMETYPES)
{ gametypestr = Gametype_Names[num];
if (gametype_cons_t[j].value == serverlist[i].info.gametype)
{
gametypestr = gametype_cons_t[j].strvalue;
break;
}
}
if (gametypestr) if (gametypestr)
CONS_Printf(M_GetText("Gametype: %s\n"), gametypestr); CONS_Printf(M_GetText("Gametype: %s\n"), gametypestr);
CONS_Printf(M_GetText("Version: %d.%d.%u\n"), serverlist[i].info.version/100, CONS_Printf(M_GetText("Version: %d.%d.%u\n"), serverlist[i].info.version/100,
@ -2598,7 +2592,10 @@ static void Command_Ban(void)
else else
{ {
if (server) // only the server is allowed to do this right now if (server) // only the server is allowed to do this right now
{
Ban_Add(COM_Argv(2)); Ban_Add(COM_Argv(2));
D_SaveBan(); // save the ban list
}
if (COM_Argc() == 2) if (COM_Argc() == 2)
{ {
@ -2629,6 +2626,42 @@ static void Command_Ban(void)
} }
static void Command_BanIP(void)
{
if (COM_Argc() < 2)
{
CONS_Printf(M_GetText("banip <ip> <reason>: ban an ip address\n"));
return;
}
if (server) // Only the server can use this, otherwise does nothing.
{
const char *address = (COM_Argv(1));
const char *reason;
if (COM_Argc() == 2)
reason = NULL;
else
reason = COM_Argv(2);
if (I_SetBanAddress && I_SetBanAddress(address, NULL))
{
if (reason)
CONS_Printf("Banned IP address %s for: %s\n", address, reason);
else
CONS_Printf("Banned IP address %s\n", address);
Ban_Add(reason);
D_SaveBan();
}
else
{
return;
}
}
}
static void Command_Kick(void) static void Command_Kick(void)
{ {
if (COM_Argc() < 2) if (COM_Argc() < 2)
@ -2908,6 +2941,7 @@ void D_ClientServerInit(void)
COM_AddCommand("getplayernum", Command_GetPlayerNum); COM_AddCommand("getplayernum", Command_GetPlayerNum);
COM_AddCommand("kick", Command_Kick); COM_AddCommand("kick", Command_Kick);
COM_AddCommand("ban", Command_Ban); COM_AddCommand("ban", Command_Ban);
COM_AddCommand("banip", Command_BanIP);
COM_AddCommand("clearbans", Command_ClearBans); COM_AddCommand("clearbans", Command_ClearBans);
COM_AddCommand("showbanlist", Command_ShowBan); COM_AddCommand("showbanlist", Command_ShowBan);
COM_AddCommand("reloadbans", Command_ReloadBan); COM_AddCommand("reloadbans", Command_ReloadBan);

View File

@ -1100,6 +1100,10 @@ void D_SRB2Main(void)
// Setup default unlockable conditions // Setup default unlockable conditions
M_SetupDefaultConditionSets(); M_SetupDefaultConditionSets();
// Setup character tables
// Have to be done here before files are loaded
M_InitCharacterTables();
// load wad, including the main wad file // load wad, including the main wad file
CONS_Printf("W_InitMultipleFiles(): Adding IWAD and main PWADs.\n"); CONS_Printf("W_InitMultipleFiles(): Adding IWAD and main PWADs.\n");
if (!W_InitMultipleFiles(startupwadfiles)) if (!W_InitMultipleFiles(startupwadfiles))
@ -1328,13 +1332,9 @@ void D_SRB2Main(void)
INT16 newgametype = -1; INT16 newgametype = -1;
const char *sgametype = M_GetNextParm(); const char *sgametype = M_GetNextParm();
for (j = 0; gametype_cons_t[j].strvalue; j++) newgametype = G_GetGametypeByName(sgametype);
if (!strcasecmp(gametype_cons_t[j].strvalue, sgametype))
{ if (newgametype == -1) // reached end of the list with no match
newgametype = (INT16)gametype_cons_t[j].value;
break;
}
if (!gametype_cons_t[j].strvalue) // reached end of the list with no match
{ {
j = atoi(sgametype); // assume they gave us a gametype number, which is okay too j = atoi(sgametype); // assume they gave us a gametype number, which is okay too
if (j >= 0 && j < NUMGAMETYPES) if (j >= 0 && j < NUMGAMETYPES)

View File

@ -19,7 +19,7 @@
#define __D_NET__ #define __D_NET__
// Max computers in a game // Max computers in a game
#define MAXNETNODES 32 #define MAXNETNODES (MAXPLAYERS+4)
#define BROADCASTADDR MAXNETNODES #define BROADCASTADDR MAXNETNODES
#define MAXSPLITSCREENPLAYERS 2 // Max number of players on a single computer #define MAXSPLITSCREENPLAYERS 2 // Max number of players on a single computer
//#define NETSPLITSCREEN // Kart's splitscreen netgame feature //#define NETSPLITSCREEN // Kart's splitscreen netgame feature

View File

@ -409,6 +409,16 @@ const char *netxcmdnames[MAXNETXCMD - 1] =
*/ */
void D_RegisterServerCommands(void) void D_RegisterServerCommands(void)
{ {
INT32 i;
for (i = 0; i < NUMGAMETYPES; i++)
{
gametype_cons_t[i].value = i;
gametype_cons_t[i].strvalue = Gametype_Names[i];
}
gametype_cons_t[NUMGAMETYPES].value = 0;
gametype_cons_t[NUMGAMETYPES].strvalue = NULL;
RegisterNetXCmd(XD_NAMEANDCOLOR, Got_NameAndColor); RegisterNetXCmd(XD_NAMEANDCOLOR, Got_NameAndColor);
RegisterNetXCmd(XD_WEAPONPREF, Got_WeaponPref); RegisterNetXCmd(XD_WEAPONPREF, Got_WeaponPref);
RegisterNetXCmd(XD_MAP, Got_Mapcmd); RegisterNetXCmd(XD_MAP, Got_Mapcmd);
@ -1639,7 +1649,7 @@ static void Command_Map_f(void)
{ {
const char *mapname; const char *mapname;
size_t i; size_t i;
INT32 j, newmapnum; INT32 newmapnum;
boolean newresetplayers; boolean newresetplayers;
INT32 newgametype = gametype; INT32 newgametype = gametype;
@ -1707,27 +1717,13 @@ static void Command_Map_f(void)
return; return;
} }
for (j = 0; gametype_cons_t[j].strvalue; j++) newgametype = G_GetGametypeByName(COM_Argv(i+1));
if (!strcasecmp(gametype_cons_t[j].strvalue, COM_Argv(i+1)))
{
// Don't do any variable setting here. Wait until you get your
// map packet first to avoid sending the same info twice!
newgametype = gametype_cons_t[j].value;
break; if (newgametype == -1) // reached end of the list with no match
}
if (!gametype_cons_t[j].strvalue) // reached end of the list with no match
{ {
// assume they gave us a gametype number, which is okay too INT32 j = atoi(COM_Argv(i+1)); // assume they gave us a gametype number, which is okay too
for (j = 0; gametype_cons_t[j].strvalue != NULL; j++) if (j >= 0 && j < NUMGAMETYPES)
{ newgametype = (INT16)j;
if (atoi(COM_Argv(i+1)) == gametype_cons_t[j].value)
{
newgametype = gametype_cons_t[j].value;
break;
}
}
} }
} }
@ -1742,12 +1738,11 @@ static void Command_Map_f(void)
char gametypestring[32] = "Single Player"; char gametypestring[32] = "Single Player";
if (multiplayer) if (multiplayer)
for (i = 0; gametype_cons_t[i].strvalue != NULL; i++) {
if (gametype_cons_t[i].value == newgametype) if (newgametype >= 0 && newgametype < NUMGAMETYPES
{ && Gametype_Names[newgametype])
strcpy(gametypestring, gametype_cons_t[i].strvalue); strcpy(gametypestring, Gametype_Names[newgametype]);
break; }
}
CONS_Alert(CONS_WARNING, M_GetText("%s doesn't support %s mode!\n(Use -force to override)\n"), mapname, gametypestring); CONS_Alert(CONS_WARNING, M_GetText("%s doesn't support %s mode!\n(Use -force to override)\n"), mapname, gametypestring);
return; return;
@ -3483,7 +3478,6 @@ static void Command_ModDetails_f(void)
// //
static void Command_ShowGametype_f(void) static void Command_ShowGametype_f(void)
{ {
INT32 j;
const char *gametypestr = NULL; const char *gametypestr = NULL;
if (!(netgame || multiplayer)) // print "Single player" instead of "Co-op" if (!(netgame || multiplayer)) // print "Single player" instead of "Co-op"
@ -3491,15 +3485,11 @@ static void Command_ShowGametype_f(void)
CONS_Printf(M_GetText("Current gametype is %s\n"), M_GetText("Single player")); CONS_Printf(M_GetText("Current gametype is %s\n"), M_GetText("Single player"));
return; return;
} }
// find name string for current gametype
for (j = 0; gametype_cons_t[j].strvalue; j++) // get name string for current gametype
{ if (gametype >= 0 && gametype < NUMGAMETYPES)
if (gametype_cons_t[j].value == gametype) gametypestr = Gametype_Names[gametype];
{
gametypestr = gametype_cons_t[j].strvalue;
break;
}
}
if (gametypestr) if (gametypestr)
CONS_Printf(M_GetText("Current gametype is %s\n"), gametypestr); CONS_Printf(M_GetText("Current gametype is %s\n"), gametypestr);
else // string for current gametype was not found above (should never happen) else // string for current gametype was not found above (should never happen)
@ -3641,15 +3631,13 @@ void D_GameTypeChanged(INT32 lastgametype)
{ {
if (netgame) if (netgame)
{ {
INT32 j;
const char *oldgt = NULL, *newgt = NULL; const char *oldgt = NULL, *newgt = NULL;
for (j = 0; gametype_cons_t[j].strvalue; j++)
{ if (lastgametype >= 0 && lastgametype < NUMGAMETYPES)
if (gametype_cons_t[j].value == lastgametype) oldgt = Gametype_Names[lastgametype];
oldgt = gametype_cons_t[j].strvalue; if (gametype >= 0 && lastgametype < NUMGAMETYPES)
if (gametype_cons_t[j].value == gametype) newgt = Gametype_Names[gametype];
newgt = gametype_cons_t[j].strvalue;
}
if (oldgt && newgt) if (oldgt && newgt)
CONS_Printf(M_GetText("Gametype was changed from %s to %s\n"), oldgt, newgt); CONS_Printf(M_GetText("Gametype was changed from %s to %s\n"), oldgt, newgt);
} }

View File

@ -435,11 +435,11 @@ static void readAnimTex(MYFILE *f, INT32 num)
static boolean findFreeSlot(INT32 *num) static boolean findFreeSlot(INT32 *num)
{ {
// Send the character select entry to a free slot. // Send the character select entry to a free slot.
while (*num < 32 && PlayerMenu[*num].status != IT_DISABLED) while (*num < MAXSKINS && PlayerMenu[*num].status != IT_DISABLED)
*num = *num+1; *num = *num+1;
// No more free slots. :( // No more free slots. :(
if (*num >= 32) if (*num >= MAXSKINS)
return false; return false;
// Found one! ^_^ // Found one! ^_^
@ -1196,6 +1196,13 @@ static void readlevelheader(MYFILE *f, INT32 num)
#endif #endif
else if (fastcmp(word, "MUSICTRACK")) else if (fastcmp(word, "MUSICTRACK"))
mapheaderinfo[num-1]->mustrack = ((UINT16)i - 1); mapheaderinfo[num-1]->mustrack = ((UINT16)i - 1);
else if (fastcmp(word, "MUSICPOS"))
mapheaderinfo[num-1]->muspos = (UINT32)get_number(word2);
else if (fastcmp(word, "MUSICINTERFADEOUT"))
mapheaderinfo[num-1]->musinterfadeout = (UINT32)get_number(word2);
else if (fastcmp(word, "MUSICINTER"))
deh_strlcpy(mapheaderinfo[num-1]->musintername, word2,
sizeof(mapheaderinfo[num-1]->musintername), va("Level header %d: intermission music", num));
else if (fastcmp(word, "FORCECHARACTER")) else if (fastcmp(word, "FORCECHARACTER"))
{ {
strlcpy(mapheaderinfo[num-1]->forcecharacter, word2, SKINNAMESIZE+1); strlcpy(mapheaderinfo[num-1]->forcecharacter, word2, SKINNAMESIZE+1);
@ -1499,6 +1506,11 @@ static void readcutscenescene(MYFILE *f, INT32 num, INT32 scenenum)
DEH_WriteUndoline(word, va("%u", cutscenes[num]->scene[scenenum].musswitchflags), UNDO_NONE); DEH_WriteUndoline(word, va("%u", cutscenes[num]->scene[scenenum].musswitchflags), UNDO_NONE);
cutscenes[num]->scene[scenenum].musswitchflags = ((UINT16)i) & MUSIC_TRACKMASK; cutscenes[num]->scene[scenenum].musswitchflags = ((UINT16)i) & MUSIC_TRACKMASK;
} }
else if (fastcmp(word, "MUSICPOS"))
{
DEH_WriteUndoline(word, va("%u", cutscenes[num]->scene[scenenum].musswitchposition), UNDO_NONE);
cutscenes[num]->scene[scenenum].musswitchposition = (UINT32)get_number(word2);
}
else if (fastcmp(word, "MUSICLOOP")) else if (fastcmp(word, "MUSICLOOP"))
{ {
DEH_WriteUndoline(word, va("%u", cutscenes[num]->scene[scenenum].musicloop), UNDO_NONE); DEH_WriteUndoline(word, va("%u", cutscenes[num]->scene[scenenum].musicloop), UNDO_NONE);
@ -6998,6 +7010,7 @@ struct {
// doomdef.h constants // doomdef.h constants
{"TICRATE",TICRATE}, {"TICRATE",TICRATE},
{"MUSICRATE",MUSICRATE},
{"RING_DIST",RING_DIST}, {"RING_DIST",RING_DIST},
{"PUSHACCEL",PUSHACCEL}, {"PUSHACCEL",PUSHACCEL},
{"MODID",MODID}, // I don't know, I just thought it would be cool for a wad to potentially know what mod it was loaded into. {"MODID",MODID}, // I don't know, I just thought it would be cool for a wad to potentially know what mod it was loaded into.
@ -8309,6 +8322,9 @@ static inline int lib_getenum(lua_State *L)
} else if (fastcmp(word,"mapmusflags")) { } else if (fastcmp(word,"mapmusflags")) {
lua_pushinteger(L, mapmusflags); lua_pushinteger(L, mapmusflags);
return 1; return 1;
} else if (fastcmp(word,"mapmusposition")) {
lua_pushinteger(L, mapmusposition);
return 1;
} else if (fastcmp(word,"server")) { } else if (fastcmp(word,"server")) {
if ((!multiplayer || !netgame) && !playeringame[serverplayer]) if ((!multiplayer || !netgame) && !playeringame[serverplayer])
return 0; return 0;

View File

@ -438,6 +438,37 @@ boolean I_SetSongSpeed(float speed)
return false; return false;
} }
/// ------------------------
// MUSIC SEEKING
/// ------------------------
UINT32 I_GetSongLength(void)
{
return 0;
}
boolean I_SetSongLoopPoint(UINT32 looppoint)
{
(void)looppoint;
return false;
}
UINT32 I_GetSongLoopPoint(void)
{
return 0;
}
boolean I_SetSongPosition(UINT32 position)
{
(void)position;
return false;
}
UINT32 I_GetSongPosition(void)
{
return 0;
}
/// ------------------------ /// ------------------------
// MUSIC PLAYBACK // MUSIC PLAYBACK
/// ------------------------ /// ------------------------
@ -545,3 +576,44 @@ int I_QrySongPlaying(int handle)
return (midi_pos==-1); return (midi_pos==-1);
} }
#endif #endif
/// ------------------------
// MUSIC FADING
/// ------------------------
void I_SetInternalMusicVolume(UINT8 volume)
{
(void)volume;
}
void I_StopFadingSong(void)
{
}
boolean I_FadeSongFromVolume(UINT8 target_volume, UINT8 source_volume, UINT32 ms, void (*callback)(void));
{
(void)target_volume;
(void)source_volume;
(void)ms;
return false;
}
boolean I_FadeSong(UINT8 target_volume, UINT32 ms, void (*callback)(void));
{
(void)target_volume;
(void)ms;
return false;
}
boolean I_FadeOutStopSong(UINT32 ms)
{
(void)ms;
return false;
}
boolean I_FadeInPlaySong(UINT32 ms, boolean looping)
{
(void)ms;
(void)looping;
return false;
}

View File

@ -150,9 +150,9 @@ extern FILE *logstream;
// we use comprevision and compbranch instead. // we use comprevision and compbranch instead.
#else #else
#define VERSION 201 // Game version #define VERSION 201 // Game version
#define SUBVERSION 23 // more precise version number #define SUBVERSION 24 // more precise version number
#define VERSIONSTRING "v2.1.23" #define VERSIONSTRING "v2.1.24"
#define VERSIONSTRINGW L"v2.1.23" #define VERSIONSTRINGW L"v2.1.24"
// Hey! If you change this, add 1 to the MODVERSION below! // Hey! If you change this, add 1 to the MODVERSION below!
// Otherwise we can't force updates! // Otherwise we can't force updates!
#endif #endif
@ -217,7 +217,7 @@ extern FILE *logstream;
// it's only for detection of the version the player is using so the MS can alert them of an update. // it's only for detection of the version the player is using so the MS can alert them of an update.
// Only set it higher, not lower, obviously. // Only set it higher, not lower, obviously.
// Note that we use this to help keep internal testing in check; this is why v2.1.0 is not version "1". // Note that we use this to help keep internal testing in check; this is why v2.1.0 is not version "1".
#define MODVERSION 28 #define MODVERSION 29
// To version config.cfg, MAJOREXECVERSION is set equal to MODVERSION automatically. // To version config.cfg, MAJOREXECVERSION is set equal to MODVERSION automatically.
// Increment MINOREXECVERSION whenever a config change is needed that does not correspond // Increment MINOREXECVERSION whenever a config change is needed that does not correspond
@ -305,6 +305,8 @@ typedef enum
#define NEWTICRATERATIO 1 // try 4 for 140 fps :) #define NEWTICRATERATIO 1 // try 4 for 140 fps :)
#define NEWTICRATE (TICRATE*NEWTICRATERATIO) #define NEWTICRATE (TICRATE*NEWTICRATERATIO)
#define MUSICRATE 1000 // sound timing is calculated by milliseconds
#define RING_DIST 512*FRACUNIT // how close you need to be to a ring to attract it #define RING_DIST 512*FRACUNIT // how close you need to be to a ring to attract it
#define PUSHACCEL (2*FRACUNIT) // Acceleration for MF2_SLIDEPUSH items. #define PUSHACCEL (2*FRACUNIT) // Acceleration for MF2_SLIDEPUSH items.

View File

@ -33,8 +33,10 @@
extern INT16 gamemap; extern INT16 gamemap;
extern char mapmusname[7]; extern char mapmusname[7];
extern UINT16 mapmusflags; extern UINT16 mapmusflags;
extern UINT32 mapmusposition;
#define MUSIC_TRACKMASK 0x0FFF // ----************ #define MUSIC_TRACKMASK 0x0FFF // ----************
#define MUSIC_RELOADRESET 0x8000 // *--------------- #define MUSIC_RELOADRESET 0x8000 // *---------------
#define MUSIC_FORCERESET 0x4000 // -*--------------
// Use other bits if necessary. // Use other bits if necessary.
extern INT16 maptol; extern INT16 maptol;
@ -145,6 +147,7 @@ typedef struct
char musswitch[7]; char musswitch[7];
UINT16 musswitchflags; UINT16 musswitchflags;
UINT32 musswitchposition;
UINT8 fadecolor; // Color number for fade, 0 means don't do the first fade UINT8 fadecolor; // Color number for fade, 0 means don't do the first fade
UINT8 fadeinid; // ID of the first fade, to a color -- ignored if fadecolor is 0 UINT8 fadeinid; // ID of the first fade, to a color -- ignored if fadecolor is 0
@ -215,6 +218,7 @@ typedef struct
INT16 nextlevel; ///< Map number of next level, or 1100-1102 to end. INT16 nextlevel; ///< Map number of next level, or 1100-1102 to end.
char musname[7]; ///< Music track to play. "" for no music. char musname[7]; ///< Music track to play. "" for no music.
UINT16 mustrack; ///< Subsong to play. Only really relevant for music modules and specific formats supported by GME. 0 to ignore. UINT16 mustrack; ///< Subsong to play. Only really relevant for music modules and specific formats supported by GME. 0 to ignore.
UINT32 muspos; ///< Music position to jump to.
char forcecharacter[17]; ///< (SKINNAMESIZE+1) Skin to switch to or "" to disable. char forcecharacter[17]; ///< (SKINNAMESIZE+1) Skin to switch to or "" to disable.
UINT8 weather; ///< 0 = sunny day, 1 = storm, 2 = snow, 3 = rain, 4 = blank, 5 = thunder w/o rain, 6 = rain w/o lightning, 7 = heat wave. UINT8 weather; ///< 0 = sunny day, 1 = storm, 2 = snow, 3 = rain, 4 = blank, 5 = thunder w/o rain, 6 = rain w/o lightning, 7 = heat wave.
INT16 skynum; ///< Sky number to use. INT16 skynum; ///< Sky number to use.
@ -243,6 +247,10 @@ typedef struct
UINT8 numGradedMares; ///< Internal. For grade support. UINT8 numGradedMares; ///< Internal. For grade support.
nightsgrades_t *grades; ///< NiGHTS grades. Allocated dynamically for space reasons. Be careful. nightsgrades_t *grades; ///< NiGHTS grades. Allocated dynamically for space reasons. Be careful.
// Music stuff.
UINT32 musinterfadeout; ///< Fade out level music on intermission screen in milliseconds
char musintername[7]; ///< Intermission screen music.
// Lua stuff. // Lua stuff.
// (This is not ifdeffed so the map header structure can stay identical, just in case.) // (This is not ifdeffed so the map header structure can stay identical, just in case.)
UINT8 numCustomOptions; ///< Internal. For Lua custom value support. UINT8 numCustomOptions; ///< Internal. For Lua custom value support.
@ -310,7 +318,10 @@ enum GameType
NUMGAMETYPES NUMGAMETYPES
}; };
// If you alter this list, update gametype_cons_t in m_menu.c // If you alter this list, update dehacked.c, and Gametype_Names in g_game.c
// String names for gametypes
extern const char *Gametype_Names[NUMGAMETYPES];
extern tic_t totalplaytime; extern tic_t totalplaytime;

View File

@ -95,6 +95,37 @@ boolean I_SetSongSpeed(float speed)
return false; return false;
} }
/// ------------------------
// MUSIC SEEKING
/// ------------------------
UINT32 I_GetSongLength(void)
{
return 0;
}
boolean I_SetSongLoopPoint(UINT32 looppoint)
{
(void)looppoint;
return false;
}
UINT32 I_GetSongLoopPoint(void)
{
return 0;
}
boolean I_SetSongPosition(UINT32 position)
{
(void)position;
return false;
}
UINT32 I_GetSongPosition(void)
{
return 0;
}
/// ------------------------ /// ------------------------
// MUSIC PLAYBACK // MUSIC PLAYBACK
/// ------------------------ /// ------------------------
@ -142,4 +173,45 @@ boolean I_SetSongTrack(int track)
{ {
(void)track; (void)track;
return false; return false;
} }
/// ------------------------
// MUSIC FADING
/// ------------------------
void I_SetInternalMusicVolume(UINT8 volume)
{
(void)volume;
}
void I_StopFadingSong(void)
{
}
boolean I_FadeSongFromVolume(UINT8 target_volume, UINT8 source_volume, UINT32 ms, void (*callback)(void));
{
(void)target_volume;
(void)source_volume;
(void)ms;
return false;
}
boolean I_FadeSong(UINT8 target_volume, UINT32 ms, void (*callback)(void));
{
(void)target_volume;
(void)ms;
return false;
}
boolean I_FadeOutStopSong(UINT32 ms)
{
(void)ms;
return false;
}
boolean I_FadeInPlaySong(UINT32 ms, boolean looping)
{
(void)ms;
(void)looping;
return false;
}

View File

@ -995,6 +995,7 @@ static const char *credits[] = {
"Andrew \"orospakr\" Clunis", "Andrew \"orospakr\" Clunis",
"Gregor \"Oogaland\" Dick", "Gregor \"Oogaland\" Dick",
"Louis-Antoine \"LJSonic\" de Moulins", // for fixing 2.1's netcode (de Rochefort doesn't quite fit on the screen sorry lol) "Louis-Antoine \"LJSonic\" de Moulins", // for fixing 2.1's netcode (de Rochefort doesn't quite fit on the screen sorry lol)
"Victor \"Steel Titanium\" Fuentes",
"Julio \"Chaos Zero 64\" Guir", "Julio \"Chaos Zero 64\" Guir",
"\"Jimita\"", "\"Jimita\"",
"\"Kalaron\"", // Coded some of Sryder13's collection of OpenGL fixes, especially fog "\"Kalaron\"", // Coded some of Sryder13's collection of OpenGL fixes, especially fog
@ -1005,7 +1006,6 @@ static const char *credits[] = {
"Colin \"Sonict\" Pfaff", "Colin \"Sonict\" Pfaff",
"Sean \"Sryder13\" Ryder", "Sean \"Sryder13\" Ryder",
"Tasos \"tatokis\" Sahanidis", // Corrected C FixedMul, making 64-bit builds netplay compatible "Tasos \"tatokis\" Sahanidis", // Corrected C FixedMul, making 64-bit builds netplay compatible
"\"Steel Titanium\"",
"Ben \"Cue\" Woodford", "Ben \"Cue\" Woodford",
// Git contributors with 5+ approved merges of substantive quality, // Git contributors with 5+ approved merges of substantive quality,
// or contributors with at least one groundbreaking merge, may be named. // or contributors with at least one groundbreaking merge, may be named.
@ -1054,12 +1054,12 @@ static const char *credits[] = {
"Dan \"Blitzzo\" Hagerstrand", "Dan \"Blitzzo\" Hagerstrand",
"Kepa \"Nev3r\" Iceta", "Kepa \"Nev3r\" Iceta",
"Thomas \"Shadow Hog\" Igoe", "Thomas \"Shadow Hog\" Igoe",
"Erik \"Torgo\" Nielsen",
"\"Kaito Sinclaire\"", "\"Kaito Sinclaire\"",
"Wessel \"sphere\" Smit", "Wessel \"sphere\" Smit",
"\"Spazzo\"", "\"Spazzo\"",
"\"SSNTails\"", "\"SSNTails\"",
"Rob Tisdell", "Rob Tisdell",
"\"Torgo\"",
"Jarrett \"JEV3\" Voight", "Jarrett \"JEV3\" Voight",
"Johnny \"Sonikku\" Wallbank", "Johnny \"Sonikku\" Wallbank",
"Marco \"mazmazz\" Zafra", "Marco \"mazmazz\" Zafra",
@ -1741,9 +1741,10 @@ static void F_AdvanceToNextScene(void)
picypos = cutscenes[cutnum]->scene[scenenum].ycoord[picnum]; picypos = cutscenes[cutnum]->scene[scenenum].ycoord[picnum];
if (cutscenes[cutnum]->scene[scenenum].musswitch[0]) if (cutscenes[cutnum]->scene[scenenum].musswitch[0])
S_ChangeMusic(cutscenes[cutnum]->scene[scenenum].musswitch, S_ChangeMusicEx(cutscenes[cutnum]->scene[scenenum].musswitch,
cutscenes[cutnum]->scene[scenenum].musswitchflags, cutscenes[cutnum]->scene[scenenum].musswitchflags,
cutscenes[cutnum]->scene[scenenum].musicloop); cutscenes[cutnum]->scene[scenenum].musicloop,
cutscenes[cutnum]->scene[scenenum].musswitchposition, 0, 0);
// Fade to the next // Fade to the next
dofadenow = true; dofadenow = true;
@ -1812,9 +1813,10 @@ void F_StartCustomCutscene(INT32 cutscenenum, boolean precutscene, boolean reset
stoptimer = 0; stoptimer = 0;
if (cutscenes[cutnum]->scene[0].musswitch[0]) if (cutscenes[cutnum]->scene[0].musswitch[0])
S_ChangeMusic(cutscenes[cutnum]->scene[0].musswitch, S_ChangeMusicEx(cutscenes[cutnum]->scene[0].musswitch,
cutscenes[cutnum]->scene[0].musswitchflags, cutscenes[cutnum]->scene[0].musswitchflags,
cutscenes[cutnum]->scene[0].musicloop); cutscenes[cutnum]->scene[0].musicloop,
cutscenes[cutnum]->scene[scenenum].musswitchposition, 0, 0);
else else
S_StopMusic(); S_StopMusic();
} }

View File

@ -71,6 +71,7 @@ static void G_DoWorldDone(void);
char mapmusname[7]; // Music name char mapmusname[7]; // Music name
UINT16 mapmusflags; // Track and reset bit UINT16 mapmusflags; // Track and reset bit
UINT32 mapmusposition; // Position to jump to
INT16 gamemap = 1; INT16 gamemap = 1;
INT16 maptol; INT16 maptol;
@ -2268,9 +2269,14 @@ void G_PlayerReborn(INT32 player)
{ {
strncpy(mapmusname, mapheaderinfo[gamemap-1]->musname, 7); strncpy(mapmusname, mapheaderinfo[gamemap-1]->musname, 7);
mapmusname[6] = 0; mapmusname[6] = 0;
mapmusflags = mapheaderinfo[gamemap-1]->mustrack & MUSIC_TRACKMASK; mapmusflags = (mapheaderinfo[gamemap-1]->mustrack & MUSIC_TRACKMASK);
mapmusposition = mapheaderinfo[gamemap-1]->muspos;
} }
S_ChangeMusic(mapmusname, mapmusflags, true);
// This is in S_Start, but this was not here previously.
// if (cv_resetmusic.value)
// S_StopMusic();
S_ChangeMusicEx(mapmusname, mapmusflags, true, mapmusposition, 0, 0);
} }
if (gametype == GT_COOP) if (gametype == GT_COOP)
@ -2692,6 +2698,38 @@ void G_ExitLevel(void)
} }
} }
// See also the enum GameType in doomstat.h
const char *Gametype_Names[NUMGAMETYPES] =
{
"Co-op", // GT_COOP
"Competition", // GT_COMPETITION
"Race", // GT_RACE
"Match", // GT_MATCH
"Team Match", // GT_TEAMMATCH
"Tag", // GT_TAG
"Hide and Seek", // GT_HIDEANDSEEK
"CTF" // GT_CTF
};
//
// G_GetGametypeByName
//
// Returns the number for the given gametype name string, or -1 if not valid.
//
INT32 G_GetGametypeByName(const char *gametypestr)
{
INT32 i;
for (i = 0; i < NUMGAMETYPES; i++)
if (!stricmp(gametypestr, Gametype_Names[i]))
return i;
return -1; // unknown gametype
}
// //
// G_IsSpecialStage // G_IsSpecialStage
// //

View File

@ -163,6 +163,7 @@ ATTRNORETURN void FUNCNORETURN G_StopMetalRecording(void);
void G_StopDemo(void); void G_StopDemo(void);
boolean G_CheckDemoStatus(void); boolean G_CheckDemoStatus(void);
INT32 G_GetGametypeByName(const char *gametypestr);
boolean G_IsSpecialStage(INT32 mapnum); boolean G_IsSpecialStage(INT32 mapnum);
boolean G_GametypeUsesLives(void); boolean G_GametypeUsesLives(void);
boolean G_GametypeHasTeams(void); boolean G_GametypeHasTeams(void);

View File

@ -1082,21 +1082,24 @@ UINT8 *HWR_GetScreenshot(void)
return buf; return buf;
} }
boolean HWR_Screenshot(const char *lbmname) boolean HWR_Screenshot(const char *pathname)
{ {
boolean ret; boolean ret;
UINT8 *buf = malloc(vid.width * vid.height * 3 * sizeof (*buf)); UINT8 *buf = malloc(vid.width * vid.height * 3 * sizeof (*buf));
if (!buf) if (!buf)
{
CONS_Debug(DBG_RENDER, "HWR_Screenshot: Failed to allocate memory\n");
return false; return false;
}
// returns 24bit 888 RGB // returns 24bit 888 RGB
HWD.pfnReadRect(0, 0, vid.width, vid.height, vid.width * 3, (void *)buf); HWD.pfnReadRect(0, 0, vid.width, vid.height, vid.width * 3, (void *)buf);
#ifdef USE_PNG #ifdef USE_PNG
ret = M_SavePNG(lbmname, buf, vid.width, vid.height, NULL); ret = M_SavePNG(pathname, buf, vid.width, vid.height, NULL);
#else #else
ret = saveTGA(lbmname, buf, vid.width, vid.height); ret = saveTGA(pathname, buf, vid.width, vid.height);
#endif #endif
free(buf); free(buf);
return ret; return ret;

View File

@ -38,8 +38,6 @@ void HWR_RenderSkyboxView(INT32 viewnumber, player_t *player);
void HWR_RenderPlayerView(INT32 viewnumber, player_t *player); void HWR_RenderPlayerView(INT32 viewnumber, player_t *player);
void HWR_DrawViewBorder(INT32 clearlines); void HWR_DrawViewBorder(INT32 clearlines);
void HWR_DrawFlatFill(INT32 x, INT32 y, INT32 w, INT32 h, lumpnum_t flatlumpnum); 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_InitTextureMapping(void);
void HWR_SetViewSize(void); void HWR_SetViewSize(void);
void HWR_DrawPatch(GLPatch_t *gpatch, INT32 x, INT32 y, INT32 option); 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_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); 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_AddCommands(void);
void HWR_CorrectSWTricks(void); void HWR_CorrectSWTricks(void);
void transform(float *cx, float *cy, float *cz); void transform(float *cx, float *cy, float *cz);

View File

@ -1944,19 +1944,17 @@ static void HU_DrawCEcho(void)
static void HU_drawGametype(void) static void HU_drawGametype(void)
{ {
INT32 i = 0; const char *strvalue = NULL;
for (i = 0; gametype_cons_t[i].strvalue; i++) if (gametype < 0 || gametype >= NUMGAMETYPES)
{ return; // not a valid gametype???
if (gametype_cons_t[i].value == gametype)
{ strvalue = Gametype_Names[gametype];
if (splitscreen)
V_DrawString(4, 184, 0, gametype_cons_t[i].strvalue); if (splitscreen)
else V_DrawString(4, 184, 0, strvalue);
V_DrawString(4, 192, 0, gametype_cons_t[i].strvalue); else
return; V_DrawString(4, 192, 0, strvalue);
}
}
} }
// //

View File

@ -146,6 +146,18 @@ boolean I_SongPaused(void);
boolean I_SetSongSpeed(float speed); boolean I_SetSongSpeed(float speed);
/// ------------------------
// MUSIC SEEKING
/// ------------------------
UINT32 I_GetSongLength(void);
boolean I_SetSongLoopPoint(UINT32 looppoint);
UINT32 I_GetSongLoopPoint(void);
boolean I_SetSongPosition(UINT32 position);
UINT32 I_GetSongPosition(void);
/// ------------------------ /// ------------------------
// MUSIC PLAYBACK // MUSIC PLAYBACK
/// ------------------------ /// ------------------------
@ -216,6 +228,17 @@ void I_SetMusicVolume(UINT8 volume);
boolean I_SetSongTrack(INT32 track); boolean I_SetSongTrack(INT32 track);
/// ------------------------
/// MUSIC FADING
/// ------------------------
void I_SetInternalMusicVolume(UINT8 volume);
void I_StopFadingSong(void);
boolean I_FadeSongFromVolume(UINT8 target_volume, UINT8 source_volume, UINT32 ms, void (*callback)(void));
boolean I_FadeSong(UINT8 target_volume, UINT32 ms, void (*callback)(void));
boolean I_FadeOutStopSong(UINT32 ms);
boolean I_FadeInPlaySong(UINT32 ms, boolean looping);
/// ------------------------ /// ------------------------
// CD MUSIC I/O // CD MUSIC I/O
/// ------------------------ /// ------------------------

View File

@ -210,7 +210,7 @@ void A_NapalmScatter();
void A_SpawnFreshCopy(); void A_SpawnFreshCopy();
// ratio of states to sprites to mobj types is roughly 6 : 1 : 1 // ratio of states to sprites to mobj types is roughly 6 : 1 : 1
#define NUMMOBJFREESLOTS 256 #define NUMMOBJFREESLOTS 512
#define NUMSPRITEFREESLOTS NUMMOBJFREESLOTS #define NUMSPRITEFREESLOTS NUMMOBJFREESLOTS
#define NUMSTATEFREESLOTS (NUMMOBJFREESLOTS*8) #define NUMSTATEFREESLOTS (NUMMOBJFREESLOTS*8)

View File

@ -780,7 +780,8 @@ static int lib_pRestoreMusic(lua_State *L)
NOHUD NOHUD
if (!player) if (!player)
return LUA_ErrInvalid(L, "player_t"); return LUA_ErrInvalid(L, "player_t");
P_RestoreMusic(player); if (P_IsLocalPlayer(player))
P_RestoreMusic(player);
return 0; return 0;
} }
@ -1820,7 +1821,7 @@ static int lib_sChangeMusic(lua_State *L)
{ {
#ifdef MUSICSLOT_COMPATIBILITY #ifdef MUSICSLOT_COMPATIBILITY
const char *music_name; const char *music_name;
UINT32 music_num; UINT32 music_num, position, prefadems, fadeinms;
char music_compat_name[7]; char music_compat_name[7];
boolean looping; boolean looping;
@ -1848,7 +1849,6 @@ static int lib_sChangeMusic(lua_State *L)
music_name = luaL_checkstring(L, 1); music_name = luaL_checkstring(L, 1);
} }
looping = (boolean)lua_opttrueboolean(L, 2); looping = (boolean)lua_opttrueboolean(L, 2);
#else #else
@ -1873,8 +1873,12 @@ static int lib_sChangeMusic(lua_State *L)
#endif #endif
music_flags = (UINT16)luaL_optinteger(L, 4, 0); music_flags = (UINT16)luaL_optinteger(L, 4, 0);
position = (UINT32)luaL_optinteger(L, 5, 0);
prefadems = (UINT32)luaL_optinteger(L, 6, 0);
fadeinms = (UINT32)luaL_optinteger(L, 7, 0);
if (!player || P_IsLocalPlayer(player)) if (!player || P_IsLocalPlayer(player))
S_ChangeMusic(music_name, music_flags, looping); S_ChangeMusicEx(music_name, music_flags, looping, position, prefadems, fadeinms);
return 0; return 0;
} }
@ -1891,10 +1895,8 @@ static int lib_sSpeedMusic(lua_State *L)
return LUA_ErrInvalid(L, "player_t"); return LUA_ErrInvalid(L, "player_t");
} }
if (!player || P_IsLocalPlayer(player)) if (!player || P_IsLocalPlayer(player))
lua_pushboolean(L, S_SpeedMusic(speed)); S_SpeedMusic(speed);
else return 0;
lua_pushboolean(L, false);
return 1;
} }
static int lib_sStopMusic(lua_State *L) static int lib_sStopMusic(lua_State *L)
@ -1912,6 +1914,110 @@ static int lib_sStopMusic(lua_State *L)
return 0; return 0;
} }
static int lib_sSetInternalMusicVolume(lua_State *L)
{
UINT32 volume = (UINT32)luaL_checkinteger(L, 1);
player_t *player = NULL;
NOHUD
if (!lua_isnone(L, 2) && lua_isuserdata(L, 2))
{
player = *((player_t **)luaL_checkudata(L, 2, META_PLAYER));
if (!player)
return LUA_ErrInvalid(L, "player_t");
}
if (!player || P_IsLocalPlayer(player))
{
S_SetInternalMusicVolume(volume);
lua_pushboolean(L, true);
}
else
lua_pushnil(L);
return 1;
}
static int lib_sStopFadingMusic(lua_State *L)
{
player_t *player = NULL;
NOHUD
if (!lua_isnone(L, 1) && lua_isuserdata(L, 1))
{
player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
if (!player)
return LUA_ErrInvalid(L, "player_t");
}
if (!player || P_IsLocalPlayer(player))
{
S_StopFadingMusic();
lua_pushboolean(L, true);
}
else
lua_pushnil(L);
return 1;
}
static int lib_sFadeMusic(lua_State *L)
{
UINT32 target_volume = (UINT32)luaL_checkinteger(L, 1);
UINT32 ms;
INT32 source_volume;
player_t *player = NULL;
NOHUD
if (!lua_isnone(L, 3) && lua_isuserdata(L, 3))
{
player = *((player_t **)luaL_checkudata(L, 3, META_PLAYER));
if (!player)
return LUA_ErrInvalid(L, "player_t");
ms = (UINT32)luaL_checkinteger(L, 2);
source_volume = -1;
}
else if (!lua_isnone(L, 4) && lua_isuserdata(L, 4))
{
player = *((player_t **)luaL_checkudata(L, 4, META_PLAYER));
if (!player)
return LUA_ErrInvalid(L, "player_t");
source_volume = (INT32)luaL_checkinteger(L, 2);
ms = (UINT32)luaL_checkinteger(L, 3);
}
else if (luaL_optinteger(L, 3, INT32_MAX) == INT32_MAX)
{
ms = (UINT32)luaL_checkinteger(L, 2);
source_volume = -1;
}
else
{
source_volume = (INT32)luaL_checkinteger(L, 2);
ms = (UINT32)luaL_checkinteger(L, 3);
}
NOHUD
if (!player || P_IsLocalPlayer(player))
lua_pushboolean(L, S_FadeMusicFromVolume(target_volume, source_volume, ms));
else
lua_pushnil(L);
return 1;
}
static int lib_sFadeOutStopMusic(lua_State *L)
{
UINT32 ms = (UINT32)luaL_checkinteger(L, 1);
player_t *player = NULL;
NOHUD
if (!lua_isnone(L, 2) && lua_isuserdata(L, 2))
{
player = *((player_t **)luaL_checkudata(L, 2, META_PLAYER));
if (!player)
return LUA_ErrInvalid(L, "player_t");
}
if (!player || P_IsLocalPlayer(player))
{
lua_pushboolean(L, S_FadeOutStopMusic(ms));
}
else
lua_pushnil(L);
return 1;
}
static int lib_sOriginPlaying(lua_State *L) static int lib_sOriginPlaying(lua_State *L)
{ {
void *origin = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); void *origin = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
@ -2264,6 +2370,10 @@ static luaL_Reg lib[] = {
{"S_ChangeMusic",lib_sChangeMusic}, {"S_ChangeMusic",lib_sChangeMusic},
{"S_SpeedMusic",lib_sSpeedMusic}, {"S_SpeedMusic",lib_sSpeedMusic},
{"S_StopMusic",lib_sStopMusic}, {"S_StopMusic",lib_sStopMusic},
{"S_SetInternalMusicVolume", lib_sSetInternalMusicVolume},
{"S_StopFadingMusic",lib_sStopFadingMusic},
{"S_FadeMusic",lib_sFadeMusic},
{"S_FadeOutStopMusic",lib_sFadeOutStopMusic},
{"S_OriginPlaying",lib_sOriginPlaying}, {"S_OriginPlaying",lib_sOriginPlaying},
{"S_IdPlaying",lib_sIdPlaying}, {"S_IdPlaying",lib_sIdPlaying},
{"S_SoundPlaying",lib_sSoundPlaying}, {"S_SoundPlaying",lib_sSoundPlaying},

View File

@ -1468,6 +1468,12 @@ static int mapheaderinfo_get(lua_State *L)
lua_pushstring(L, header->musname); lua_pushstring(L, header->musname);
else if (fastcmp(field,"mustrack")) else if (fastcmp(field,"mustrack"))
lua_pushinteger(L, header->mustrack); lua_pushinteger(L, header->mustrack);
else if (fastcmp(field,"muspos"))
lua_pushinteger(L, header->muspos);
else if (fastcmp(field,"musinterfadeout"))
lua_pushinteger(L, header->musinterfadeout);
else if (fastcmp(field,"musintername"))
lua_pushstring(L, header->musintername);
else if (fastcmp(field,"forcecharacter")) else if (fastcmp(field,"forcecharacter"))
lua_pushstring(L, header->forcecharacter); lua_pushstring(L, header->forcecharacter);
else if (fastcmp(field,"weather")) else if (fastcmp(field,"weather"))

View File

@ -112,41 +112,8 @@ typedef enum
const char *quitmsg[NUM_QUITMESSAGES]; const char *quitmsg[NUM_QUITMESSAGES];
// Stuff for customizing the player select screen Tails 09-22-2003 // Stuff for customizing the player select screen Tails 09-22-2003
description_t description[32] = description_t description[MAXSKINS];
{
{"\x82Sonic\x80 is the fastest of the three, but also the hardest to control. Beginners beware, but experts will find Sonic very powerful.\n\n\x82""Ability:\x80 Speed Thok\nDouble jump to zoom forward with a huge burst of speed.\n\n\x82Tip:\x80 Simply letting go of forward does not slow down in SRB2. To slow down, hold the opposite direction.", "", "sonic"},
{"\x82Tails\x80 is the most mobile of the three, but has the slowest speed. Because of his mobility, he's well-\nsuited to beginners.\n\n\x82""Ability:\x80 Fly\nDouble jump to start flying for a limited time. Repetitively hit the jump button to ascend.\n\n\x82Tip:\x80 To quickly descend while flying, hit the spin button.", "", "tails"},
{"\x82Knuckles\x80 is well-\nrounded and can destroy breakable walls simply by touching them, but he can't jump as high as the other two.\n\n\x82""Ability:\x80 Glide & Climb\nDouble jump to glide in the air as long as jump is held. Glide into a wall to climb it.\n\n\x82Tip:\x80 Press spin while climbing to jump off the wall; press jump instead to jump off\nand face away from\nthe wall.", "", "knuckles"},
{"\x82Sonic & Tails\x80 team up to take on Dr. Eggman!\nControl Sonic while Tails desperately struggles to keep up.\n\nPlayer 2 can control Tails directly by setting the controls in the options menu.\nTails's directional controls are relative to Player 1's camera.\n\nTails can pick up Sonic while flying and carry him around.", "CHRS&T", "sonic&tails"},
{"???", "", ""},
{"???", "", ""},
{"???", "", ""},
{"???", "", ""},
{"???", "", ""},
{"???", "", ""},
{"???", "", ""},
{"???", "", ""},
{"???", "", ""},
{"???", "", ""},
{"???", "", ""},
{"???", "", ""},
{"???", "", ""},
{"???", "", ""},
{"???", "", ""},
{"???", "", ""},
{"???", "", ""},
{"???", "", ""},
{"???", "", ""},
{"???", "", ""},
{"???", "", ""},
{"???", "", ""},
{"???", "", ""},
{"???", "", ""},
{"???", "", ""},
{"???", "", ""},
{"???", "", ""},
{"???", "", ""}
};
static char *char_notes = NULL; static char *char_notes = NULL;
static fixed_t char_scroll = 0; static fixed_t char_scroll = 0;
@ -380,23 +347,9 @@ static CV_PossibleValue_t skins_cons_t[MAXSKINS+1] = {{1, DEFAULTSKIN}};
consvar_t cv_chooseskin = {"chooseskin", DEFAULTSKIN, CV_HIDEN|CV_CALL, skins_cons_t, Nextmap_OnChange, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_chooseskin = {"chooseskin", DEFAULTSKIN, CV_HIDEN|CV_CALL, skins_cons_t, Nextmap_OnChange, 0, NULL, NULL, 0, 0, NULL};
// This gametype list is integral for many different reasons. // This gametype list is integral for many different reasons.
// When you add gametypes here, don't forget to update them in CV_AddValue! // When you add gametypes here, don't forget to update them in dehacked.c and doomstat.h!
CV_PossibleValue_t gametype_cons_t[] = CV_PossibleValue_t gametype_cons_t[NUMGAMETYPES+1];
{
{GT_COOP, "Co-op"},
{GT_COMPETITION, "Competition"},
{GT_RACE, "Race"},
{GT_MATCH, "Match"},
{GT_TEAMMATCH, "Team Match"},
{GT_TAG, "Tag"},
{GT_HIDEANDSEEK, "Hide and Seek"},
{GT_CTF, "CTF"},
{0, NULL}
};
consvar_t cv_newgametype = {"newgametype", "Co-op", CV_HIDEN|CV_CALL, gametype_cons_t, Newgametype_OnChange, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_newgametype = {"newgametype", "Co-op", CV_HIDEN|CV_CALL, gametype_cons_t, Newgametype_OnChange, 0, NULL, NULL, 0, 0, NULL};
static CV_PossibleValue_t serversort_cons_t[] = { static CV_PossibleValue_t serversort_cons_t[] = {
@ -842,41 +795,7 @@ static menuitem_t SP_LevelStatsMenu[] =
// A rare case. // A rare case.
// External files modify this menu, so we can't call it static. // External files modify this menu, so we can't call it static.
// And I'm too lazy to go through and rename it everywhere. ARRGH! // And I'm too lazy to go through and rename it everywhere. ARRGH!
menuitem_t PlayerMenu[32] = menuitem_t PlayerMenu[MAXSKINS];
{
{IT_CALL, NULL, NULL, M_ChoosePlayer, 0},
{IT_CALL, NULL, NULL, M_ChoosePlayer, 0},
{IT_CALL, NULL, NULL, M_ChoosePlayer, 0},
{IT_CALL, NULL, NULL, M_ChoosePlayer, 0},
{IT_DISABLED, NULL, NULL, M_ChoosePlayer, 0},
{IT_DISABLED, NULL, NULL, M_ChoosePlayer, 0},
{IT_DISABLED, NULL, NULL, M_ChoosePlayer, 0},
{IT_DISABLED, NULL, NULL, M_ChoosePlayer, 0},
{IT_DISABLED, NULL, NULL, M_ChoosePlayer, 0},
{IT_DISABLED, NULL, NULL, M_ChoosePlayer, 0},
{IT_DISABLED, NULL, NULL, M_ChoosePlayer, 0},
{IT_DISABLED, NULL, NULL, M_ChoosePlayer, 0},
{IT_DISABLED, NULL, NULL, M_ChoosePlayer, 0},
{IT_DISABLED, NULL, NULL, M_ChoosePlayer, 0},
{IT_DISABLED, NULL, NULL, M_ChoosePlayer, 0},
{IT_DISABLED, NULL, NULL, M_ChoosePlayer, 0},
{IT_DISABLED, NULL, NULL, M_ChoosePlayer, 0},
{IT_DISABLED, NULL, NULL, M_ChoosePlayer, 0},
{IT_DISABLED, NULL, NULL, M_ChoosePlayer, 0},
{IT_DISABLED, NULL, NULL, M_ChoosePlayer, 0},
{IT_DISABLED, NULL, NULL, M_ChoosePlayer, 0},
{IT_DISABLED, NULL, NULL, M_ChoosePlayer, 0},
{IT_DISABLED, NULL, NULL, M_ChoosePlayer, 0},
{IT_DISABLED, NULL, NULL, M_ChoosePlayer, 0},
{IT_DISABLED, NULL, NULL, M_ChoosePlayer, 0},
{IT_DISABLED, NULL, NULL, M_ChoosePlayer, 0},
{IT_DISABLED, NULL, NULL, M_ChoosePlayer, 0},
{IT_DISABLED, NULL, NULL, M_ChoosePlayer, 0},
{IT_DISABLED, NULL, NULL, M_ChoosePlayer, 0},
{IT_DISABLED, NULL, NULL, M_ChoosePlayer, 0},
{IT_DISABLED, NULL, NULL, M_ChoosePlayer, 0},
{IT_DISABLED, NULL, NULL, M_ChoosePlayer, 0}
};
// ----------------------------------- // -----------------------------------
// Multiplayer and all of its submenus // Multiplayer and all of its submenus
@ -2864,6 +2783,55 @@ void M_Init(void)
CV_RegisterVar(&cv_allcaps); CV_RegisterVar(&cv_allcaps);
} }
void M_InitCharacterTables(void)
{
UINT8 i;
// Setup PlayerMenu table
for (i = 0; i < MAXSKINS; i++)
{
PlayerMenu[i].status = (i < 4 ? IT_CALL : IT_DISABLED);
PlayerMenu[i].patch = PlayerMenu[i].text = NULL;
PlayerMenu[i].itemaction = M_ChoosePlayer;
PlayerMenu[i].alphaKey = 0;
}
// Setup description table
for (i = 0; i < MAXSKINS; i++)
{
if (i == 0)
{
strcpy(description[i].notes, "\x82Sonic\x80 is the fastest of the three, but also the hardest to control. Beginners beware, but experts will find Sonic very powerful.\n\n\x82""Ability:\x80 Speed Thok\nDouble jump to zoom forward with a huge burst of speed.\n\n\x82Tip:\x80 Simply letting go of forward does not slow down in SRB2. To slow down, hold the opposite direction.");
strcpy(description[i].picname, "");
strcpy(description[i].skinname, "sonic");
}
else if (i == 1)
{
strcpy(description[i].notes, "\x82Tails\x80 is the most mobile of the three, but has the slowest speed. Because of his mobility, he's well-\nsuited to beginners.\n\n\x82""Ability:\x80 Fly\nDouble jump to start flying for a limited time. Repetitively hit the jump button to ascend.\n\n\x82Tip:\x80 To quickly descend while flying, hit the spin button.");
strcpy(description[i].picname, "");
strcpy(description[i].skinname, "tails");
}
else if (i == 2)
{
strcpy(description[i].notes, "\x82Knuckles\x80 is well-\nrounded and can destroy breakable walls simply by touching them, but he can't jump as high as the other two.\n\n\x82""Ability:\x80 Glide & Climb\nDouble jump to glide in the air as long as jump is held. Glide into a wall to climb it.\n\n\x82Tip:\x80 Press spin while climbing to jump off the wall; press jump instead to jump off\nand face away from\nthe wall.");
strcpy(description[i].picname, "");
strcpy(description[i].skinname, "knuckles");
}
else if (i == 3)
{
strcpy(description[i].notes, "\x82Sonic & Tails\x80 team up to take on Dr. Eggman!\nControl Sonic while Tails desperately struggles to keep up.\n\nPlayer 2 can control Tails directly by setting the controls in the options menu.\nTails's directional controls are relative to Player 1's camera.\n\nTails can pick up Sonic while flying and carry him around.");
strcpy(description[i].picname, "CHRS&T");
strcpy(description[i].skinname, "sonic&tails");
}
else
{
strcpy(description[i].notes, "???");
strcpy(description[i].picname, "");
strcpy(description[i].skinname, "");
}
}
}
// ========================================================================== // ==========================================================================
// SPECIAL MENU OPTION DRAW ROUTINES GO HERE // SPECIAL MENU OPTION DRAW ROUTINES GO HERE
// ========================================================================== // ==========================================================================
@ -6563,7 +6531,7 @@ static void M_DrawRoomMenu(void)
static void M_DrawConnectMenu(void) static void M_DrawConnectMenu(void)
{ {
UINT16 i, j; UINT16 i;
const char *gt = "Unknown"; const char *gt = "Unknown";
INT32 numPages = (serverlistcount+(SERVERS_PER_PAGE-1))/SERVERS_PER_PAGE; INT32 numPages = (serverlistcount+(SERVERS_PER_PAGE-1))/SERVERS_PER_PAGE;
@ -6609,11 +6577,8 @@ static void M_DrawConnectMenu(void)
va("Ping: %u", (UINT32)LONG(serverlist[slindex].info.time))); va("Ping: %u", (UINT32)LONG(serverlist[slindex].info.time)));
gt = "Unknown"; gt = "Unknown";
for (j = 0; gametype_cons_t[j].strvalue; j++) if (serverlist[slindex].info.gametype < NUMGAMETYPES)
{ gt = Gametype_Names[serverlist[slindex].info.gametype];
if (gametype_cons_t[j].value == serverlist[slindex].info.gametype)
gt = gametype_cons_t[j].strvalue;
}
V_DrawSmallString(currentMenu->x+46,S_LINEY(i)+8, globalflags, V_DrawSmallString(currentMenu->x+46,S_LINEY(i)+8, globalflags,
va("Players: %02d/%02d", serverlist[slindex].info.numberofplayer, serverlist[slindex].info.maxplayer)); va("Players: %02d/%02d", serverlist[slindex].info.numberofplayer, serverlist[slindex].info.maxplayer));

View File

@ -38,6 +38,9 @@ void M_Drawer(void);
// Called by D_SRB2Main, loads the config file. // Called by D_SRB2Main, loads the config file.
void M_Init(void); void M_Init(void);
// Called by D_SRB2Main also, sets up the playermenu and description tables.
void M_InitCharacterTables(void);
// Called by intro code to force menu up upon a keypress, // Called by intro code to force menu up upon a keypress,
// does nothing if menu is already up. // does nothing if menu is already up.
void M_StartControlPanel(void); void M_StartControlPanel(void);
@ -151,7 +154,7 @@ typedef struct menuitem_s
UINT8 alphaKey; UINT8 alphaKey;
} menuitem_t; } menuitem_t;
extern menuitem_t PlayerMenu[32]; extern menuitem_t PlayerMenu[MAXSKINS];
typedef struct menu_s typedef struct menu_s
{ {
@ -206,7 +209,7 @@ typedef struct
UINT8 netgame; UINT8 netgame;
} saveinfo_t; } saveinfo_t;
extern description_t description[32]; extern description_t description[MAXSKINS];
extern consvar_t cv_newgametype, cv_nextmap, cv_chooseskin, cv_serversort; extern consvar_t cv_newgametype, cv_nextmap, cv_chooseskin, cv_serversort;
extern CV_PossibleValue_t gametype_cons_t[]; extern CV_PossibleValue_t gametype_cons_t[];

View File

@ -30,6 +30,7 @@
#include "g_game.h" #include "g_game.h"
#include "m_misc.h" #include "m_misc.h"
#include "hu_stuff.h" #include "hu_stuff.h"
#include "st_stuff.h"
#include "v_video.h" #include "v_video.h"
#include "z_zone.h" #include "z_zone.h"
#include "g_input.h" #include "g_input.h"
@ -586,6 +587,21 @@ void M_SaveConfig(const char *filename)
fclose(f); 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 = pLocalPalette[(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 #if NUMSCREENS > 2
static const char *Newsnapshotfile(const char *pathname, const char *ext) static const char *Newsnapshotfile(const char *pathname, const char *ext)
@ -1016,6 +1032,7 @@ static boolean M_SetupaPNG(png_const_charp filename, png_bytep pal)
static inline moviemode_t M_StartMovieAPNG(const char *pathname) static inline moviemode_t M_StartMovieAPNG(const char *pathname)
{ {
#ifdef USE_APNG #ifdef USE_APNG
UINT8 *palette = NULL;
const char *freename = NULL; const char *freename = NULL;
boolean ret = false; boolean ret = false;
@ -1032,9 +1049,12 @@ static inline moviemode_t M_StartMovieAPNG(const char *pathname)
} }
if (rendermode == render_soft) if (rendermode == render_soft)
ret = M_SetupaPNG(va(pandf,pathname,freename), W_CacheLumpName(GetPalette(), PU_CACHE)); {
else M_CreateScreenShotPalette();
ret = M_SetupaPNG(va(pandf,pathname,freename), NULL); palette = screenshot_palette;
}
ret = M_SetupaPNG(va(pandf,pathname,freename), palette);
if (!ret) if (!ret)
{ {
@ -1237,7 +1257,7 @@ void M_StopMovie(void)
* \param data The image data. * \param data The image data.
* \param width Width of the picture. * \param width Width of the picture.
* \param height Height 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 * \note if palette is NULL, BGR888 format
*/ */
boolean M_SavePNG(const char *filename, void *data, int width, int height, const UINT8 *palette) boolean M_SavePNG(const char *filename, void *data, int width, int height, const UINT8 *palette)
@ -1259,8 +1279,7 @@ boolean M_SavePNG(const char *filename, void *data, int width, int height, const
return false; return false;
} }
png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, PNG_error, PNG_warn);
PNG_error, PNG_warn);
if (!png_ptr) if (!png_ptr)
{ {
CONS_Debug(DBG_RENDER, "M_SavePNG: Error on initialize libpng\n"); CONS_Debug(DBG_RENDER, "M_SavePNG: Error on initialize libpng\n");
@ -1414,9 +1433,8 @@ void M_ScreenShot(void)
} }
/** Takes a screenshot. /** Takes a screenshot.
* The screenshot is saved as "srb2xxxx.pcx" (or "srb2xxxx.tga" in hardware * The screenshot is saved as "srb2xxxx.png" where xxxx is the lowest
* rendermode) where xxxx is the lowest four-digit number for which a file * four-digit number for which a file does not already exist.
* does not already exist.
* *
* \sa HWR_ScreenShot * \sa HWR_ScreenShot
*/ */
@ -1430,6 +1448,10 @@ void M_DoScreenShot(void)
// Don't take multiple screenshots, obviously // Don't take multiple screenshots, obviously
takescreenshot = false; takescreenshot = false;
// how does one take a screenshot without a render system?
if (rendermode == render_none)
return;
if (cv_screenshot_option.value == 0) if (cv_screenshot_option.value == 0)
pathname = usehome ? srb2home : srb2path; pathname = usehome ? srb2home : srb2path;
else if (cv_screenshot_option.value == 1) else if (cv_screenshot_option.value == 1)
@ -1440,16 +1462,13 @@ void M_DoScreenShot(void)
pathname = cv_screenshot_folder.string; pathname = cv_screenshot_folder.string;
#ifdef USE_PNG #ifdef USE_PNG
if (rendermode != render_none) freename = Newsnapshotfile(pathname,"png");
freename = Newsnapshotfile(pathname,"png");
#else #else
if (rendermode == render_soft) if (rendermode == render_soft)
freename = Newsnapshotfile(pathname,"pcx"); freename = Newsnapshotfile(pathname,"pcx");
else if (rendermode != render_none) else if (rendermode == render_opengl)
freename = Newsnapshotfile(pathname,"tga"); freename = Newsnapshotfile(pathname,"tga");
#endif #endif
else
I_Error("Can't take a screenshot without a render system");
if (rendermode == render_soft) if (rendermode == render_soft)
{ {
@ -1463,18 +1482,16 @@ void M_DoScreenShot(void)
// save the pcx file // save the pcx file
#ifdef HWRENDER #ifdef HWRENDER
if (rendermode != render_soft) if (rendermode == render_opengl)
ret = HWR_Screenshot(va(pandf,pathname,freename)); ret = HWR_Screenshot(va(pandf,pathname,freename));
else else
#endif #endif
if (rendermode != render_none)
{ {
M_CreateScreenShotPalette();
#ifdef USE_PNG #ifdef USE_PNG
ret = M_SavePNG(va(pandf,pathname,freename), linear, vid.width, vid.height, ret = M_SavePNG(va(pandf,pathname,freename), linear, vid.width, vid.height, screenshot_palette);
W_CacheLumpName(GetPalette(), PU_CACHE));
#else #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);
W_CacheLumpName(GetPalette(), PU_CACHE));
#endif #endif
} }
@ -1482,14 +1499,14 @@ failure:
if (ret) if (ret)
{ {
if (moviemode != MM_SCREENSHOT) 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 else
{ {
if (freename) 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 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) if (moviemode == MM_SCREENSHOT)
M_StopMovie(); M_StopMovie();

View File

@ -647,8 +647,6 @@ static void P_NetArchiveWorld(void)
WRITEUINT16(put, 0xffff); WRITEUINT16(put, 0xffff);
mld = W_CacheLumpNum(lastloadedmaplumpnum+ML_LINEDEFS, PU_CACHE);
msd = W_CacheLumpNum(lastloadedmaplumpnum+ML_SIDEDEFS, PU_CACHE);
// do lines // do lines
for (i = 0; i < numlines; i++, mld++, li++) for (i = 0; i < numlines; i++, mld++, li++)
{ {

View File

@ -187,6 +187,12 @@ static void P_ClearSingleMapHeaderInfo(INT16 i)
mapheaderinfo[num]->musname[6] = 0; mapheaderinfo[num]->musname[6] = 0;
DEH_WriteUndoline("MUSICTRACK", va("%d", mapheaderinfo[num]->mustrack), UNDO_NONE); DEH_WriteUndoline("MUSICTRACK", va("%d", mapheaderinfo[num]->mustrack), UNDO_NONE);
mapheaderinfo[num]->mustrack = 0; mapheaderinfo[num]->mustrack = 0;
DEH_WriteUndoline("MUSICPOS", va("%d", mapheaderinfo[num]->muspos), UNDO_NONE);
mapheaderinfo[num]->muspos = 0;
DEH_WriteUndoline("MUSICINTERFADEOUT", va("%d", mapheaderinfo[num]->musinterfadeout), UNDO_NONE);
mapheaderinfo[num]->musinterfadeout = 0;
DEH_WriteUndoline("MUSICINTER", mapheaderinfo[num]->musintername, UNDO_NONE);
mapheaderinfo[num]->musintername[0] = '\0';
DEH_WriteUndoline("FORCECHARACTER", va("%d", mapheaderinfo[num]->forcecharacter), UNDO_NONE); DEH_WriteUndoline("FORCECHARACTER", va("%d", mapheaderinfo[num]->forcecharacter), UNDO_NONE);
mapheaderinfo[num]->forcecharacter[0] = '\0'; mapheaderinfo[num]->forcecharacter[0] = '\0';
DEH_WriteUndoline("WEATHER", va("%d", mapheaderinfo[num]->weather), UNDO_NONE); DEH_WriteUndoline("WEATHER", va("%d", mapheaderinfo[num]->weather), UNDO_NONE);
@ -1537,19 +1543,33 @@ static void P_LoadRawSideDefs2(void *data)
{ {
M_Memcpy(process,msd->bottomtexture,8); M_Memcpy(process,msd->bottomtexture,8);
process[8] = '\0'; process[8] = '\0';
sd->bottomtexture = get_number(process)-1; sd->bottomtexture = get_number(process);
} }
M_Memcpy(process,msd->toptexture,8);
process[8] = '\0';
sd->text = Z_Malloc(7, PU_LEVEL, NULL);
// If they type in O_ or D_ and their music name, just shrug, if (!(msd->midtexture[0] == '-' && msd->midtexture[1] == '\0') || msd->midtexture[1] != '\0')
// then copy the rest instead. {
if ((process[0] == 'O' || process[0] == 'D') && process[7]) M_Memcpy(process,msd->midtexture,8);
M_Memcpy(sd->text, process+2, 6); process[8] = '\0';
else // Assume it's a proper music name. sd->midtexture = get_number(process);
M_Memcpy(sd->text, process, 6); }
sd->text[6] = 0;
// always process if back sidedef, because we need that - symbol
sd->text = Z_Malloc(7, PU_LEVEL, NULL);
if (i == 1 || msd->toptexture[0] != '-' || msd->toptexture[1] != '\0')
{
M_Memcpy(process,msd->toptexture,8);
process[8] = '\0';
// If they type in O_ or D_ and their music name, just shrug,
// then copy the rest instead.
if ((process[0] == 'O' || process[0] == 'D') && process[7])
M_Memcpy(sd->text, process+2, 6);
else // Assume it's a proper music name.
M_Memcpy(sd->text, process, 6);
sd->text[6] = 0;
}
else
sd->text[0] = 0;
break; break;
} }

View File

@ -264,7 +264,7 @@ void P_SpawnSlope_Line(int linenum)
if(!line->frontsector || !line->backsector) if(!line->frontsector || !line->backsector)
{ {
CONS_Printf("P_SpawnSlope_Line used on a line without two sides.\n"); CONS_Debug(DBG_SETUP, "P_SpawnSlope_Line used on a line without two sides. (line number %i)\n", linenum);
return; return;
} }

View File

@ -2417,16 +2417,68 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
// console player only unless NOCLIMB is set // console player only unless NOCLIMB is set
if ((line->flags & ML_NOCLIMB) || (mo && mo->player && P_IsLocalPlayer(mo->player))) if ((line->flags & ML_NOCLIMB) || (mo && mo->player && P_IsLocalPlayer(mo->player)))
{ {
UINT16 tracknum = (UINT16)sides[line->sidenum[0]].bottomtexture; boolean musicsame = (!sides[line->sidenum[0]].text[0] || !strnicmp(sides[line->sidenum[0]].text, S_MusicName(), 7));
UINT16 tracknum = (UINT16)max(sides[line->sidenum[0]].bottomtexture, 0);
INT32 position = (INT32)max(sides[line->sidenum[0]].midtexture, 0);
UINT32 prefadems = (UINT32)max(sides[line->sidenum[0]].textureoffset >> FRACBITS, 0);
UINT32 postfadems = (UINT32)max(sides[line->sidenum[0]].rowoffset >> FRACBITS, 0);
UINT8 fadetarget = (UINT8)max((line->sidenum[1] != 0xffff) ? sides[line->sidenum[1]].textureoffset >> FRACBITS : 0, 0);
INT16 fadesource = (INT16)max((line->sidenum[1] != 0xffff) ? sides[line->sidenum[1]].rowoffset >> FRACBITS : -1, -1);
strncpy(mapmusname, sides[line->sidenum[0]].text, 7); // Seek offset from current song position
mapmusname[6] = 0; if (line->flags & ML_EFFECT1)
{
// adjust for loop point if subtracting
if (position < 0 && S_GetMusicLength() &&
S_GetMusicPosition() > S_GetMusicLoopPoint() &&
S_GetMusicPosition() + position < S_GetMusicLoopPoint())
position = max(S_GetMusicLength() - (S_GetMusicLoopPoint() - (S_GetMusicPosition() + position)), 0);
else
position = max(S_GetMusicPosition() + position, 0);
}
mapmusflags = tracknum & MUSIC_TRACKMASK; // Fade current music to target volume (if music won't be changed)
if (!(line->flags & ML_BLOCKMONSTERS)) if ((line->flags & ML_EFFECT2) && fadetarget && musicsame)
mapmusflags |= MUSIC_RELOADRESET; {
// 0 fadesource means fade from current volume.
// meaning that we can't specify volume 0 as the source volume -- this starts at 1.
if (!fadesource)
fadesource = -1;
S_ChangeMusic(mapmusname, mapmusflags, !(line->flags & ML_EFFECT4)); if (!postfadems)
S_SetInternalMusicVolume(fadetarget);
else
S_FadeMusicFromVolume(fadetarget, fadesource, postfadems);
if (position)
S_SetMusicPosition(position);
}
// Change the music and apply position/fade operations
else
{
strncpy(mapmusname, sides[line->sidenum[0]].text, 7);
mapmusname[6] = 0;
mapmusflags = tracknum & MUSIC_TRACKMASK;
if (!(line->flags & ML_BLOCKMONSTERS))
mapmusflags |= MUSIC_RELOADRESET;
if (line->flags & ML_BOUNCY)
mapmusflags |= MUSIC_FORCERESET;
mapmusposition = position;
S_ChangeMusicEx(mapmusname, mapmusflags, !(line->flags & ML_EFFECT4), position,
!(line->flags & ML_EFFECT2) ? prefadems : 0,
!(line->flags & ML_EFFECT2) ? postfadems : 0);
if ((line->flags & ML_EFFECT2) && fadetarget)
{
if (!postfadems)
S_SetInternalMusicVolume(fadetarget);
else
S_FadeMusicFromVolume(fadetarget, fadesource, postfadems);
}
}
// Except, you can use the ML_BLOCKMONSTERS flag to change this behavior. // Except, you can use the ML_BLOCKMONSTERS flag to change this behavior.
// if (mapmusflags & MUSIC_RELOADRESET) then it will reset the music in G_PlayerReborn. // if (mapmusflags & MUSIC_RELOADRESET) then it will reset the music in G_PlayerReborn.

View File

@ -1124,13 +1124,13 @@ void P_RestoreMusic(player_t *player)
if (mapheaderinfo[gamemap-1]->levelflags & LF_SPEEDMUSIC) if (mapheaderinfo[gamemap-1]->levelflags & LF_SPEEDMUSIC)
{ {
S_SpeedMusic(1.4f); S_SpeedMusic(1.4f);
S_ChangeMusic(mapmusname, mapmusflags, true); S_ChangeMusicEx(mapmusname, mapmusflags, true, mapmusposition, 0, 0);
} }
else else
S_ChangeMusicInternal("shoes", true); S_ChangeMusicInternal("shoes", true);
} }
else else
S_ChangeMusic(mapmusname, mapmusflags, true); S_ChangeMusicEx(mapmusname, mapmusflags, true, mapmusposition, 0, 0);
} }
// //
@ -8688,8 +8688,11 @@ void P_PlayerThink(player_t *player)
if (player->bot) if (player->bot)
{ {
if (player->playerstate == PST_LIVE && B_CheckRespawn(player)) if (player->playerstate == PST_LIVE || player->playerstate == PST_DEAD)
player->playerstate = PST_REBORN; {
if (B_CheckRespawn(player))
player->playerstate = PST_REBORN;
}
if (player->playerstate == PST_REBORN) if (player->playerstate == PST_REBORN)
return; return;
} }

View File

@ -2306,7 +2306,7 @@ void R_DrawMasked(void)
// ========================================================================== // ==========================================================================
INT32 numskins = 0; INT32 numskins = 0;
skin_t skins[MAXSKINS+1]; skin_t skins[MAXSKINS];
// FIXTHIS: don't work because it must be inistilised before the config load // FIXTHIS: don't work because it must be inistilised before the config load
//#define SKINVALUES //#define SKINVALUES
#ifdef SKINVALUES #ifdef SKINVALUES
@ -2559,7 +2559,7 @@ void R_AddSkins(UINT16 wadnum)
// advance by default // advance by default
lastlump = lump + 1; lastlump = lump + 1;
if (numskins > MAXSKINS) if (numskins >= MAXSKINS)
{ {
CONS_Debug(DBG_RENDER, "ignored skin (%d skins maximum)\n", MAXSKINS); CONS_Debug(DBG_RENDER, "ignored skin (%d skins maximum)\n", MAXSKINS);
continue; // so we know how many skins couldn't be added continue; // so we know how many skins couldn't be added

View File

@ -180,7 +180,7 @@ typedef struct drawnode_s
} drawnode_t; } drawnode_t;
extern INT32 numskins; extern INT32 numskins;
extern skin_t skins[MAXSKINS + 1]; extern skin_t skins[MAXSKINS];
void SetPlayerSkin(INT32 playernum,const char *skinname); void SetPlayerSkin(INT32 playernum,const char *skinname);
void SetPlayerSkinByNum(INT32 playernum,INT32 skinnum); // Tails 03-16-2002 void SetPlayerSkinByNum(INT32 playernum,INT32 skinnum); // Tails 03-16-2002

View File

@ -38,6 +38,10 @@ extern INT32 msg_id;
#include "p_local.h" // camera info #include "p_local.h" // camera info
#include "m_misc.h" // for tunes command #include "m_misc.h" // for tunes command
#if defined(HAVE_BLUA) && defined(HAVE_LUA_MUSICPLUS)
#include "lua_hook.h" // MusicChange hook
#endif
#ifdef HW3SOUND #ifdef HW3SOUND
// 3D Sound Interface // 3D Sound Interface
#include "hardware/hw3sound.h" #include "hardware/hw3sound.h"
@ -1241,6 +1245,12 @@ static void *music_data;
static UINT16 music_flags; static UINT16 music_flags;
static boolean music_looping; static boolean music_looping;
static char queue_name[7];
static UINT16 queue_flags;
static boolean queue_looping;
static UINT32 queue_position;
static UINT32 queue_fadeinms;
/// ------------------------ /// ------------------------
/// Music Status /// Music Status
/// ------------------------ /// ------------------------
@ -1275,6 +1285,11 @@ musictype_t S_MusicType(void)
return I_SongType(); return I_SongType();
} }
const char *S_MusicName(void)
{
return music_name;
}
boolean S_MusicInfo(char *mname, UINT16 *mflags, boolean *looping) boolean S_MusicInfo(char *mname, UINT16 *mflags, boolean *looping)
{ {
if (!I_SongPlaying()) if (!I_SongPlaying())
@ -1305,6 +1320,35 @@ boolean S_SpeedMusic(float speed)
return I_SetSongSpeed(speed); return I_SetSongSpeed(speed);
} }
/// ------------------------
/// Music Seeking
/// ------------------------
UINT32 S_GetMusicLength(void)
{
return I_GetSongLength();
}
boolean S_SetMusicLoopPoint(UINT32 looppoint)
{
return I_SetSongLoopPoint(looppoint);
}
UINT32 S_GetMusicLoopPoint(void)
{
return I_GetSongLoopPoint();
}
boolean S_SetMusicPosition(UINT32 position)
{
return I_SetSongPosition(position);
}
UINT32 S_GetMusicPosition(void)
{
return I_GetSongPosition();
}
/// ------------------------ /// ------------------------
/// Music Playback /// Music Playback
/// ------------------------ /// ------------------------
@ -1377,12 +1421,13 @@ static void S_UnloadMusic(void)
music_looping = false; music_looping = false;
} }
static boolean S_PlayMusic(boolean looping) static boolean S_PlayMusic(boolean looping, UINT32 fadeinms)
{ {
if (S_MusicDisabled()) if (S_MusicDisabled())
return false; return false;
if (!I_PlaySong(looping)) if ((!fadeinms && !I_PlaySong(looping)) ||
(fadeinms && !I_FadeInPlaySong(fadeinms, looping)))
{ {
S_UnloadMusic(); S_UnloadMusic();
return false; return false;
@ -1392,8 +1437,30 @@ static boolean S_PlayMusic(boolean looping)
return true; return true;
} }
void S_ChangeMusic(const char *mmusic, UINT16 mflags, boolean looping) static void S_QueueMusic(const char *mmusic, UINT16 mflags, boolean looping, UINT32 position, UINT32 fadeinms)
{ {
strncpy(queue_name, mmusic, 7);
queue_flags = mflags;
queue_looping = looping;
queue_position = position;
queue_fadeinms = fadeinms;
}
static void S_ClearQueue(void)
{
queue_name[0] = queue_flags = queue_looping = queue_position = queue_fadeinms = 0;
}
static void S_ChangeMusicToQueue(void)
{
S_ChangeMusicEx(queue_name, queue_flags, queue_looping, queue_position, 0, queue_fadeinms);
S_ClearQueue();
}
void S_ChangeMusicEx(const char *mmusic, UINT16 mflags, boolean looping, UINT32 position, UINT32 prefadems, UINT32 fadeinms)
{
char newmusic[7];
#if defined (DC) || defined (_WIN32_WCE) || defined (PSP) || defined(GP2X) #if defined (DC) || defined (_WIN32_WCE) || defined (PSP) || defined(GP2X)
S_ClearSfx(); S_ClearSfx();
#endif #endif
@ -1401,33 +1468,66 @@ void S_ChangeMusic(const char *mmusic, UINT16 mflags, boolean looping)
if (S_MusicDisabled()) if (S_MusicDisabled())
return; return;
// No Music (empty string) strncpy(newmusic, mmusic, 7);
if (mmusic[0] == 0) #if defined(HAVE_BLUA) && defined(HAVE_LUA_MUSICPLUS)
{ if(LUAh_MusicChange(music_name, newmusic, &mflags, &looping, &position, &prefadems, &fadeinms))
S_StopMusic(); return;
#endif
newmusic[6] = 0;
// No Music (empty string)
if (newmusic[0] == 0)
{
if (prefadems)
I_FadeSong(0, prefadems, &S_StopMusic);
else
S_StopMusic();
return; return;
} }
if (strnicmp(music_name, mmusic, 6)) if (prefadems && S_MusicPlaying()) // queue music change for after fade // allow even if the music is the same
{ {
S_StopMusic(); // shutdown old music CONS_Debug(DBG_DETAILED, "Now fading out song %s\n", music_name);
S_QueueMusic(newmusic, mflags, looping, position, fadeinms);
I_FadeSong(0, prefadems, S_ChangeMusicToQueue);
return;
}
else if (strnicmp(music_name, newmusic, 6) || (mflags & MUSIC_FORCERESET))
{
CONS_Debug(DBG_DETAILED, "Now playing song %s\n", newmusic);
if (!S_LoadMusic(mmusic)) S_StopMusic();
if (!S_LoadMusic(newmusic))
{ {
CONS_Alert(CONS_ERROR, "Music %.6s could not be loaded!\n", mmusic); CONS_Alert(CONS_ERROR, "Music %.6s could not be loaded!\n", newmusic);
return; return;
} }
music_flags = mflags; music_flags = mflags;
music_looping = looping; music_looping = looping;
if (!S_PlayMusic(looping)) if (!S_PlayMusic(looping, fadeinms))
{ {
CONS_Alert(CONS_ERROR, "Music %.6s could not be played!\n", mmusic); CONS_Alert(CONS_ERROR, "Music %.6s could not be played!\n", newmusic);
return; return;
} }
if (position)
I_SetSongPosition(position);
I_SetSongTrack(mflags & MUSIC_TRACKMASK);
}
else if (fadeinms) // let fades happen with same music
{
I_SetSongPosition(position);
I_FadeSong(100, fadeinms, NULL);
}
else // reset volume to 100 with same music
{
I_StopFadingSong();
I_FadeSong(100, 500, NULL);
} }
I_SetSongTrack(mflags & MUSIC_TRACKMASK);
} }
void S_StopMusic(void) void S_StopMusic(void)
@ -1502,6 +1602,32 @@ void S_SetMusicVolume(INT32 digvolume, INT32 seqvolume)
} }
} }
/// ------------------------
/// Music Fading
/// ------------------------
void S_SetInternalMusicVolume(INT32 volume)
{
I_SetInternalMusicVolume(min(max(volume, 0), 100));
}
void S_StopFadingMusic(void)
{
I_StopFadingSong();
}
boolean S_FadeMusicFromVolume(UINT8 target_volume, INT16 source_volume, UINT32 ms)
{
if (source_volume < 0)
return I_FadeSong(target_volume, ms, NULL);
else
return I_FadeSongFromVolume(target_volume, source_volume, ms, NULL);
}
boolean S_FadeOutStopMusic(UINT32 ms)
{
return I_FadeSong(0, ms, &S_StopMusic);
}
/// ------------------------ /// ------------------------
/// Init & Others /// Init & Others
@ -1519,22 +1645,24 @@ void S_Start(void)
strncpy(mapmusname, mapheaderinfo[gamemap-1]->musname, 7); strncpy(mapmusname, mapheaderinfo[gamemap-1]->musname, 7);
mapmusname[6] = 0; mapmusname[6] = 0;
mapmusflags = (mapheaderinfo[gamemap-1]->mustrack & MUSIC_TRACKMASK); mapmusflags = (mapheaderinfo[gamemap-1]->mustrack & MUSIC_TRACKMASK);
mapmusposition = mapheaderinfo[gamemap-1]->muspos;
} }
if (cv_resetmusic.value) if (cv_resetmusic.value)
S_StopMusic(); S_StopMusic();
S_ChangeMusic(mapmusname, mapmusflags, true); S_ChangeMusicEx(mapmusname, mapmusflags, true, mapmusposition, 0, 0);
} }
static void Command_Tunes_f(void) static void Command_Tunes_f(void)
{ {
const char *tunearg; const char *tunearg;
UINT16 tunenum, track = 0; UINT16 tunenum, track = 0;
UINT32 position = 0;
const size_t argc = COM_Argc(); const size_t argc = COM_Argc();
if (argc < 2) //tunes slot ... if (argc < 2) //tunes slot ...
{ {
CONS_Printf("tunes <name/num> [track] [speed] / <-show> / <-default> / <-none>:\n"); CONS_Printf("tunes <name/num> [track] [speed] [position] / <-show> / <-default> / <-none>:\n");
CONS_Printf(M_GetText("Play an arbitrary music lump. If a map number is used, 'MAP##M' is played.\n")); CONS_Printf(M_GetText("Play an arbitrary music lump. If a map number is used, 'MAP##M' is played.\n"));
CONS_Printf(M_GetText("If the format supports multiple songs, you can specify which one to play.\n\n")); CONS_Printf(M_GetText("If the format supports multiple songs, you can specify which one to play.\n\n"));
CONS_Printf(M_GetText("* With \"-show\", shows the currently playing tune and track.\n")); CONS_Printf(M_GetText("* With \"-show\", shows the currently playing tune and track.\n"));
@ -1581,10 +1709,15 @@ static void Command_Tunes_f(void)
snprintf(mapmusname, 7, "%sM", G_BuildMapName(tunenum)); snprintf(mapmusname, 7, "%sM", G_BuildMapName(tunenum));
else else
strncpy(mapmusname, tunearg, 7); strncpy(mapmusname, tunearg, 7);
if (argc > 4)
position = (UINT32)atoi(COM_Argv(4));
mapmusname[6] = 0; mapmusname[6] = 0;
mapmusflags = (track & MUSIC_TRACKMASK); mapmusflags = (track & MUSIC_TRACKMASK);
mapmusposition = position;
S_ChangeMusic(mapmusname, mapmusflags, true); S_ChangeMusicEx(mapmusname, mapmusflags, true, mapmusposition, 0, 0);
if (argc > 3) if (argc > 3)
{ {

View File

@ -112,29 +112,49 @@ boolean S_MusicDisabled(void);
boolean S_MusicPlaying(void); boolean S_MusicPlaying(void);
boolean S_MusicPaused(void); boolean S_MusicPaused(void);
musictype_t S_MusicType(void); musictype_t S_MusicType(void);
const char *S_MusicName(void);
boolean S_MusicInfo(char *mname, UINT16 *mflags, boolean *looping); boolean S_MusicInfo(char *mname, UINT16 *mflags, boolean *looping);
boolean S_MusicExists(const char *mname, boolean checkMIDI, boolean checkDigi); boolean S_MusicExists(const char *mname, boolean checkMIDI, boolean checkDigi);
#define S_DigExists(a) S_MusicExists(a, false, true) #define S_DigExists(a) S_MusicExists(a, false, true)
#define S_MIDIExists(a) S_MusicExists(a, true, false) #define S_MIDIExists(a) S_MusicExists(a, true, false)
// //
// Music Properties // Music Effects
// //
// Set Speed of Music // Set Speed of Music
boolean S_SpeedMusic(float speed); boolean S_SpeedMusic(float speed);
// //
// Music Routines // Music Seeking
//
// Get Length of Music
UINT32 S_GetMusicLength(void);
// Set LoopPoint of Music
boolean S_SetMusicLoopPoint(UINT32 looppoint);
// Get LoopPoint of Music
UINT32 S_GetMusicLoopPoint(void);
// Set Position of Music
boolean S_SetMusicPosition(UINT32 position);
// Get Position of Music
UINT32 S_GetMusicPosition(void);
//
// Music Playback
// //
// Start music track, arbitrary, given its name, and set whether looping // Start music track, arbitrary, given its name, and set whether looping
// note: music flags 12 bits for tracknum (gme, other formats with more than one track) // note: music flags 12 bits for tracknum (gme, other formats with more than one track)
// 13-15 aren't used yet // 13-15 aren't used yet
// and the last bit we ignore (internal game flag for resetting music on reload) // and the last bit we ignore (internal game flag for resetting music on reload)
#define S_ChangeMusicInternal(a,b) S_ChangeMusic(a,0,b) void S_ChangeMusicEx(const char *mmusic, UINT16 mflags, boolean looping, UINT32 position, UINT32 prefadems, UINT32 fadeinms);
void S_ChangeMusic(const char *mmusic, UINT16 mflags, boolean looping); #define S_ChangeMusicInternal(a,b) S_ChangeMusicEx(a,0,b,0,0,0)
#define S_ChangeMusic(a,b,c) S_ChangeMusicEx(a,b,c,0,0,0)
// Stops the music. // Stops the music.
void S_StopMusic(void); void S_StopMusic(void);
@ -143,6 +163,17 @@ void S_StopMusic(void);
void S_PauseAudio(void); void S_PauseAudio(void);
void S_ResumeAudio(void); void S_ResumeAudio(void);
//
// Music Fading
//
void S_SetInternalMusicVolume(INT32 volume);
void S_StopFadingMusic(void);
boolean S_FadeMusicFromVolume(UINT8 target_volume, INT16 source_volume, UINT32 ms);
#define S_FadeMusic(a, b) S_FadeMusicFromVolume(a, -1, b)
#define S_FadeInChangeMusic(a,b,c,d) S_ChangeMusicEx(a,b,c,0,0,d)
boolean S_FadeOutStopMusic(UINT32 ms);
// //
// Updates music & sounds // Updates music & sounds
// //

View File

@ -153,7 +153,7 @@ if(${SDL2_FOUND})
${ZLIB_LIBRARIES} ${ZLIB_LIBRARIES}
${OPENGL_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() else()
target_link_libraries(SRB2SDL2 PRIVATE target_link_libraries(SRB2SDL2 PRIVATE
${SDL2_LIBRARIES} ${SDL2_LIBRARIES}
@ -337,10 +337,19 @@ if(${SDL2_FOUND})
# Mac bundle fixup # 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) if(${CMAKE_SYSTEM} MATCHES Darwin)
install(CODE " install(CODE "
include(BundleUtilities) include(BundleUtilities)
fixup_bundle(\"${CMAKE_INSTALL_PREFIX}/Sonic Robo Blast 2.app\" fixup_bundle(\"\${CMAKE_INSTALL_PREFIX}/${CPACK_PACKAGE_DESCRIPTION_SUMMARY}.app\"
\"\" \"\"
/Library/Frameworks /Library/Frameworks
)" )"

View File

@ -93,6 +93,7 @@
<Import Project="..\..\libs\libpng.props" /> <Import Project="..\..\libs\libpng.props" />
<Import Project="..\..\libs\SDL2.props" /> <Import Project="..\..\libs\SDL2.props" />
<Import Project="..\..\libs\SDL_mixer.props" /> <Import Project="..\..\libs\SDL_mixer.props" />
<Import Project="..\..\libs\libgme.props" />
<Import Project="Srb2SDL.props" /> <Import Project="Srb2SDL.props" />
</ImportGroup> </ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">

View File

@ -5,7 +5,10 @@
<PropertyGroup /> <PropertyGroup />
<ItemDefinitionGroup> <ItemDefinitionGroup>
<ClCompile> <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> </ClCompile>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemGroup /> <ItemGroup />

View File

@ -996,6 +996,7 @@ void I_UpdateNoBlit(void)
// from PrBoom's src/SDL/i_video.c // from PrBoom's src/SDL/i_video.c
static inline boolean I_SkipFrame(void) static inline boolean I_SkipFrame(void)
{ {
#if 0
static boolean skip = false; static boolean skip = false;
if (rendermode != render_soft) if (rendermode != render_soft)
@ -1015,6 +1016,8 @@ static inline boolean I_SkipFrame(void)
default: default:
return false; return false;
} }
#endif
return false;
} }
// //

View File

@ -1219,7 +1219,7 @@
C01FCF4B08A954540054247B /* Debug */ = { C01FCF4B08A954540054247B /* Debug */ = {
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
buildSettings = { buildSettings = {
CURRENT_PROJECT_VERSION = 2.1.23; CURRENT_PROJECT_VERSION = 2.1.24;
GCC_PREPROCESSOR_DEFINITIONS = ( GCC_PREPROCESSOR_DEFINITIONS = (
"$(inherited)", "$(inherited)",
NORMALSRB2, NORMALSRB2,
@ -1231,7 +1231,7 @@
C01FCF4C08A954540054247B /* Release */ = { C01FCF4C08A954540054247B /* Release */ = {
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
buildSettings = { buildSettings = {
CURRENT_PROJECT_VERSION = 2.1.23; CURRENT_PROJECT_VERSION = 2.1.24;
GCC_ENABLE_FIX_AND_CONTINUE = NO; GCC_ENABLE_FIX_AND_CONTINUE = NO;
GCC_GENERATE_DEBUGGING_SYMBOLS = NO; GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
GCC_PREPROCESSOR_DEFINITIONS = ( GCC_PREPROCESSOR_DEFINITIONS = (

View File

@ -75,15 +75,41 @@
UINT8 sound_started = false; UINT8 sound_started = false;
static Mix_Music *music; static Mix_Music *music;
static UINT8 music_volume, sfx_volume; static UINT8 music_volume, sfx_volume, internal_volume;
static float loop_point; static float loop_point;
static float song_length; // length in seconds
static boolean songpaused; static boolean songpaused;
static UINT32 music_bytes;
static boolean is_looping;
// fading
static boolean is_fading;
static UINT8 fading_source;
static UINT8 fading_target;
static UINT32 fading_timer;
static UINT32 fading_duration;
static INT32 fading_id;
static void (*fading_callback)(void);
#ifdef HAVE_LIBGME #ifdef HAVE_LIBGME
static Music_Emu *gme; static Music_Emu *gme;
static INT32 current_track; static INT32 current_track;
#endif #endif
static void var_cleanup(void)
{
loop_point = song_length =\
music_bytes = fading_source = fading_target =\
fading_timer = fading_duration = 0;
songpaused = is_looping =\
is_fading = false;
fading_callback = NULL;
internal_volume = 100;
}
/// ------------------------ /// ------------------------
/// Audio System /// Audio System
/// ------------------------ /// ------------------------
@ -111,6 +137,8 @@ void I_StartupSound(void)
return; return;
} }
var_cleanup();
music = NULL; music = NULL;
music_volume = sfx_volume = 0; music_volume = sfx_volume = 0;
@ -336,6 +364,7 @@ void *I_GetSfx(sfxinfo_t *sfx)
len = (info->play_length * 441 / 10) << 2; len = (info->play_length * 441 / 10) << 2;
mem = malloc(len); mem = malloc(len);
gme_play(emu, len >> 1, mem); gme_play(emu, len >> 1, mem);
gme_free_info(info);
gme_delete(emu); gme_delete(emu);
return Mix_QuickLoad_RAW((Uint8 *)mem, len); return Mix_QuickLoad_RAW((Uint8 *)mem, len);
@ -408,6 +437,7 @@ void *I_GetSfx(sfxinfo_t *sfx)
len = (info->play_length * 441 / 10) << 2; len = (info->play_length * 441 / 10) << 2;
mem = malloc(len); mem = malloc(len);
gme_play(emu, len >> 1, mem); gme_play(emu, len >> 1, mem);
gme_free_info(info);
gme_delete(emu); gme_delete(emu);
return Mix_QuickLoad_RAW((Uint8 *)mem, len); return Mix_QuickLoad_RAW((Uint8 *)mem, len);
@ -482,14 +512,102 @@ void I_SetSfxVolume(UINT8 volume)
sfx_volume = volume; sfx_volume = volume;
} }
/// ------------------------
/// Music Utilities
/// ------------------------
static UINT32 get_real_volume(UINT8 volume)
{
#ifdef _WIN32
if (I_SongType() == MU_MID)
// HACK: Until we stop using native MIDI,
// disable volume changes
return ((UINT32)31*128/31); // volume = 31
else
#endif
// convert volume to mixer's 128 scale
// then apply internal_volume as a percentage
return ((UINT32)volume*128/31) * (UINT32)internal_volume / 100;
}
static UINT32 get_adjusted_position(UINT32 position)
{
// all in milliseconds
UINT32 length = I_GetSongLength();
UINT32 looppoint = I_GetSongLoopPoint();
if (length)
return position >= length ? (position % (length-looppoint)) : position;
else
return position;
}
static void do_fading_callback(void)
{
if (fading_callback)
(*fading_callback)();
fading_callback = NULL;
}
/// ------------------------ /// ------------------------
/// Music Hooks /// Music Hooks
/// ------------------------ /// ------------------------
static void count_music_bytes(int chan, void *stream, int len, void *udata)
{
(void)chan;
(void)stream;
(void)udata;
if (!music || I_SongType() == MU_GME || I_SongType() == MU_MOD || I_SongType() == MU_MID)
return;
music_bytes += len;
}
static void music_loop(void) static void music_loop(void)
{ {
Mix_PlayMusic(music, 0); if (is_looping)
Mix_SetMusicPosition(loop_point); {
Mix_PlayMusic(music, 0);
Mix_SetMusicPosition(loop_point);
music_bytes = loop_point*44100.0L*4; //assume 44.1khz, 4-byte length (see I_GetSongPosition)
}
else
I_StopSong();
}
static UINT32 music_fade(UINT32 interval, void *param)
{
(void)param;
if (!is_fading ||
internal_volume == fading_target ||
fading_duration == 0)
{
I_StopFadingSong();
do_fading_callback();
return 0;
}
else if (songpaused) // don't decrement timer
return interval;
else if ((fading_timer -= 10) <= 0)
{
internal_volume = fading_target;
Mix_VolumeMusic(get_real_volume(music_volume));
I_StopFadingSong();
do_fading_callback();
return 0;
}
else
{
UINT8 delta = abs(fading_target - fading_source);
fixed_t factor = FixedDiv(fading_duration - fading_timer, fading_duration);
if (fading_target < fading_source)
internal_volume = max(min(internal_volume, fading_source - FixedMul(delta, factor)), fading_target);
else if (fading_target > fading_source)
internal_volume = min(max(internal_volume, fading_source + FixedMul(delta, factor)), fading_target);
Mix_VolumeMusic(get_real_volume(music_volume));
return interval;
}
} }
#ifdef HAVE_LIBGME #ifdef HAVE_LIBGME
@ -509,7 +627,7 @@ static void mix_gme(void *udata, Uint8 *stream, int len)
// apply volume to stream // apply volume to stream
for (i = 0, p = (short *)stream; i < len/2; i++, p++) for (i = 0, p = (short *)stream; i < len/2; i++, p++)
*p = ((INT32)*p) * music_volume*2 / 42; *p = ((INT32)*p) * (music_volume*internal_volume/100)*2 / 42;
} }
#endif #endif
@ -587,6 +705,194 @@ boolean I_SetSongSpeed(float speed)
return false; return false;
} }
/// ------------------------
/// MUSIC SEEKING
/// ------------------------
UINT32 I_GetSongLength(void)
{
INT32 length;
#ifdef HAVE_LIBGME
if (gme)
{
gme_info_t *info;
gme_err_t gme_e = gme_track_info(gme, &info, current_track);
if (gme_e != NULL)
{
CONS_Alert(CONS_ERROR, "GME error: %s\n", gme_e);
length = 0;
}
else
{
// reconstruct info->play_length, from GME source
// we only want intro + 1 loop, not 2
length = info->length;
if (length <= 0)
{
length = info->intro_length + info->loop_length; // intro + 1 loop
if (length <= 0)
length = 150 * 1000; // 2.5 minutes
}
}
gme_free_info(info);
return max(length, 0);
}
else
#endif
if (!music || I_SongType() == MU_MOD || I_SongType() == MU_MID)
return 0;
else
{
// VERY IMPORTANT to set your LENGTHMS= in your song files, folks!
// SDL mixer can't read music length itself.
length = (UINT32)(song_length*1000);
if (!length)
CONS_Debug(DBG_DETAILED, "Getting music length: music is missing LENGTHMS= tag. Needed for seeking.\n");
return length;
}
}
boolean I_SetSongLoopPoint(UINT32 looppoint)
{
if (!music || I_SongType() == MU_GME || I_SongType() == MU_MOD || I_SongType() == MU_MID || !is_looping)
return false;
else
{
UINT32 length = I_GetSongLength();
if (length > 0)
looppoint %= length;
loop_point = max((float)(looppoint / 1000.0L), 0);
return true;
}
}
UINT32 I_GetSongLoopPoint(void)
{
#ifdef HAVE_LIBGME
if (gme)
{
INT32 looppoint;
gme_info_t *info;
gme_err_t gme_e = gme_track_info(gme, &info, current_track);
if (gme_e != NULL)
{
CONS_Alert(CONS_ERROR, "GME error: %s\n", gme_e);
looppoint = 0;
}
else
looppoint = info->intro_length > 0 ? info->intro_length : 0;
gme_free_info(info);
return max(looppoint, 0);
}
else
#endif
if (!music || I_SongType() == MU_MOD || I_SongType() == MU_MID)
return 0;
else
return (UINT32)(loop_point * 1000);
}
boolean I_SetSongPosition(UINT32 position)
{
UINT32 length;
#ifdef HAVE_LIBGME
if (gme)
{
// this is unstable, so fail silently
return true;
// this isn't required technically, but GME thread-locks for a second
// if you seek too high from the counter
// length = I_GetSongLength();
// if (length)
// position = get_adjusted_position(position);
// SDL_LockAudio();
// gme_err_t gme_e = gme_seek(gme, position);
// SDL_UnlockAudio();
// if (gme_e != NULL)
// {
// CONS_Alert(CONS_ERROR, "GME error: %s\n", gme_e);
// return false;
// }
// else
// return true;
}
else
#endif
if (!music || I_SongType() == MU_MID)
return false;
else if (I_SongType() == MU_MOD)
return Mix_SetMusicPosition(position); // Goes by channels
else
{
// Because SDL mixer can't identify song length, if you have
// a position input greater than the real length, then
// music_bytes becomes inaccurate.
length = I_GetSongLength(); // get it in MS
if (length)
position = get_adjusted_position(position);
Mix_RewindMusic(); // needed for mp3
if(Mix_SetMusicPosition((float)(position/1000.0L)) == 0)
music_bytes = position/1000.0L*44100.0L*4; //assume 44.1khz, 4-byte length (see I_GetSongPosition)
else
// NOTE: This block fires on incorrect song format,
// NOT if position input is greater than song length.
music_bytes = 0;
return true;
}
}
UINT32 I_GetSongPosition(void)
{
#ifdef HAVE_LIBGME
if (gme)
{
INT32 position = gme_tell(gme);
gme_info_t *info;
gme_err_t gme_e = gme_track_info(gme, &info, current_track);
if (gme_e != NULL)
{
CONS_Alert(CONS_ERROR, "GME error: %s\n", gme_e);
return position;
}
else
{
// adjust position, since GME's counter keeps going past loop
if (info->length > 0)
position %= info->length;
else if (info->intro_length + info->loop_length > 0)
position = position >= (info->intro_length + info->loop_length) ? (position % info->loop_length) : position;
else
position %= 150 * 1000; // 2.5 minutes
}
gme_free_info(info);
return max(position, 0);
}
else
#endif
if (!music || I_SongType() == MU_MID)
return 0;
else
return music_bytes/44100.0L*1000.0L/4; //assume 44.1khz
// 4 = byte length for 16-bit samples (AUDIO_S16SYS), stereo (2-channel)
// This is hardcoded in I_StartupSound. Other formats for factor:
// 8M: 1 | 8S: 2 | 16M: 2 | 16S: 4
}
/// ------------------------ /// ------------------------
/// Music Playback /// Music Playback
/// ------------------------ /// ------------------------
@ -599,6 +905,7 @@ boolean I_LoadSong(char *data, size_t len)
const size_t key1len = strlen(key1); const size_t key1len = strlen(key1);
const size_t key2len = strlen(key2); const size_t key2len = strlen(key2);
const size_t key3len = strlen(key3); const size_t key3len = strlen(key3);
char *p = data; char *p = data;
SDL_RWops *rw; SDL_RWops *rw;
@ -609,6 +916,9 @@ boolean I_LoadSong(char *data, size_t len)
) )
I_UnloadSong(); I_UnloadSong();
// always do this whether or not a music already exists
var_cleanup();
#ifdef HAVE_LIBGME #ifdef HAVE_LIBGME
if ((UINT8)data[0] == 0x1F if ((UINT8)data[0] == 0x1F
&& (UINT8)data[1] == 0x8B) && (UINT8)data[1] == 0x8B)
@ -718,30 +1028,35 @@ boolean I_LoadSong(char *data, size_t len)
// Find the OGG loop point. // Find the OGG loop point.
loop_point = 0.0f; loop_point = 0.0f;
song_length = 0.0f;
while ((UINT32)(p - data) < len) while ((UINT32)(p - data) < len)
{ {
if (strncmp(p++, key1, key1len)) if (fpclassify(loop_point) == FP_ZERO && !strncmp(p, key1, key1len))
continue;
p += key1len-1; // skip OOP (the L was skipped in strncmp)
if (!strncmp(p, key2, key2len)) // is it LOOPPOINT=?
{ {
p += key2len; // skip POINT= p += key1len; // skip LOOP
loop_point = (float)((44.1L+atoi(p)) / 44100.0L); // LOOPPOINT works by sample count. if (!strncmp(p, key2, key2len)) // is it LOOPPOINT=?
// because SDL_Mixer is USELESS and can't even tell us {
// something simple like the frequency of the streaming music, p += key2len; // skip POINT=
// we are unfortunately forced to assume that ALL MUSIC is 44100hz. loop_point = (float)((44.1L+atoi(p)) / 44100.0L); // LOOPPOINT works by sample count.
// This means a lot of tracks that are only 22050hz for a reasonable downloadable file size will loop VERY badly. // because SDL_Mixer is USELESS and can't even tell us
// something simple like the frequency of the streaming music,
// we are unfortunately forced to assume that ALL MUSIC is 44100hz.
// This means a lot of tracks that are only 22050hz for a reasonable downloadable file size will loop VERY badly.
}
else if (!strncmp(p, key3, key3len)) // is it LOOPMS=?
{
p += key3len; // skip MS=
loop_point = (float)(atoi(p) / 1000.0L); // LOOPMS works by real time, as miliseconds.
// Everything that uses LOOPMS will work perfectly with SDL_Mixer.
}
} }
else if (!strncmp(p, key3, key3len)) // is it LOOPMS=?
{
p += key3len; // skip MS=
loop_point = (float)(atoi(p) / 1000.0L); // LOOPMS works by real time, as miliseconds.
// Everything that uses LOOPMS will work perfectly with SDL_Mixer.
}
// Neither?! Continue searching.
}
if (fpclassify(loop_point) != FP_ZERO) // Got what we needed
break;
else // continue searching
p++;
}
return true; return true;
} }
@ -765,7 +1080,6 @@ void I_UnloadSong(void)
boolean I_PlaySong(boolean looping) boolean I_PlaySong(boolean looping)
{ {
boolean lpz = fpclassify(loop_point) == FP_ZERO;
#ifdef HAVE_LIBGME #ifdef HAVE_LIBGME
if (gme) if (gme)
{ {
@ -779,21 +1093,37 @@ boolean I_PlaySong(boolean looping)
if (!music) if (!music)
return false; return false;
if (fpclassify(song_length) == FP_ZERO && (I_SongType() == MU_OGG || I_SongType() == MU_MP3 || I_SongType() == MU_FLAC))
CONS_Debug(DBG_DETAILED, "This song is missing a LENGTHMS= tag! Required to make seeking work properly.\n");
if (Mix_PlayMusic(music, looping && lpz ? -1 : 0) == -1) if (I_SongType() != MU_MOD && I_SongType() != MU_MID && Mix_PlayMusic(music, 0) == -1)
{
CONS_Alert(CONS_ERROR, "Mix_PlayMusic: %s\n", Mix_GetError());
return false;
}
else if ((I_SongType() == MU_MOD || I_SongType() == MU_MID) && Mix_PlayMusic(music, looping ? -1 : 0) == -1) // if MOD, loop forever
{ {
CONS_Alert(CONS_ERROR, "Mix_PlayMusic: %s\n", Mix_GetError()); CONS_Alert(CONS_ERROR, "Mix_PlayMusic: %s\n", Mix_GetError());
return false; return false;
} }
Mix_VolumeMusic((UINT32)music_volume*128/31);
if (!lpz) is_looping = looping;
Mix_HookMusicFinished(music_loop);
I_SetMusicVolume(music_volume);
if (I_SongType() != MU_MOD && I_SongType() != MU_MID)
Mix_HookMusicFinished(music_loop); // don't bother counting if MOD
if(I_SongType() != MU_MOD && I_SongType() != MU_MID && !Mix_RegisterEffect(MIX_CHANNEL_POST, count_music_bytes, NULL, NULL))
CONS_Alert(CONS_WARNING, "Error registering SDL music position counter: %s\n", Mix_GetError());
return true; return true;
} }
void I_StopSong(void) void I_StopSong(void)
{ {
I_StopFadingSong();
#ifdef HAVE_LIBGME #ifdef HAVE_LIBGME
if (gme) if (gme)
{ {
@ -803,19 +1133,40 @@ void I_StopSong(void)
#endif #endif
if (music) if (music)
{ {
Mix_UnregisterEffect(MIX_CHANNEL_POST, count_music_bytes);
Mix_HookMusicFinished(NULL); Mix_HookMusicFinished(NULL);
Mix_HaltMusic(); Mix_HaltMusic();
} }
var_cleanup();
} }
void I_PauseSong(void) void I_PauseSong(void)
{ {
if(I_SongType() == MU_MID) // really, SDL Mixer? why can't you pause MIDI???
return;
if(I_SongType() != MU_GME && I_SongType() != MU_MOD && I_SongType() != MU_MID)
Mix_UnregisterEffect(MIX_CHANNEL_POST, count_music_bytes);
Mix_PauseMusic(); Mix_PauseMusic();
songpaused = true; songpaused = true;
} }
void I_ResumeSong(void) void I_ResumeSong(void)
{ {
if (I_SongType() == MU_MID)
return;
if (I_SongType() != MU_GME && I_SongType() != MU_MOD && I_SongType() != MU_MID)
{
while(Mix_UnregisterEffect(MIX_CHANNEL_POST, count_music_bytes) != 0) { }
// HACK: fixes issue of multiple effect callbacks being registered
if(music && I_SongType() != MU_MOD && I_SongType() != MU_MID && !Mix_RegisterEffect(MIX_CHANNEL_POST, count_music_bytes, NULL, NULL))
CONS_Alert(CONS_WARNING, "Error registering SDL music position counter: %s\n", Mix_GetError());
}
Mix_ResumeMusic(); Mix_ResumeMusic();
songpaused = false; songpaused = false;
} }
@ -834,7 +1185,7 @@ void I_SetMusicVolume(UINT8 volume)
#endif #endif
music_volume = volume; music_volume = volume;
Mix_VolumeMusic((UINT32)music_volume*128/31); Mix_VolumeMusic(get_real_volume(music_volume));
} }
boolean I_SetSongTrack(int track) boolean I_SetSongTrack(int track)
@ -863,9 +1214,100 @@ boolean I_SetSongTrack(int track)
SDL_UnlockAudio(); SDL_UnlockAudio();
return false; return false;
} }
else
#endif #endif
if (I_SongType() == MU_MOD)
return !Mix_SetMusicPosition(track);
(void)track; (void)track;
return false; return false;
} }
/// ------------------------
/// MUSIC FADING
/// ------------------------
void I_SetInternalMusicVolume(UINT8 volume)
{
internal_volume = volume;
if (!I_SongPlaying())
return;
Mix_VolumeMusic(get_real_volume(music_volume));
}
void I_StopFadingSong(void)
{
if (fading_id)
SDL_RemoveTimer(fading_id);
is_fading = false;
fading_source = fading_target = fading_timer = fading_duration = fading_id = 0;
}
boolean I_FadeSongFromVolume(UINT8 target_volume, UINT8 source_volume, UINT32 ms, void (*callback)(void))
{
INT16 volume_delta;
source_volume = min(source_volume, 100);
volume_delta = (INT16)(target_volume - source_volume);
I_StopFadingSong();
if (!ms && volume_delta)
{
I_SetInternalMusicVolume(target_volume);
if (callback)
(*callback)();
return true;
}
else if (!volume_delta)
{
if (callback)
(*callback)();
return true;
}
// Round MS to nearest 10
// If n - lower > higher - n, then round up
ms = (ms - ((ms / 10) * 10) > (((ms / 10) * 10) + 10) - ms) ?
(((ms / 10) * 10) + 10) // higher
: ((ms / 10) * 10); // lower
if (!ms)
I_SetInternalMusicVolume(target_volume);
else if (source_volume != target_volume)
{
fading_id = SDL_AddTimer(10, music_fade, NULL);
if (fading_id)
{
is_fading = true;
fading_timer = fading_duration = ms;
fading_source = source_volume;
fading_target = target_volume;
fading_callback = callback;
if (internal_volume != source_volume)
I_SetInternalMusicVolume(source_volume);
}
}
return is_fading;
}
boolean I_FadeSong(UINT8 target_volume, UINT32 ms, void (*callback)(void))
{
return I_FadeSongFromVolume(target_volume, internal_volume, ms, callback);
}
boolean I_FadeOutStopSong(UINT32 ms)
{
return I_FadeSongFromVolume(0, internal_volume, ms, &I_StopSong);
}
boolean I_FadeInPlaySong(UINT32 ms, boolean looping)
{
if (I_PlaySong(looping))
return I_FadeSongFromVolume(100, 0, ms, NULL);
else
return false;
}
#endif #endif

View File

@ -1375,6 +1375,37 @@ boolean I_SetSongSpeed(float speed)
return false; return false;
} }
/// ------------------------
// MUSIC SEEKING
/// ------------------------
UINT32 I_GetSongLength(void)
{
return 0;
}
boolean I_SetSongLoopPoint(UINT32 looppoint)
{
(void)looppoint;
return false;
}
UINT32 I_GetSongLoopPoint(void)
{
return 0;
}
boolean I_SetSongPosition(UINT32 position)
{
(void)position;
return false;
}
UINT32 I_GetSongPosition(void)
{
return 0;
}
/// ------------------------ /// ------------------------
// MUSIC PLAYBACK // MUSIC PLAYBACK
/// ------------------------ /// ------------------------
@ -1443,6 +1474,47 @@ boolean I_SetSongTrack(int track)
return false; return false;
} }
/// ------------------------
/// MUSIC FADING
/// ------------------------
void I_SetInternalMusicVolume(UINT8 volume)
{
(void)volume;
}
void I_StopFadingSong(void)
{
}
boolean I_FadeSongFromVolume(UINT8 target_volume, UINT8 source_volume, UINT32 ms, void (*callback)(void))
{
(void)target_volume;
(void)source_volume;
(void)ms;
return false;
}
boolean I_FadeSong(UINT8 target_volume, UINT32 ms, void (*callback)(void))
{
(void)target_volume;
(void)ms;
return false;
}
boolean I_FadeOutStopSong(UINT32 ms)
{
(void)ms;
return false;
}
boolean I_FadeInPlaySong(UINT32 ms, boolean looping)
{
(void)ms;
(void)looping;
return false;
}
/// ------------------------ /// ------------------------
// MUSIC LOADING AND CLEANUP // MUSIC LOADING AND CLEANUP
// \todo Split logic between loading and playing, // \todo Split logic between loading and playing,

View File

@ -1219,7 +1219,7 @@
C01FCF4B08A954540054247B /* Debug */ = { C01FCF4B08A954540054247B /* Debug */ = {
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
buildSettings = { buildSettings = {
CURRENT_PROJECT_VERSION = 2.1.23; CURRENT_PROJECT_VERSION = 2.1.24;
GCC_PREPROCESSOR_DEFINITIONS = ( GCC_PREPROCESSOR_DEFINITIONS = (
"$(inherited)", "$(inherited)",
NORMALSRB2, NORMALSRB2,
@ -1231,7 +1231,7 @@
C01FCF4C08A954540054247B /* Release */ = { C01FCF4C08A954540054247B /* Release */ = {
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
buildSettings = { buildSettings = {
CURRENT_PROJECT_VERSION = 2.1.23; CURRENT_PROJECT_VERSION = 2.1.24;
GCC_ENABLE_FIX_AND_CONTINUE = NO; GCC_ENABLE_FIX_AND_CONTINUE = NO;
GCC_GENERATE_DEBUGGING_SYMBOLS = NO; GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
GCC_PREPROCESSOR_DEFINITIONS = ( GCC_PREPROCESSOR_DEFINITIONS = (

View File

@ -42,7 +42,7 @@ typedef enum
} skinsound_t; } skinsound_t;
// free sfx for S_AddSoundFx() // free sfx for S_AddSoundFx()
#define NUMSFXFREESLOTS 800 // Matches SOC Editor. #define NUMSFXFREESLOTS 1600 // Matches SOC Editor.
#define NUMSKINSFXSLOTS (MAXSKINS*NUMSKINSOUNDS) #define NUMSKINSFXSLOTS (MAXSKINS*NUMSKINSOUNDS)
// //

View File

@ -197,7 +197,7 @@ void ST_Ticker(void)
} }
// 0 is default, any others are special palettes. // 0 is default, any others are special palettes.
static INT32 st_palette = 0; INT32 st_palette = 0;
void ST_doPaletteStuff(void) void ST_doPaletteStuff(void)
{ {

View File

@ -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 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; extern lumpnum_t st_borderpatchnum;
// patches, also used in intermission // patches, also used in intermission

View File

@ -334,7 +334,6 @@ static restype_t ResourceFileDetect (const char* filename)
static lumpinfo_t* ResGetLumpsStandalone (FILE* handle, UINT16* numlumps, const char* lumpname) static lumpinfo_t* ResGetLumpsStandalone (FILE* handle, UINT16* numlumps, const char* lumpname)
{ {
lumpinfo_t* lumpinfo = Z_Calloc(sizeof (*lumpinfo), PU_STATIC, NULL); lumpinfo_t* lumpinfo = Z_Calloc(sizeof (*lumpinfo), PU_STATIC, NULL);
lumpinfo = Z_Calloc(sizeof (*lumpinfo), PU_STATIC, NULL);
lumpinfo->position = 0; lumpinfo->position = 0;
fseek(handle, 0, SEEK_END); fseek(handle, 0, SEEK_END);
lumpinfo->size = ftell(handle); lumpinfo->size = ftell(handle);
@ -566,14 +565,14 @@ static lumpinfo_t* ResGetLumpsZip (FILE* handle, UINT16* nlmp)
{ {
CONS_Alert(CONS_ERROR, "Failed to read central directory (%s)\n", strerror(ferror(handle))); CONS_Alert(CONS_ERROR, "Failed to read central directory (%s)\n", strerror(ferror(handle)));
Z_Free(lumpinfo); Z_Free(lumpinfo);
free(zentry); free(zentries);
return NULL; return NULL;
} }
if (memcmp(zentry->signature, pat_central, 4)) if (memcmp(zentry->signature, pat_central, 4))
{ {
CONS_Alert(CONS_ERROR, "Central directory is corrupt\n"); CONS_Alert(CONS_ERROR, "Central directory is corrupt\n");
Z_Free(lumpinfo); Z_Free(lumpinfo);
free(zentry); free(zentries);
return NULL; return NULL;
} }
@ -586,7 +585,7 @@ static lumpinfo_t* ResGetLumpsZip (FILE* handle, UINT16* nlmp)
{ {
CONS_Alert(CONS_ERROR, "Unable to read lumpname (%s)\n", strerror(ferror(handle))); CONS_Alert(CONS_ERROR, "Unable to read lumpname (%s)\n", strerror(ferror(handle)));
Z_Free(lumpinfo); Z_Free(lumpinfo);
free(zentry); free(zentries);
free(fullname); free(fullname);
return NULL; return NULL;
} }
@ -628,6 +627,8 @@ static lumpinfo_t* ResGetLumpsZip (FILE* handle, UINT16* nlmp)
} }
} }
free(zentries);
*nlmp = numlumps; *nlmp = numlumps;
return lumpinfo; return lumpinfo;
} }
@ -1325,8 +1326,9 @@ size_t W_ReadLumpHeaderPwad(UINT16 wad, UINT16 lump, void *dest, size_t size, si
{ {
size = 0; size = 0;
zerr(zErr); zerr(zErr);
(void)inflateEnd(&strm);
} }
(void)inflateEnd(&strm);
} }
else else
{ {
@ -1715,15 +1717,27 @@ int W_VerifyNMUSlumps(const char *filename)
// ENDOOM text and palette lumps // ENDOOM text and palette lumps
lumpchecklist_t NMUSlist[] = lumpchecklist_t NMUSlist[] =
{ {
{"D_", 2}, {"D_", 2}, // MIDI music
{"O_", 2}, {"O_", 2}, // Digital music
{"DS", 2}, {"DS", 2}, // Sound effects
{"ENDOOM", 6},
{"PLAYPAL", 7}, {"ENDOOM", 6}, // ENDOOM text lump
{"COLORMAP", 8},
{"PAL", 3}, {"PLAYPAL", 7}, // Palette changes
{"CLM", 3}, {"PAL", 3}, // Palette changes
{"TRANS", 5}, {"COLORMAP", 8}, // Colormap changes
{"CLM", 3}, // Colormap changes
{"TRANS", 5}, // Translucency map changes
{"LTFNT", 5}, // Level title font changes
{"TTL", 3}, // Act number changes
{"STCFN", 5}, // Console font changes
{"TNYFN", 5}, // Tiny console font changes
{"SBO", 3}, // Acceptable HUD changes (Score Time Rings)
{"RRINGS", 6}, // Rings HUD (not named as SBO)
{"YB_", 3}, // Intermission graphics, goes with the above
{"M_", 2}, // As does menu stuff
{NULL, 0}, {NULL, 0},
}; };
return W_VerifyFile(filename, NMUSlist, false); return W_VerifyFile(filename, NMUSlist, false);

View File

@ -91,6 +91,7 @@
<Import Project="..\..\libs\FMOD.props" /> <Import Project="..\..\libs\FMOD.props" />
<Import Project="..\..\libs\zlib.props" /> <Import Project="..\..\libs\zlib.props" />
<Import Project="..\..\libs\libpng.props" /> <Import Project="..\..\libs\libpng.props" />
<Import Project="..\..\libs\libgme.props" />
<Import Project="SRB2Win.props" /> <Import Project="SRB2Win.props" />
</ImportGroup> </ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">

View File

@ -5,7 +5,10 @@
<PropertyGroup /> <PropertyGroup />
<ItemDefinitionGroup> <ItemDefinitionGroup>
<ClCompile> <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> </ClCompile>
<Link /> <Link />
<Link> <Link>

View File

@ -815,6 +815,60 @@ void I_SetMusicVolume(UINT8 volume)
FMR_MUSIC(FMOD_Channel_SetVolume(music_channel, music_volume / 31.0)); FMR_MUSIC(FMOD_Channel_SetVolume(music_channel, music_volume / 31.0));
} }
UINT32 I_GetSongLength(void)
{
UINT32 length;
if (I_SongType() == MU_MID)
return 0;
FMR_MUSIC(FMOD_Sound_GetLength(music_stream, &length, FMOD_TIMEUNIT_MS));
return length;
}
boolean I_SetSongLoopPoint(UINT32 looppoint)
{
(void)looppoint;
return false;
}
UINT32 I_GetSongLoopPoint(void)
{
return 0;
}
boolean I_SetSongPosition(UINT32 position)
{
FMOD_RESULT e;
if(I_SongType() == MU_MID)
// Dummy out; this works for some MIDI, but not others.
// SDL does not support this for any MIDI.
return false;
e = FMOD_Channel_SetPosition(music_channel, position, FMOD_TIMEUNIT_MS);
if (e == FMOD_OK)
return true;
else if (e == FMOD_ERR_UNSUPPORTED // Only music modules, numbnuts!
|| e == FMOD_ERR_INVALID_POSITION) // Out-of-bounds!
return false;
else // Congrats, you horribly broke it somehow
{
FMR_MUSIC(e);
return false;
}
}
UINT32 I_GetSongPosition(void)
{
FMOD_RESULT e;
unsigned int fmposition = 0;
if(I_SongType() == MU_MID)
// Dummy out because unsupported, even though FMOD does this correctly.
return 0;
e = FMOD_Channel_GetPosition(music_channel, &fmposition, FMOD_TIMEUNIT_MS);
if (e == FMOD_OK)
return (UINT32)fmposition;
else
return 0;
}
boolean I_SetSongTrack(INT32 track) boolean I_SetSongTrack(INT32 track)
{ {
if (track != current_track) // If the track's already playing, then why bother? if (track != current_track) // If the track's already playing, then why bother?
@ -859,3 +913,46 @@ boolean I_SetSongTrack(INT32 track)
} }
return false; return false;
} }
/// ------------------------
/// MUSIC FADING
/// ------------------------
void I_SetInternalMusicVolume(UINT8 volume)
{
(void)volume;
}
void I_StopFadingSong(void)
{
}
boolean I_FadeSongFromVolume(UINT8 target_volume, UINT8 source_volume, UINT32 ms, void (*callback)(void))
{
(void)target_volume;
(void)source_volume;
(void)ms;
(void)callback;
return false;
}
boolean I_FadeSong(UINT8 target_volume, UINT32 ms, void (*callback)(void))
{
(void)target_volume;
(void)ms;
(void)callback;
return false;
}
boolean I_FadeOutStopSong(UINT32 ms)
{
(void)ms;
return false;
}
boolean I_FadeInPlaySong(UINT32 ms, boolean looping)
{
(void)ms;
(void)looping;
return false;
}

View File

@ -639,9 +639,6 @@ void I_Error(const char *error, ...)
if (!errorcount) if (!errorcount)
{ {
M_SaveConfig(NULL); // save game config, cvars.. M_SaveConfig(NULL); // save game config, cvars..
#ifndef NONET
D_SaveBan(); // save the ban list
#endif
G_SaveGameData(); G_SaveGameData();
} }

View File

@ -696,7 +696,19 @@ void Y_Ticker(void)
boolean anybonuses = false; boolean anybonuses = false;
if (!intertic) // first time only if (!intertic) // first time only
S_ChangeMusicInternal("lclear", false); // don't loop it {
if (mapheaderinfo[gamemap-1]->musinterfadeout
#ifdef _WIN32
// can't fade midi due to win32 volume hack
&& S_MusicType() != MU_MID
#endif
)
S_FadeOutStopMusic(mapheaderinfo[gamemap-1]->musinterfadeout);
else if (mapheaderinfo[gamemap-1]->musintername[0] && S_MusicExists(mapheaderinfo[gamemap-1]->musintername, !midi_disabled, !digital_disabled))
S_ChangeMusicInternal(mapheaderinfo[gamemap-1]->musintername, false); // don't loop it
else
S_ChangeMusicInternal("lclear", false); // don't loop it
}
if (intertic < TICRATE) // one second pause before tally begins if (intertic < TICRATE) // one second pause before tally begins
return; return;
@ -757,7 +769,17 @@ void Y_Ticker(void)
if (!intertic) // first time only if (!intertic) // first time only
{ {
S_ChangeMusicInternal("lclear", false); // don't loop it if (mapheaderinfo[gamemap-1]->musinterfadeout
#ifdef _WIN32
// can't fade midi due to win32 volume hack
&& S_MusicType() != MU_MID
#endif
)
S_FadeOutStopMusic(mapheaderinfo[gamemap-1]->musinterfadeout);
else if (mapheaderinfo[gamemap-1]->musintername[0] && S_MusicExists(mapheaderinfo[gamemap-1]->musintername, !midi_disabled, !digital_disabled))
S_ChangeMusicInternal(mapheaderinfo[gamemap-1]->musintername, false); // don't loop it
else
S_ChangeMusicInternal("lclear", false); // don't loop it
tallydonetic = 0; tallydonetic = 0;
} }