diff --git a/.circleci/config.yml b/.circleci/config.yml
index ca9105685..61e508e4d 100644
--- a/.circleci/config.yml
+++ b/.circleci/config.yml
@@ -3,7 +3,7 @@ jobs:
build:
working_directory: /root/SRB2
docker:
- - image: debian:jessie
+ - image: debian:stretch
environment:
CC: ccache gcc -m32
PKG_CONFIG_LIBDIR: /usr/lib/i386-linux-gnu/pkgconfig
@@ -25,6 +25,13 @@ jobs:
- run:
name: Add i386 arch
command: dpkg --add-architecture i386
+ - run:
+ name: Add STJr PPA
+ command: |
+ apt-get -qq update
+ apt-get -qq -y install dirmngr
+ apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 0B1702D71499D9C25F986507F240F4449D3B0EC6
+ echo "deb http://ppa.launchpad.net/stjr/srb2/ubuntu trusty main" >> /etc/apt/sources.list
- run:
name: Update APT listing
command: apt-get -qq update
@@ -36,14 +43,21 @@ jobs:
- v1-SRB2-APT
- run:
name: Install SDK
- command: apt-get -qq -y install git build-essential nasm libpng12-dev:i386 libsdl2-mixer-dev:i386 libgme-dev:i386 gettext ccache wget gcc-multilib upx
+ command: apt-get -qq -y --no-install-recommends install git build-essential nasm libpng-dev:i386 libsdl2-mixer-dev:i386 libgme-dev:i386 libopenmpt-dev:i386 gettext ccache wget gcc-multilib upx openssh-client
+
- save_cache:
key: v1-SRB2-APT
paths:
- /var/cache/apt/archives
- checkout
- run:
- name: Clean build
+ name: Compile without network support and BLUA
+ command: make -C src LINUX=1 ERRORMODE=1 -k NONET=1 NO_LUA=1
+ - run:
+ name: wipe build
+ command: make -C src LINUX=1 cleandep
+ - run:
+ name: rebuild depend
command: make -C src LINUX=1 clean
- restore_cache:
keys:
@@ -57,4 +71,4 @@ jobs:
- save_cache:
key: v1-SRB2-{{ .Branch }}-{{ checksum "objs/Linux/SDL/Release/depend.dep" }}
paths:
- - /root/.ccache
+ - /root/.ccache
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
index 922fac4aa..3090417dd 100644
--- a/.gitignore
+++ b/.gitignore
@@ -19,3 +19,5 @@ Win32_LIB_ASM_Release
*.db
*.opendb
/.vs
+/debian
+/assets/debian
diff --git a/.travis.yml b/.travis.yml
index 3166ed783..f2ed43000 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,53 +1,323 @@
+# Travis-CI Config
+#
+# You may use the Deployer to upload packages and builds to external servers.
+# See deployer/travis/deployer_defaults.sh for environment variables to configure.
+
language: c
sudo: required
dist: trusty
matrix:
include:
+################################
+# Test Buildbots
+# Deployer does not operate on these. See Deployer Buildbots, below.
+# These bots are disabled when a deployment is triggered by 'deployer' branch name AND DPL_TERMINATE_TESTS=1.
+# These bots remain enabled when a deployment is triggered by release tag.
+################################
- os: linux
addons:
apt:
+ sources:
+ - sourceline: 'ppa:stjr/srb2'
packages:
- libsdl2-mixer-dev
- libpng-dev
- libgl1-mesa-dev
- libgme-dev
+ - libopenmpt-dev
- p7zip-full
- gcc-4.4
compiler: gcc-4.4
+ env: GCC44=1
+ if: env(DPL_ENABLED) != "1" OR env(DPL_TERMINATE_TESTS) != "1" OR NOT branch =~ /^.*deployer.*$/
#gcc-4.4 (Ubuntu/Linaro 4.4.7-8ubuntu1) 4.4.7
- os: linux
addons:
apt:
+ sources:
+ - sourceline: 'ppa:stjr/srb2'
packages:
- libsdl2-mixer-dev
- libpng-dev
- libgl1-mesa-dev
- libgme-dev
+ - libopenmpt-dev
- p7zip-full
- gcc-4.6
compiler: gcc-4.6
+ env: GCC46=1
+ if: env(DPL_ENABLED) != "1" OR env(DPL_TERMINATE_TESTS) != "1" OR NOT branch =~ /^.*deployer.*$/
#gcc-4.6 (Ubuntu/Linaro 4.6.4-6ubuntu2) 4.6.4
- os: linux
addons:
apt:
+ sources:
+ - sourceline: 'ppa:stjr/srb2'
packages:
- libsdl2-mixer-dev
- libpng-dev
- libgl1-mesa-dev
- libgme-dev
+ - libopenmpt-dev
- p7zip-full
- gcc-4.7
compiler: gcc-4.7
+ env: GCC47=1
+ if: env(DPL_ENABLED) != "1" OR env(DPL_TERMINATE_TESTS) != "1" OR NOT branch =~ /^.*deployer.*$/
#gcc-4.7
- os: linux
compiler: gcc
+ env: GCC48=1
+ if: env(DPL_ENABLED) != "1" OR env(DPL_TERMINATE_TESTS) != "1" OR NOT branch =~ /^.*deployer.*$/
#gcc (Ubuntu 4.8.4-2ubuntu1~14.04) 4.8.4
- os: linux
addons:
apt:
sources:
- ubuntu-toolchain-r-test
+ - sourceline: 'ppa:stjr/srb2'
+ packages:
+ - libsdl2-mixer-dev
+ - libpng-dev
+ - libgl1-mesa-dev
+ - libgme-dev
+ - libopenmpt-dev
+ - p7zip-full
+ - gcc-4.8
+ compiler: gcc-4.8
+ env: GCC48=1
+ if: env(DPL_ENABLED) != "1" OR env(DPL_TERMINATE_TESTS) != "1" OR NOT branch =~ /^.*deployer.*$/
+ #gcc-4.8 (Ubuntu 4.8.5-2ubuntu1~14.04.1) 4.8.5
+ - os: linux
+ addons:
+ apt:
+ sources:
+ - ubuntu-toolchain-r-test
+ - sourceline: 'ppa:stjr/srb2'
+ packages:
+ - libsdl2-mixer-dev
+ - libpng-dev
+ - libgl1-mesa-dev
+ - libgme-dev
+ - libopenmpt-dev
+ - p7zip-full
+ - gcc-7
+ compiler: gcc-7
+ env: WFLAGS="-Wno-tautological-compare -Wno-error=implicit-fallthrough -Wno-implicit-fallthrough" GCC72=1
+ if: env(DPL_ENABLED) != "1" OR env(DPL_TERMINATE_TESTS) != "1" OR NOT branch =~ /^.*deployer.*$/
+ #gcc-7 (Ubuntu 7.2.0-1ubuntu1~14.04) 7.2.0 20170802
+ - os: linux
+ addons:
+ apt:
+ sources:
+ - ubuntu-toolchain-r-test
+ - sourceline: 'ppa:stjr/srb2'
+ packages:
+ - libsdl2-mixer-dev
+ - libpng-dev
+ - libgl1-mesa-dev
+ - libgme-dev
+ - libopenmpt-dev
+ - p7zip-full
+ - gcc-8
+ compiler: gcc-8
+ env: WFLAGS="-Wno-tautological-compare -Wno-error=implicit-fallthrough -Wno-implicit-fallthrough -Wno-error=format-overflow -Wno-error=format-truncation" GCC81=1
+ if: env(DPL_ENABLED) != "1" OR env(DPL_TERMINATE_TESTS) != "1" OR NOT branch =~ /^.*deployer.*$/
+ #gcc-8 (Ubuntu 7.2.0-1ubuntu1~14.04) 8.1.0
+ - os: linux
+ compiler: clang
+ if: env(DPL_ENABLED) != "1" OR env(DPL_TERMINATE_TESTS) != "1" OR NOT branch =~ /^.*deployer.*$/
+ #clang version 3.5.0 (tags/RELEASE_350/final)
+ - os: linux
+ addons:
+ apt:
+ sources:
+ - llvm-toolchain-precise-3.5
+ - sourceline: 'ppa:stjr/srb2'
+ packages:
+ - libsdl2-mixer-dev
+ - libpng-dev
+ - libgl1-mesa-dev
+ - libgme-dev
+ - libopenmpt-dev
+ - p7zip-full
+ - clang-3.5
+ compiler: clang-3.5
+ if: env(DPL_ENABLED) != "1" OR env(DPL_TERMINATE_TESTS) != "1" OR NOT branch =~ /^.*deployer.*$/
+ #Ubuntu clang version 3.5.0-4ubuntu2~trusty2 (tags/RELEASE_350/final) (based on LLVM 3.5.0)
+ - os: linux
+ addons:
+ apt:
+ sources:
+ - llvm-toolchain-precise-3.6
+ - ubuntu-toolchain-r-test
+ - sourceline: 'ppa:stjr/srb2'
+ packages:
+ - libsdl2-mixer-dev
+ - libpng-dev
+ - libgl1-mesa-dev
+ - libgme-dev
+ - libopenmpt-dev
+ - p7zip-full
+ - clang-3.6
+ compiler: clang-3.6
+ if: env(DPL_ENABLED) != "1" OR env(DPL_TERMINATE_TESTS) != "1" OR NOT branch =~ /^.*deployer.*$/
+ #Ubuntu clang version 3.6.2-svn240577-1~exp1 (branches/release_36) (based on LLVM 3.6.2)
+ - os: linux
+ addons:
+ apt:
+ sources:
+ - llvm-toolchain-precise-3.7
+ - ubuntu-toolchain-r-test
+ - sourceline: 'ppa:stjr/srb2'
+ packages:
+ - libsdl2-mixer-dev
+ - libpng-dev
+ - libgl1-mesa-dev
+ - libgme-dev
+ - libopenmpt-dev
+ - p7zip-full
+ - clang-3.7
+ compiler: clang-3.7
+ if: env(DPL_ENABLED) != "1" OR env(DPL_TERMINATE_TESTS) != "1" OR NOT branch =~ /^.*deployer.*$/
+ #Ubuntu clang version 3.7.1-svn253571-1~exp1 (branches/release_37) (based on LLVM 3.7.1)
+ - os: linux
+ addons:
+ apt:
+ sources:
+ - llvm-toolchain-precise-3.8
+ - ubuntu-toolchain-r-test
+ - sourceline: 'ppa:stjr/srb2'
+ packages:
+ - libsdl2-mixer-dev
+ - libpng-dev
+ - libgl1-mesa-dev
+ - libgme-dev
+ - libopenmpt-dev
+ - p7zip-full
+ - clang-3.8
+ compiler: clang-3.8
+ if: env(DPL_ENABLED) != "1" OR env(DPL_TERMINATE_TESTS) != "1" OR NOT branch =~ /^.*deployer.*$/
+ #clang version 3.8.1-svn271127-1~exp1 (branches/release_38)
+ - os: linux
+ addons:
+ apt:
+ sources:
+ - llvm-toolchain-precise-3.9
+ - ubuntu-toolchain-r-test
+ - sourceline: 'ppa:stjr/srb2'
+ packages:
+ - libsdl2-mixer-dev
+ - libpng-dev
+ - libgl1-mesa-dev
+ - libgme-dev
+ - libopenmpt-dev
+ - p7zip-full
+ - clang-3.9
+ compiler: clang-3.9
+ if: env(DPL_ENABLED) != "1" OR env(DPL_TERMINATE_TESTS) != "1" OR NOT branch =~ /^.*deployer.*$/
+ #clang version 3.9.X
+# - os: linux
+# addons:
+# apt:
+# sources:
+# - llvm-toolchain-precise-4.0
+# - ubuntu-toolchain-r-test
+# - sourceline: 'ppa:stjr/srb2'
+# packages:
+# - libsdl2-mixer-dev
+# - libpng-dev
+# - libgl1-mesa-dev
+# - libgme-dev
+# - libopenmpt-dev
+# - p7zip-full
+# - clang-4.0
+# compiler: clang-4.0
+# if: env(DPL_ENABLED) != "1" OR env(DPL_TERMINATE_TESTS) != "1" OR NOT branch =~ /^.*deployer.*$/
+# #clang version 4.0.X
+# - os: linux
+# addons:
+# apt:
+# sources:
+# - llvm-toolchain-precise-5.0
+# - ubuntu-toolchain-r-test
+# - sourceline: 'ppa:stjr/srb2'
+# packages:
+# - libsdl2-mixer-dev
+# - libpng-dev
+# - libgl1-mesa-dev
+# - libgme-dev
+# - libopenmpt-dev
+# - p7zip-full
+# - clang-5.0
+# compiler: clang-5.0
+# if: env(DPL_ENABLED) != "1" OR env(DPL_TERMINATE_TESTS) != "1" OR NOT branch =~ /^.*deployer.*$/
+# #clang version 5.0.X
+# - os: osx
+# osx_image: beta-xcode6.1
+# if: env(DPL_ENABLED) != "1" OR env(DPL_TERMINATE_TESTS) != "1" OR NOT branch =~ /^.*deployer.*$/
+# #Apple LLVM version 6.0 (clang-600.0.54) (based on LLVM 3.5svn)
+# - os: osx
+# osx_image: beta-xcode6.2
+# compiler: gcc
+# if: env(DPL_ENABLED) != "1" OR env(DPL_TERMINATE_TESTS) != "1" OR NOT branch =~ /^.*deployer.*$/
+# #Apple LLVM version 6.0 (clang-600.0.57) (based on LLVM 3.5svn)
+## - os: osx
+## osx_image: beta-xcode6.3
+## if: env(DPL_ENABLED) != "1" OR env(DPL_TERMINATE_TESTS) != "1" OR NOT branch =~ /^.*deployer.*$/
+## #I think xcode.6.3 VM is broken, it does not boot
+# - os: osx
+# osx_image: xcode6.4
+# if: env(DPL_ENABLED) != "1" OR env(DPL_TERMINATE_TESTS) != "1" OR NOT branch =~ /^.*deployer.*$/
+# #Apple LLVM version 6.1.0 (clang-602.0.53) (based on LLVM 3.6.0svn)
+# - os: osx
+# osx_image: xcode7
+# if: env(DPL_ENABLED) != "1" OR env(DPL_TERMINATE_TESTS) != "1" OR NOT branch =~ /^.*deployer.*$/
+# #Apple LLVM version 7.0.0 (clang-700.0.72)
+# - os: osx
+# osx_image: xcode7.1
+# if: env(DPL_ENABLED) != "1" OR env(DPL_TERMINATE_TESTS) != "1" OR NOT branch =~ /^.*deployer.*$/
+# #Apple LLVM version 7.0.0 (clang-700.1.76)
+# - os: osx
+# osx_image: xcode7.2
+# if: env(DPL_ENABLED) != "1" OR env(DPL_TERMINATE_TESTS) != "1" OR NOT branch =~ /^.*deployer.*$/
+# #Apple LLVM version 7.0.2 (clang-700.1.81)
+# - os: osx
+# osx_image: xcode7.3
+# #Apple LLVM version 7.3.0 (clang-703.0.31)
+# - os: osx
+# osx_image: xcode7.3
+# #Apple LLVM version 7.3.0 (clang-703.0.31)
+ - os: osx
+ if: env(DPL_ENABLED) != "1" OR env(DPL_TERMINATE_TESTS) != "1" OR NOT branch =~ /^.*deployer.*$/
+ #Default: macOS 10.13 and Xcode 9.4.1
+
+
+################################
+# Deployer Buildbots - OSX
+################################
+ - os: osx
+ if: env(DPL_ENABLED) = "1" AND (env(_DPL_JOB_ENABLED) = "1" OR env(DPL_JOB_ENABLE_ALL) = "1")
+ AND (branch =~ /^.*deployer.*$/ OR (tag IS present AND env(DPL_TAG_ENABLED) = "1"))
+ AND env(DPL_TERMINATE_MAIN) != "1"
+ env:
+ - _DPL_JOB_ENABLED=1
+ - _DPL_JOB_NAME=osx
+ - _DPL_FTP_TARGET=1
+ - _DPL_PACKAGE_BINARY=1
+ #Apple LLVM version 7.3.0 (clang-703.0.31)
+
+
+################################
+# Deployer Buildbots - Linux assets
+# Set DPL_TERMINATE_ASSETS to disable all of these
+# List Ubuntu LTS next, newest to oldest
+# Then list non-LTS, newest to oldest
+################################
+ - os: linux
+ addons:
+ apt:
packages:
- libsdl2-mixer-dev
- libpng-dev
@@ -56,169 +326,251 @@ matrix:
- 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:
- sources:
- - ubuntu-toolchain-r-test
packages:
- libsdl2-mixer-dev
- libpng-dev
- libgl1-mesa-dev
- libgme-dev
- p7zip-full
- - gcc-7
- compiler: gcc-7
- env: WFLAGS="-Wno-tautological-compare -Wno-error=implicit-fallthrough -Wno-implicit-fallthrough"
- #gcc-7 (Ubuntu 7.2.0-1ubuntu1~14.04) 7.2.0 20170802
+ - 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:
- sources:
- - ubuntu-toolchain-r-test
packages:
- libsdl2-mixer-dev
- libpng-dev
- libgl1-mesa-dev
- libgme-dev
- p7zip-full
- - gcc-8
- compiler: gcc-8
- env: WFLAGS="-Wno-tautological-compare -Wno-error=implicit-fallthrough -Wno-implicit-fallthrough -Wno-error=format-overflow"
- #gcc-8 (Ubuntu 7.2.0-1ubuntu1~14.04) 8.1.0
- - os: linux
- compiler: clang
- #clang version 3.5.0 (tags/RELEASE_350/final)
+ - 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:
- sources:
- - llvm-toolchain-precise-3.5
packages:
- libsdl2-mixer-dev
- libpng-dev
- libgl1-mesa-dev
- libgme-dev
- p7zip-full
- - clang-3.5
- compiler: clang-3.5
- #Ubuntu clang version 3.5.0-4ubuntu2~trusty2 (tags/RELEASE_350/final) (based on LLVM 3.5.0)
+ - 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:
- sources:
- - llvm-toolchain-precise-3.6
- - ubuntu-toolchain-r-test
packages:
- libsdl2-mixer-dev
- libpng-dev
- libgl1-mesa-dev
- libgme-dev
- p7zip-full
- - clang-3.6
- compiler: clang-3.6
- #Ubuntu clang version 3.6.2-svn240577-1~exp1 (branches/release_36) (based on LLVM 3.6.2)
- - os: linux
- addons:
- apt:
- sources:
- - llvm-toolchain-precise-3.7
- - ubuntu-toolchain-r-test
- packages:
- - libsdl2-mixer-dev
- - libpng-dev
- - libgl1-mesa-dev
- - libgme-dev
- - p7zip-full
- - clang-3.7
- compiler: clang-3.7
- #Ubuntu clang version 3.7.1-svn253571-1~exp1 (branches/release_37) (based on LLVM 3.7.1)
- - os: linux
- addons:
- apt:
- sources:
- - llvm-toolchain-precise-3.8
- - ubuntu-toolchain-r-test
- packages:
- - libsdl2-mixer-dev
- - libpng-dev
- - libgl1-mesa-dev
- - libgme-dev
- - p7zip-full
- - clang-3.8
- compiler: clang-3.8
- #clang version 3.8.1-svn271127-1~exp1 (branches/release_38)
- - os: linux
- addons:
- apt:
- sources:
- - llvm-toolchain-precise-3.9
- - ubuntu-toolchain-r-test
- packages:
- - libsdl2-mixer-dev
- - libpng-dev
- - libgl1-mesa-dev
- - libgme-dev
- - p7zip-full
- - clang-3.9
- compiler: clang-3.9
- #clang version 3.9.X
-# - os: linux
-# addons:
-# apt:
-# sources:
-# - llvm-toolchain-precise-4.0
-# - ubuntu-toolchain-r-test
-# packages:
-# - libsdl2-mixer-dev
-# - libpng-dev
-# - libgl1-mesa-dev
-# - libgme-dev
-# - p7zip-full
-# - clang-4.0
-# compiler: clang-4.0
-# #clang version 4.0.X
-# - os: linux
-# addons:
-# apt:
-# sources:
-# - llvm-toolchain-precise-5.0
-# - ubuntu-toolchain-r-test
-# packages:
-# - libsdl2-mixer-dev
-# - libpng-dev
-# - libgl1-mesa-dev
-# - libgme-dev
-# - p7zip-full
-# - clang-5.0
-# compiler: clang-5.0
-# #clang version 5.0.X
-# - os: osx
-# osx_image: beta-xcode6.1
-# #Apple LLVM version 6.0 (clang-600.0.54) (based on LLVM 3.5svn)
-# - os: osx
-# osx_image: beta-xcode6.2
-# compiler: gcc
-# #Apple LLVM version 6.0 (clang-600.0.57) (based on LLVM 3.5svn)
-## - os: osx
-## osx_image: beta-xcode6.3
-## #I think xcode.6.3 VM is broken, it does not boot
-# - os: osx
-# osx_image: xcode6.4
-# #Apple LLVM version 6.1.0 (clang-602.0.53) (based on LLVM 3.6.0svn)
-# - os: osx
-# osx_image: xcode7
-# #Apple LLVM version 7.0.0 (clang-700.0.72)
-# - os: osx
-# osx_image: xcode7.1
-# #Apple LLVM version 7.0.0 (clang-700.1.76)
-# - os: osx
-# osx_image: xcode7.2
-# #Apple LLVM version 7.0.2 (clang-700.1.81)
- - os: osx
- osx_image: xcode7.3
- #Apple LLVM version 7.3.0 (clang-703.0.31)
+ - gcc-4.8
+ compiler: gcc-4.8
+ dist: xenial
+ if: env(DPL_ENABLED) = "1" AND (env(_DPL_JOB_ENABLED) = "1" OR env(DPL_JOB_ENABLE_ALL) = "1")
+ AND (branch =~ /^.*deployer.*$/ OR (tag IS present AND env(DPL_TAG_ENABLED) = "1"))
+ AND env(DPL_TERMINATE_MAIN) != "1"
+ env:
+ - _DPL_JOB_ENABLED=1
+ - _DPL_JOB_NAME=xenial
+ - _DPL_DPUT_TARGET=1
+ - _DPL_PACKAGE_SOURCE=1
+ - PACKAGE_DISTRO=xenial
+ - PACKAGE_SUBVERSION=~16.04xenial
+ #gcc-4.8 (Ubuntu 4.8.5-2ubuntu1~14.04.1) 4.8.5
allow_failures:
- compiler: clang-3.5
- compiler: clang-3.6
@@ -227,7 +579,7 @@ matrix:
- compiler: clang-3.9
- compiler: clang-4.0
- compiler: clang-5.0
- - compiler: gcc-8
+
cache:
apt: true
@@ -235,30 +587,140 @@ cache:
directories:
- $HOME/srb2_cache
+
addons:
apt:
+ sources:
+ - sourceline: 'ppa:stjr/srb2'
packages:
- libsdl2-mixer-dev
- libpng-dev
- libgl1-mesa-dev
- libgme-dev
+ - zlib1g-dev
+ - libopenmpt-dev
- p7zip-full
+ homebrew:
+ taps:
+ - mazmazz/srb2
+ packages:
+ - sdl2_mixer
+ - game-music-emu
+ - p7zip
+ - libopenmpt
+ - cmake
+ 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:
- - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew update ; fi
- - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew install sdl2 sdl2_mixer game-music-emu p7zip; fi
- - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew install cmake||true; fi
- - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then curl -O -L https://www.libsdl.org/release/SDL2-2.0.6.dmg; hdiutil attach SDL2-2.0.6.dmg; sudo cp -a /Volumes/SDL2/SDL2.framework /Library/Frameworks/; fi
- - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then curl -O -L https://www.libsdl.org/projects/SDL_mixer/release/SDL2_mixer-2.0.1.dmg; hdiutil attach SDL2_mixer-2.0.1.dmg; sudo cp -a /Volumes/SDL2_mixer/SDL2_mixer.framework /Library/Frameworks/; fi
+ # Initialize Deployer defaults
+ - . ./deployer/travis/deployer_defaults.sh
+
+ # Initialize Deployer; check if Deployer is enabled
+ # This needs to be run in the current shell so that $__DPL_ACTIVE is set for this session
+ - . ./deployer/travis/deployer.sh
+
+ # Also check if we should now terminate -- see `deployer.sh` for conditions.
+ # This should never happen on non-release buildbots when Deployer is not triggered.
+ - if [[ "$__DPL_TRY_TERMINATE_EARLY" == "1" ]]; then
+ if [[ "$__DPL_ACTIVE" != "1" ]]; then
+ echo "Exiting early because this job is not deploying.";
+ exit;
+ fi;
+ fi
+
+ # If we're triggered by release tag, force ASSET_FILES_OPTIONAL_GET=1
+ - if [[ "$__DPL_TAG_ELIGIBLE" = "1" ]]; then
+ ASSET_FILES_OPTIONAL_GET=1;
+ fi;
+
+
+install:
+ # Install OS X library dependencies via Homebrew
+ # Do this differently for release buildbots:
+ # * `brew install --build-bottle` builds libraries for x86_64's lowest common denominator CPU, core2
+ # * `sdl2_mixer` requires options from the formula tap https://github.com/mazmazz/homebrew-srb2
+ # * `brew postinstall` runs post-install scripts after building a bottle
+ - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then
+ if [[ "$__DPL_ACTIVE" == "1" ]]; then
+ brew install --build-bottle sdl2 game-music-emu;
+ brew install --build-bottle mazmazz/srb2/sdl2_mixer --with-flac --with-mpg123;
+ brew postinstall sdl2 game-music-emu mazmazz/srb2/sdl2_mixer;
+ fi;
+ fi
- mkdir -p $HOME/srb2_cache
-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
diff --git a/CMakeLists.txt b/CMakeLists.txt
index ec96b7030..96e32a06d 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,6 +1,8 @@
cmake_minimum_required(VERSION 3.0)
+# DO NOT CHANGE THIS SRB2 STRING! Some variable names depend on this string.
+# Version change is fine.
project(SRB2
- VERSION 2.1.21
+ VERSION 2.1.25
LANGUAGES C)
if(${PROJECT_SOURCE_DIR} MATCHES ${PROJECT_BINARY_DIR})
@@ -54,13 +56,19 @@ macro(copy_files_to_build_dir target dlllist_var)
endif()
endmacro()
-# 64-bit check
-if(${CMAKE_SIZEOF_VOID_P} EQUAL 8)
+# bitness check
+set(SRB2_SYSTEM_BITS 0)
+if(CMAKE_SIZEOF_VOID_P EQUAL 8)
message(STATUS "Target is 64-bit")
set(SRB2_SYSTEM_BITS 64)
-else()
+endif()
+if(CMAKE_SIZEOF_VOID_P EQUAL 4)
+ message(STATUS "Target is 32-bit")
set(SRB2_SYSTEM_BITS 32)
endif()
+if(${SRB2_SYSTEM_BITS} EQUAL 0)
+ message(STATUS "Target bitness is unknown")
+endif()
# OS macros
if (UNIX)
@@ -86,8 +94,8 @@ set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin")
set(CMAKE_PDB_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin")
# Set EXE names so the assets CMakeLists can refer to its target
-set(SRB2_SDL2_EXE_NAME srb2)
-set(SRB2_WIN_EXE_NAME srb2dd)
+set(SRB2_SDL2_EXE_NAME srb2 CACHE STRING "Executable binary output name")
+set(SRB2_WIN_EXE_NAME srb2dd CACHE STRING "Executable binary output name for DirectDraw build")
include_directories(${CMAKE_CURRENT_BINARY_DIR}/src)
@@ -116,8 +124,8 @@ if(${CMAKE_SYSTEM} MATCHES "Darwin")
set(CPACK_GENERATOR "DragNDrop")
endif()
-set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Sonic Robo Blast 2")
-set(CPACK_PACKAGE_VENDOR "Sonic Team Jr.")
+set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Sonic Robo Blast 2" CACHE STRING "Program name for display purposes")
+set(CPACK_PACKAGE_VENDOR "Sonic Team Jr." CACHE STRING "Vendor name for display purposes")
#set(CPACK_PACKAGE_DESCRIPTION_FILE )
set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/LICENSE")
set(CPACK_PACKAGE_VERSION_MAJOR ${SRB2_VERSION_MAJOR})
diff --git a/README.md b/README.md
index 7d92ab303..8a5ca1a1f 100644
--- a/README.md
+++ b/README.md
@@ -12,6 +12,7 @@
- SDL2-Mixer (Linux/OS X only)
- libupnp (Linux/OS X only)
- libgme (Linux/OS X only)
+- libopenmpt (Linux/OS X only)
## Compiling
diff --git a/SRB2_Debug.props b/SRB2_Debug.props
index 8be11c58a..74177c6ef 100644
--- a/SRB2_Debug.props
+++ b/SRB2_Debug.props
@@ -22,6 +22,7 @@
Debug
+ true
diff --git a/SRB2_Release.props b/SRB2_Release.props
index a216ea45a..905dfdcf9 100644
--- a/SRB2_Release.props
+++ b/SRB2_Release.props
@@ -24,6 +24,7 @@
DebugFastLinktruetrue
+ true
diff --git a/SRB2_common.props b/SRB2_common.props
index 2fb2eb8c6..0f80ceb17 100644
--- a/SRB2_common.props
+++ b/SRB2_common.props
@@ -18,7 +18,7 @@
4244;4267
- ws2_32.lib;%(AdditionalDependencies)
+ advapi32.lib;ws2_32.lib;%(AdditionalDependencies)Windowsfalsetrue
diff --git a/appveyor.yml b/appveyor.yml
index 061613c4d..d58976fd5 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -1,11 +1,15 @@
-version: 2.1.21.{branch}-{build}
+version: 2.1.25.{branch}-{build}
os: MinGW
environment:
CC: ccache
CCACHE_CC: i686-w64-mingw32-gcc
+ CCACHE_CC_64: x86_64-w64-mingw32-gcc
WINDRES: windres
+ # c:\mingw-w64 i686 has gcc 6.3.0, so use c:\msys64 7.3.0 instead
MINGW_SDK: c:\msys64\mingw32
+ # c:\msys64 x86_64 has gcc 8.2.0, so use c:\mingw-w64 7.3.0 instead
+ MINGW_SDK_64: C:\mingw-w64\x86_64-7.3.0-posix-seh-rt_v5-rev0\mingw64
CFLAGS: -Wall -W -Werror -Wno-error=implicit-fallthrough -Wimplicit-fallthrough=3 -Wno-tautological-compare -Wno-error=suggest-attribute=noreturn
NASM_ZIP: nasm-2.12.01
NASM_URL: http://www.nasm.us/pub/nasm/releasebuilds/2.12.01/win64/nasm-2.12.01-win64.zip
@@ -15,65 +19,114 @@ environment:
CCACHE_URL: http://alam.srb2.org/ccache.exe
CCACHE_COMPRESS: true
CCACHE_DIR: C:\Users\appveyor\.ccache
+ # Disable UPX by default. The user can override this in their Appveyor project settings
+ NOUPX: 1
+ ##############################
+ # DEPLOYER VARIABLES
+ # DPL_ENABLED=1 builds installers for branch names starting with `deployer`.
+ # DPL_TAG_ENABLED=1 will also build installers for release tags. DPL_ENABLED=1 must also be set.
+ # Set these in the Appveyor project settings
+ ##############################
+ DPL_ENABLED: 0
+ DPL_TAG_ENABLED: 0
+ DPL_INSTALLER_NAME: SRB2-v2123
+ # Asset handling is barebones vs. Travis Deployer. We operate on 7z only.
+ # Include the README files and the OpenGL batch in the main and patch archives.
+ # The x86/x64 archives contain the DLL binaries.
+ ASSET_ARCHIVE_PATH: https://github.com/mazmazz/SRB2/releases/download/SRB2_assets/SRB2-v2122-assets.7z
+ ASSET_ARCHIVE_PATCH_PATH: https://github.com/mazmazz/SRB2/releases/download/SRB2_assets/SRB2-v2122-patch-assets.7z
+ ASSET_ARCHIVE_X86_PATH: https://github.com/mazmazz/SRB2/releases/download/SRB2_assets/SRB2-v2122-x86-assets.7z
+ ASSET_ARCHIVE_X64_PATH: https://github.com/mazmazz/SRB2/releases/download/SRB2_assets/SRB2-v2122-x64-assets.7z
+ ASSET_ARCHIVE_OPTIONAL_PATH: https://github.com/mazmazz/SRB2/releases/download/SRB2_assets/SRB2-v2122-optional-assets.7z
+ # This is overridden to 1 for release tag builds
+ ASSET_FILES_OPTIONAL_GET: 0
+ # For patches, also include the X86/X64 DLLs.
+ PACKAGE_PATCH_DLL_GET: 0
+ # Delete all asset downloads so they can be redownloaded
+ ASSET_CLEAN: 0
cache:
- nasm-2.12.01.zip
- upx391w.zip
- ccache.exe
- C:\Users\appveyor\.ccache
+- C:\Users\appveyor\srb2_cache
install:
+- if [%CONFIGURATION%] == [SDL64] ( set "X86_64=1" )
+- if [%CONFIGURATION%] == [SDL64] ( set "CONFIGURATION=SDL" )
+- if [%CONFIGURATION%] == [DD64] ( set "X86_64=1" )
+- if [%CONFIGURATION%] == [DD64] ( set "CONFIGURATION=DD" )
+- if [%X86_64%] == [1] ( set "MINGW_SDK=%MINGW_SDK_64%" )
+- if [%X86_64%] == [1] ( set "CCACHE_CC=%CCACHE_CC_64%" )
+
- if not exist "%NASM_ZIP%.zip" appveyor DownloadFile "%NASM_URL%" -FileName "%NASM_ZIP%.zip"
- 7z x -y "%NASM_ZIP%.zip" -o%TMP% >null
-- robocopy /S /xx /ns /nc /nfl /ndl /np /njh /njs %TMP%\%NASM_ZIP% %MINGW_SDK%\bin nasm.exe || exit 0
+- robocopy /S /xx /ns /nc /nfl /ndl /np /njh /njs "%TMP%\%NASM_ZIP%" "%MINGW_SDK%\bin" nasm.exe || exit 0
- if not exist "%UPX_ZIP%.zip" appveyor DownloadFile "%UPX_URL%" -FileName "%UPX_ZIP%.zip"
- 7z x -y "%UPX_ZIP%.zip" -o%TMP% >null
-- robocopy /S /xx /ns /nc /nfl /ndl /np /njh /njs %TMP%\%UPX_ZIP% %MINGW_SDK%\bin upx.exe || exit 0
+- robocopy /S /xx /ns /nc /nfl /ndl /np /njh /njs "%TMP%\%UPX_ZIP%" "%MINGW_SDK%\bin" upx.exe || exit 0
- if not exist "%CCACHE_EXE%" appveyor DownloadFile "%CCACHE_URL%" -FileName "%CCACHE_EXE%"
- ccache -M 99M
-- xcopy /Y /V /I ccache.exe %MINGW_SDK%\bin
+- xcopy /Y /V /I ccache.exe "%MINGW_SDK%\bin"
configuration:
- SDL
+- SDL64
- DD
+- DD64
matrix:
allow_failures:
- configuration: DD
+ - configuration: DD64
before_build:
-- set Path=%MINGW_SDK%\bin;%Path%
-- i686-w64-mingw32-gcc --version
+- set "Path=%MINGW_SDK%\bin;%Path%"
+- if [%X86_64%] == [1] ( x86_64-w64-mingw32-gcc --version ) else ( i686-w64-mingw32-gcc --version )
- mingw32-make --version
-- nasm -v
-- upx -V
+- if not [%X86_64%] == [1] ( nasm -v )
+- if not [%NOUPX%] == [1] ( upx -V )
- ccache -V
- ccache -s
-- set SRB2_MFLAGS=-C src MINGW=1 WARNINGMODE=1 GCC72=1 CCACHE=1 NOOBJDUMP=1
+- if [%NOUPX%] == [1] ( set "NOUPX=NOUPX=1" ) else ( set "NOUPX=" )
+- set "SRB2_MFLAGS=-C src WARNINGMODE=1 CCACHE=1 GCC73=1 NOOBJDUMP=1 %NOUPX%"
+- if [%X86_64%] == [1] ( set "MINGW_FLAGS=MINGW64=1 X86_64=1" ) else ( set "MINGW_FLAGS=MINGW=1 GCC91=1" )
+- set "SRB2_MFLAGS=%SRB2_MFLAGS% %MINGW_FLAGS% %CONFIGURATION%=1"
build_script:
-- cmd: mingw32-make.exe %SRB2_MFLAGS% %CONFIGURATION%=1 clean
-- cmd: mingw32-make.exe %SRB2_MFLAGS% %CONFIGURATION%=1 ERRORMODE=1 -k
+- cmd: mingw32-make.exe %SRB2_MFLAGS% clean
+- cmd: mingw32-make.exe %SRB2_MFLAGS% ERRORMODE=1 -k
after_build:
+- if [%X86_64%] == [1] (
+ set "BUILD_PATH=bin\Mingw64\Release"
+ ) else (
+ set "BUILD_PATH=bin\Mingw\Release"
+ )
+- if [%X86_64%] == [1] ( set "CONFIGURATION=%CONFIGURATION%64" )
- ccache -s
- cmd: git rev-parse --short %APPVEYOR_REPO_COMMIT%>%TMP%/gitshort.txt
- cmd: set /P GITSHORT=<%TMP%/gitshort.txt
- set BUILD_ARCHIVE=%APPVEYOR_REPO_BRANCH%-%GITSHORT%-%CONFIGURATION%.7z
- set BUILDSARCHIVE=%APPVEYOR_REPO_BRANCH%-%CONFIGURATION%.7z
-- cmd: 7z a %BUILD_ARCHIVE% bin\Mingw\Release -xr!.gitignore
+- cmd: 7z a %BUILD_ARCHIVE% %BUILD_PATH% -xr!.gitignore
- appveyor PushArtifact %BUILD_ARCHIVE%
- cmd: copy %BUILD_ARCHIVE% %BUILDSARCHIVE%
- appveyor PushArtifact %BUILDSARCHIVE%
+##############################
+# DEPLOYER SCRIPT
+##############################
+- if [%DPL_ENABLED%] == [1] ( call "deployer\appveyor\deployer.bat" )
test: off
#deploy:
# - provider: FTP
# protocol: ftps
-# host:
+# host:
# secure: NsLJEPIBvmwCOj8Tg8RoRQ==
# username:
# secure: ejxi5mvk7oLYu7QtbYojajEPigMy0mokaKhuEVuDZcA=
diff --git a/assets/.gitignore b/assets/.gitignore
index 9ed61ca1a..d6e46a75b 100644
--- a/assets/.gitignore
+++ b/assets/.gitignore
@@ -1,5 +1,10 @@
-*
-*.*
+*.srb
+*.pk3
+*.dta
+*.wad
+*.txt
!README.txt
!LICENSE.txt
-!LICENSE-3RD-PARTY.txt
\ No newline at end of file
+!LICENSE-3RD-PARTY.txt
+!CMakeLists.txt
+!debian-template/*
diff --git a/assets/CMakeLists.txt b/assets/CMakeLists.txt
index 6edb3df13..68ff0fdf9 100644
--- a/assets/CMakeLists.txt
+++ b/assets/CMakeLists.txt
@@ -1,40 +1,58 @@
## Assets Target Configuration ##
-# MD5 generation
-set(SRB2_ASSET_ALL
- ${CMAKE_CURRENT_SOURCE_DIR}/srb2.srb
- ${CMAKE_CURRENT_SOURCE_DIR}/player.dta
- ${CMAKE_CURRENT_SOURCE_DIR}/rings.dta
- ${CMAKE_CURRENT_SOURCE_DIR}/zones.dta
- ${CMAKE_CURRENT_SOURCE_DIR}/patch.dta
- ${CMAKE_CURRENT_SOURCE_DIR}/music.dta
- ${CMAKE_CURRENT_SOURCE_DIR}/README.txt
- ${CMAKE_CURRENT_SOURCE_DIR}/LICENSE.txt
- ${CMAKE_CURRENT_SOURCE_DIR}/LICENSE-3RD-PARTY.txt
-)
+# For prepending the current source path, later
+FUNCTION(PREPEND var prefix)
+ SET(listVar "")
+ FOREACH(f ${ARGN})
+ LIST(APPEND listVar "${prefix}/${f}")
+ ENDFOREACH(f)
+ SET(${var} "${listVar}" PARENT_SCOPE)
+ENDFUNCTION(PREPEND)
+
+set(SRB2_ASSET_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/installer"
+ CACHE STRING "Path to directory that contains all asset files for the installer.")
set(SRB2_ASSET_HASHED
- srb2.srb
- player.dta
- rings.dta
- zones.dta
- patch.dta
+"srb2.srb;\
+player.dta;\
+rings.dta;\
+zones.dta;\
+patch.dta"
+ CACHE STRING "Asset filenames to apply MD5 checks. No spaces between entries!"
)
+set(SRB2_ASSET_DOCS
+"README.txt;\
+LICENSE.txt;\
+LICENSE-3RD-PARTY.txt"
+ CACHE STRING "Documentation filenames. In OS X, these are packaged separately from other assets. No spaces between entries!"
+)
+
+PREPEND(SRB2_ASSET_DOCS ${SRB2_ASSET_DIRECTORY} ${SRB2_ASSET_DOCS})
+
foreach(SRB2_ASSET ${SRB2_ASSET_HASHED})
- file(MD5 ${CMAKE_CURRENT_SOURCE_DIR}/${SRB2_ASSET} "SRB2_ASSET_${SRB2_ASSET}_HASH")
+ file(MD5 ${SRB2_ASSET_DIRECTORY}/${SRB2_ASSET} "SRB2_ASSET_${SRB2_ASSET}_HASH")
set(SRB2_ASSET_${SRB2_ASSET}_HASH ${SRB2_ASSET_${SRB2_ASSET}_HASH} PARENT_SCOPE)
endforeach()
# Installation
-if(CLANG)
+if(${CMAKE_SYSTEM} MATCHES Darwin)
get_target_property(outname SRB2SDL2 OUTPUT_NAME)
- install(FILES ${SRB2_ASSET_ALL}
+ install(DIRECTORY "${SRB2_ASSET_DIRECTORY}/"
DESTINATION "${outname}.app/Contents/Resources"
)
+ install(FILES ${SRB2_ASSET_DOCS}
+ DESTINATION .
+ OPTIONAL
+ )
else()
- install(FILES ${SRB2_ASSET_ALL}
+ install(DIRECTORY "${SRB2_ASSET_DIRECTORY}/"
DESTINATION .
)
+ # Docs are assumed to be located in SRB2_ASSET_DIRECTORY, so don't install again
+ #install(FILES ${SRB2_ASSET_DOCS}
+ # DESTINATION .
+ # OPTIONAL
+ #)
endif()
diff --git a/assets/debian/README.Debian b/assets/debian-template/README.Debian
similarity index 59%
rename from assets/debian/README.Debian
rename to assets/debian-template/README.Debian
index 68c952a4e..f3fe90030 100644
--- a/assets/debian/README.Debian
+++ b/assets/debian-template/README.Debian
@@ -12,9 +12,39 @@ with apt-key add. Thanks!
-- Callum Dickinson 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 " to match
+the identity of the key you will use to sign the package.
+
+
+Building for Launchpad PPA
+
+Run this step first:
+
+ 1. source [repo-root]/debian_template.sh
+ * Initializes defaults for the package variables and fills in templates.
+
+Use these steps to prepare building a source package for Launchpad:
+
+ 1. cd [repo-root]/assets/
+ 2. debuild -T clean-all (optional; if you already have asset files, this clears them)
+
+Build the source package:
+
+ 1. debuild -T build (this downloads the asset files from srb2.org if necessary)
+ 2. debuild -S (builds the source package for Launchpad, including the asset files)
+
+
Signing for Launchpad PPA
-First, follow the above instructions to generate a GnuPG key with your identity. You will need
+First, follow Callum's instructions to generate a GnuPG key with your identity. You will need
to publish the fingerprint of that key to Ubuntu's key server.
https://help.ubuntu.com/community/GnuPrivacyGuardHowto#Uploading_the_key_to_Ubuntu_keyserver
@@ -26,22 +56,18 @@ upload signed source packages and publish them onto your PPA.
IF YOU UPLOAD A PACKAGE and Launchpad does NOT send you a confirmation or rejection email, that
means your key is not set up correctly with your Launchpad account.
+Finally, if your packages have not already been signed, follow these steps:
-Building for Launchpad PPA
+ 1. cd ..
+ * Packages are located in the parent folder of where debuild was called
+ 2. debsign "srb2-data_[version]_source.changes"
+ * You may need to specify -k [key-fingerprint]
-Use these steps to prepare building a source package for Launchpad:
- 1. Highly recommend copying the assets/ folder to outside your repo folder, or else the asset
- files may be included in the main source package, when you build that.
- 2. cd [wherever-your-assets-folder-is]/assets/
- 3. debuild -T clean (optional, if you already have asset files)
+Uploading for Launchpad PPA
-Building the source package is a two-step process:
-
- 1. debuild -T build (this downloads the asset files from srb2.org if necessary)
- 2. debuild -S (builds the source package for Launchpad, including the asset files)
-
-Then follow the instructions at to upload
+Follow the instructions at to upload
to your PPA and have Launchpad build your binary deb packages.
+
-- Marco Zafra Mon, 26 Nov 2018 21:13:00 -0500
diff --git a/assets/debian/README.source b/assets/debian-template/README.source
similarity index 100%
rename from assets/debian/README.source
rename to assets/debian-template/README.source
diff --git a/assets/debian-template/changelog b/assets/debian-template/changelog
new file mode 100644
index 000000000..64562e2a3
--- /dev/null
+++ b/assets/debian-template/changelog
@@ -0,0 +1,5 @@
+${PACKAGE_NAME}-data (${PACKAGE_VERSION}${PACKAGE_SUBVERSION}${PACKAGE_REVISION}) ${PACKAGE_DISTRO}; urgency=${PACKAGE_URGENCY}
+
+ * ${PROGRAM_NAME} v${PROGRAM_VERSION} asset data
+
+ -- ${PACKAGE_NAME_EMAIL} ${__PACKAGE_DATETIME}
diff --git a/assets/debian/compat b/assets/debian-template/compat
similarity index 100%
rename from assets/debian/compat
rename to assets/debian-template/compat
diff --git a/assets/debian/control b/assets/debian-template/control
similarity index 84%
rename from assets/debian/control
rename to assets/debian-template/control
index 22d9643ee..ae5c0ce67 100644
--- a/assets/debian/control
+++ b/assets/debian-template/control
@@ -1,15 +1,15 @@
# SRB2-data Debian package control file.
-Source: srb2-data
+Source: ${PACKAGE_NAME}-data
Section: games
Priority: extra
-Maintainer: Sonic Team Junior
+Maintainer: ${PACKAGE_GROUP_NAME_EMAIL}
Build-Depends: debhelper (>= 7.0.50~),
wget
Standards-Version: 3.8.4
-Homepage: http://www.srb2.org
+Homepage: ${PACKAGE_WEBSITE}
-Package: srb2-data
+Package: ${PACKAGE_NAME}-data
Architecture: all
Description: A cross-platform 3D Sonic fangame
Sonic Robo Blast 2 is a 3D open-source Sonic the Hedgehog
diff --git a/debian/copyright b/assets/debian-template/copyright
similarity index 57%
rename from debian/copyright
rename to assets/debian-template/copyright
index 97d606b0f..cc47c453b 100644
--- a/debian/copyright
+++ b/assets/debian-template/copyright
@@ -1,18 +1,18 @@
This work was packaged for Debian by:
- Marco Zafra Mon, 26 Nov 2018 14:31:00 -0500
+ ${PACKAGE_NAME_EMAIL} ${__PACKAGE_DATETIME}
It was downloaded from:
-
+ ${PACKAGE_WEBSITE}
Upstream Author(s):
- Sonic Team Junior
+ ${PACKAGE_GROUP_NAME_EMAIL}
Copyright:
- Copyright (C) 1998-2018 Sonic Team Junior
+ Copyright (C) 1998-2018 by Sonic Team Junior
License:
@@ -21,7 +21,7 @@ License:
The Debian packaging is:
Copyright (C) 2010 Callum Dickinson
- Copyright (C) 2010-2018 Sonic Team Junior
+ Copyright (C) 2010-2018 by Sonic Team Junior
and is licensed under the GPL version 2,
see "/usr/share/common-licenses/GPL-2".
diff --git a/assets/debian/rules b/assets/debian-template/rules
old mode 100755
new mode 100644
similarity index 70%
rename from assets/debian/rules
rename to assets/debian-template/rules
index a34a3393f..c2d19922d
--- a/assets/debian/rules
+++ b/assets/debian-template/rules
@@ -23,6 +23,16 @@
#
#############################################################################
+#############################################################################
+#
+# !!!!!!!!!! DEPLOYER NOTE !!!!!!!!!!
+#
+# Variables to be templated are curly-braced ${PACKAGE_INSTALL_PATH}
+# Variables used by the rules script are parenthese'd $(DATADIR)
+# See [repo-root]/debian_template.sh
+#
+#############################################################################
+
# Uncomment this to turn on verbose mode.
#export DH_VERBOSE=1
@@ -37,30 +47,32 @@ RM := rm -rf
DIR := $(shell pwd)
PACKAGE := $(shell cat $(DIR)/debian/control | grep 'Package:' | sed -e 's/Package: //g')
-DATAFILES := srb2.srb zones.dta player.dta rings.dta music.dta patch.dta README.txt LICENSE.txt LICENSE-3RD-PARTY.txt
+ARCHIVEPATH := ${ASSET_ARCHIVE_PATH}
+ARCHIVEOPTIONALPATH := ${ASSET_ARCHIVE_OPTIONAL_PATH}
+GETOPTIONALFILES := ${ASSET_FILES_OPTIONAL_GET}
-DATADIR := usr/games/SRB2
+DATADIR := $(shell echo "${PACKAGE_INSTALL_PATH}" | sed -e 's/^\///')
RESOURCEDIR := .
+STAGINGDIR := $(RESOURCEDIR)/installer
WGET := wget -P $(RESOURCEDIR) -c -nc
build:
$(MKDIR) $(DIR)/debian/tmp/$(DATADIR)
> $(DIR)/debian/source/include-binaries
- # This will need to be updated every time SRB2 official version is
# Copy data files to their install locations, and add data files to include-binaries
- for file in $(DATAFILES); do \
- if [ ! -f $(RESOURCEDIR)/$$file ]; then \
- $(WGET) http://alam.srb2.org/SRB2/2.1.21-Final/Resources/$$file; \
+ if [ ! -d $(STAGINGDIR) ]; then \
+ mkdir -p "$(STAGINGDIR)"; \
+ $(WGET) $(ARCHIVEPATH); \
+ 7z x "$(RESOURCEDIR)/$(shell basename $(ARCHIVEPATH))" -aos; \
+ if [ "$(GETOPTIONALFILES)" = "1" ]; then \
+ $(WGET) $(ARCHIVEOPTIONALPATH); \
+ 7z x "$(RESOURCEDIR)/$(shell basename $(ARCHIVEOPTIONALPATH))" -aos; \
fi; \
- if [ -f $(RESOURCEDIR)/$$file ]; then \
- $(INSTALL) $(RESOURCEDIR)/$$file $(DIR)/debian/tmp/$(DATADIR)/$$file; \
- echo $(RESOURCEDIR)/$$file >> $(DIR)/debian/source/include-binaries; \
- fi; \
- if [ ! -f $(DIR)/debian/tmp/$(DATADIR)/$$file ]; then \
- echo $(DIR)/debian/tmp/$(DATADIR)/$$file not found and could not be downloaded!; \
- return 1; \
- fi; \
- done
+ fi
+ # Install asset directory and add asset file to include-binaries
+ cp -vr "$(STAGINGDIR)/." "$(DIR)/debian/tmp/$(DATADIR)"
+ find "$(STAGINGDIR)" >> $(DIR)/debian/source/include-binaries
+
binary-indep:
# Generate install folder file
diff --git a/assets/debian/source/format b/assets/debian-template/source/format
similarity index 100%
rename from assets/debian/source/format
rename to assets/debian-template/source/format
diff --git a/assets/debian/source/options b/assets/debian-template/source/options
similarity index 100%
rename from assets/debian/source/options
rename to assets/debian-template/source/options
diff --git a/assets/debian/changelog b/assets/debian/changelog
deleted file mode 100644
index f3a92e1cd..000000000
--- a/assets/debian/changelog
+++ /dev/null
@@ -1,19 +0,0 @@
-srb2-data (2.1.21~7) trusty; urgency=high
-
- * Updated for SRB2 v2.1.21
-
- -- Marco Zafra 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 Sat, 6 Jan 2016 11:00:00 -0500
-
-
-srb2-data (2.0.6-2) maverick; urgency=high
-
- * Initial proper release..
-
- -- Callum Dickinson Sat, 29 Jan 2011 01:18:42 +1300
diff --git a/bin/DC/.gitignore b/bin/DC/.gitignore
deleted file mode 100644
index 42c6dc2c6..000000000
--- a/bin/DC/.gitignore
+++ /dev/null
@@ -1,2 +0,0 @@
-# DON'T REMOVE
-# This keeps the folder from disappearing
diff --git a/bin/Mingw/Release/.gitignore b/bin/Mingw/Release/.gitignore
index 834f313e3..3458ff764 100644
--- a/bin/Mingw/Release/.gitignore
+++ b/bin/Mingw/Release/.gitignore
@@ -1,3 +1,4 @@
*.exe
*.mo
r_opengl.dll
+*.bat
diff --git a/bin/PS3/Debug/.gitignore b/bin/PS3/Debug/.gitignore
deleted file mode 100644
index c4dcd19e5..000000000
--- a/bin/PS3/Debug/.gitignore
+++ /dev/null
@@ -1,5 +0,0 @@
-/*.elf
-/*.self
-/*.pkg
-/*.BIN
-/pkg
diff --git a/bin/PS3/Release/.gitignore b/bin/PS3/Release/.gitignore
deleted file mode 100644
index c4dcd19e5..000000000
--- a/bin/PS3/Release/.gitignore
+++ /dev/null
@@ -1,5 +0,0 @@
-/*.elf
-/*.self
-/*.pkg
-/*.BIN
-/pkg
diff --git a/bin/PSP/Release/.gitignore b/bin/PSP/Release/.gitignore
deleted file mode 100644
index 98d08e695..000000000
--- a/bin/PSP/Release/.gitignore
+++ /dev/null
@@ -1,4 +0,0 @@
-/EBOOT.PBP
-/PARAM.SFO
-/SRB2PSP.PBP
-/SRB2PSP.elf
diff --git a/bin/Wii/Debug/.gitignore b/bin/Wii/Debug/.gitignore
deleted file mode 100644
index 200eea51f..000000000
--- a/bin/Wii/Debug/.gitignore
+++ /dev/null
@@ -1,3 +0,0 @@
-/*.elf
-/*.dol
-/apps
diff --git a/bin/Wii/Release/.gitignore b/bin/Wii/Release/.gitignore
deleted file mode 100644
index 200eea51f..000000000
--- a/bin/Wii/Release/.gitignore
+++ /dev/null
@@ -1,3 +0,0 @@
-/*.elf
-/*.dol
-/apps
diff --git a/bin/WinCE/ARMV4Dbg/.gitignore b/bin/WinCE/ARMV4Dbg/.gitignore
deleted file mode 100644
index 42c6dc2c6..000000000
--- a/bin/WinCE/ARMV4Dbg/.gitignore
+++ /dev/null
@@ -1,2 +0,0 @@
-# DON'T REMOVE
-# This keeps the folder from disappearing
diff --git a/bin/WinCE/ARMV4IDbg/.gitignore b/bin/WinCE/ARMV4IDbg/.gitignore
deleted file mode 100644
index 42c6dc2c6..000000000
--- a/bin/WinCE/ARMV4IDbg/.gitignore
+++ /dev/null
@@ -1,2 +0,0 @@
-# DON'T REMOVE
-# This keeps the folder from disappearing
diff --git a/bin/WinCE/ARMV4IRel/.gitignore b/bin/WinCE/ARMV4IRel/.gitignore
deleted file mode 100644
index 42c6dc2c6..000000000
--- a/bin/WinCE/ARMV4IRel/.gitignore
+++ /dev/null
@@ -1,2 +0,0 @@
-# DON'T REMOVE
-# This keeps the folder from disappearing
diff --git a/bin/WinCE/ARMV4Rel/.gitignore b/bin/WinCE/ARMV4Rel/.gitignore
deleted file mode 100644
index 42c6dc2c6..000000000
--- a/bin/WinCE/ARMV4Rel/.gitignore
+++ /dev/null
@@ -1,2 +0,0 @@
-# DON'T REMOVE
-# This keeps the folder from disappearing
diff --git a/bin/WinCE/ARMV4TDbg/.gitignore b/bin/WinCE/ARMV4TDbg/.gitignore
deleted file mode 100644
index 42c6dc2c6..000000000
--- a/bin/WinCE/ARMV4TDbg/.gitignore
+++ /dev/null
@@ -1,2 +0,0 @@
-# DON'T REMOVE
-# This keeps the folder from disappearing
diff --git a/bin/WinCE/ARMV4TRel/.gitignore b/bin/WinCE/ARMV4TRel/.gitignore
deleted file mode 100644
index 42c6dc2c6..000000000
--- a/bin/WinCE/ARMV4TRel/.gitignore
+++ /dev/null
@@ -1,2 +0,0 @@
-# DON'T REMOVE
-# This keeps the folder from disappearing
diff --git a/bin/WinCE/MIPS16Dbg/.gitignore b/bin/WinCE/MIPS16Dbg/.gitignore
deleted file mode 100644
index 42c6dc2c6..000000000
--- a/bin/WinCE/MIPS16Dbg/.gitignore
+++ /dev/null
@@ -1,2 +0,0 @@
-# DON'T REMOVE
-# This keeps the folder from disappearing
diff --git a/bin/WinCE/MIPS16Rel/.gitignore b/bin/WinCE/MIPS16Rel/.gitignore
deleted file mode 100644
index 42c6dc2c6..000000000
--- a/bin/WinCE/MIPS16Rel/.gitignore
+++ /dev/null
@@ -1,2 +0,0 @@
-# DON'T REMOVE
-# This keeps the folder from disappearing
diff --git a/bin/WinCE/MIPSIIDbg/.gitignore b/bin/WinCE/MIPSIIDbg/.gitignore
deleted file mode 100644
index 42c6dc2c6..000000000
--- a/bin/WinCE/MIPSIIDbg/.gitignore
+++ /dev/null
@@ -1,2 +0,0 @@
-# DON'T REMOVE
-# This keeps the folder from disappearing
diff --git a/bin/WinCE/MIPSIIRel/.gitignore b/bin/WinCE/MIPSIIRel/.gitignore
deleted file mode 100644
index 42c6dc2c6..000000000
--- a/bin/WinCE/MIPSIIRel/.gitignore
+++ /dev/null
@@ -1,2 +0,0 @@
-# DON'T REMOVE
-# This keeps the folder from disappearing
diff --git a/bin/WinCE/MIPSII_FPDbg/.gitignore b/bin/WinCE/MIPSII_FPDbg/.gitignore
deleted file mode 100644
index 42c6dc2c6..000000000
--- a/bin/WinCE/MIPSII_FPDbg/.gitignore
+++ /dev/null
@@ -1,2 +0,0 @@
-# DON'T REMOVE
-# This keeps the folder from disappearing
diff --git a/bin/WinCE/MIPSII_FPRel/.gitignore b/bin/WinCE/MIPSII_FPRel/.gitignore
deleted file mode 100644
index 42c6dc2c6..000000000
--- a/bin/WinCE/MIPSII_FPRel/.gitignore
+++ /dev/null
@@ -1,2 +0,0 @@
-# DON'T REMOVE
-# This keeps the folder from disappearing
diff --git a/bin/WinCE/MIPSIVDbg/.gitignore b/bin/WinCE/MIPSIVDbg/.gitignore
deleted file mode 100644
index 42c6dc2c6..000000000
--- a/bin/WinCE/MIPSIVDbg/.gitignore
+++ /dev/null
@@ -1,2 +0,0 @@
-# DON'T REMOVE
-# This keeps the folder from disappearing
diff --git a/bin/WinCE/MIPSIVRel/.gitignore b/bin/WinCE/MIPSIVRel/.gitignore
deleted file mode 100644
index 42c6dc2c6..000000000
--- a/bin/WinCE/MIPSIVRel/.gitignore
+++ /dev/null
@@ -1,2 +0,0 @@
-# DON'T REMOVE
-# This keeps the folder from disappearing
diff --git a/bin/WinCE/MIPSIV_FPDbg/.gitignore b/bin/WinCE/MIPSIV_FPDbg/.gitignore
deleted file mode 100644
index 42c6dc2c6..000000000
--- a/bin/WinCE/MIPSIV_FPDbg/.gitignore
+++ /dev/null
@@ -1,2 +0,0 @@
-# DON'T REMOVE
-# This keeps the folder from disappearing
diff --git a/bin/WinCE/MIPSIV_FPRel/.gitignore b/bin/WinCE/MIPSIV_FPRel/.gitignore
deleted file mode 100644
index 42c6dc2c6..000000000
--- a/bin/WinCE/MIPSIV_FPRel/.gitignore
+++ /dev/null
@@ -1,2 +0,0 @@
-# DON'T REMOVE
-# This keeps the folder from disappearing
diff --git a/bin/WinCE/Release/.gitignore b/bin/WinCE/Release/.gitignore
deleted file mode 100644
index 42c6dc2c6..000000000
--- a/bin/WinCE/Release/.gitignore
+++ /dev/null
@@ -1,2 +0,0 @@
-# DON'T REMOVE
-# This keeps the folder from disappearing
diff --git a/bin/WinCE/SH3Dbg/.gitignore b/bin/WinCE/SH3Dbg/.gitignore
deleted file mode 100644
index 42c6dc2c6..000000000
--- a/bin/WinCE/SH3Dbg/.gitignore
+++ /dev/null
@@ -1,2 +0,0 @@
-# DON'T REMOVE
-# This keeps the folder from disappearing
diff --git a/bin/WinCE/SH3Rel/.gitignore b/bin/WinCE/SH3Rel/.gitignore
deleted file mode 100644
index 42c6dc2c6..000000000
--- a/bin/WinCE/SH3Rel/.gitignore
+++ /dev/null
@@ -1,2 +0,0 @@
-# DON'T REMOVE
-# This keeps the folder from disappearing
diff --git a/bin/WinCE/SH4Dbg/.gitignore b/bin/WinCE/SH4Dbg/.gitignore
deleted file mode 100644
index 42c6dc2c6..000000000
--- a/bin/WinCE/SH4Dbg/.gitignore
+++ /dev/null
@@ -1,2 +0,0 @@
-# DON'T REMOVE
-# This keeps the folder from disappearing
diff --git a/bin/WinCE/SH4Rel/.gitignore b/bin/WinCE/SH4Rel/.gitignore
deleted file mode 100644
index 42c6dc2c6..000000000
--- a/bin/WinCE/SH4Rel/.gitignore
+++ /dev/null
@@ -1,2 +0,0 @@
-# DON'T REMOVE
-# This keeps the folder from disappearing
diff --git a/bin/WinCE/X86Dbg/.gitignore b/bin/WinCE/X86Dbg/.gitignore
deleted file mode 100644
index 42c6dc2c6..000000000
--- a/bin/WinCE/X86Dbg/.gitignore
+++ /dev/null
@@ -1,2 +0,0 @@
-# DON'T REMOVE
-# This keeps the folder from disappearing
diff --git a/bin/WinCE/X86Rel/.gitignore b/bin/WinCE/X86Rel/.gitignore
deleted file mode 100644
index 42c6dc2c6..000000000
--- a/bin/WinCE/X86Rel/.gitignore
+++ /dev/null
@@ -1,2 +0,0 @@
-# DON'T REMOVE
-# This keeps the folder from disappearing
diff --git a/bin/WinCE/emulatorDbg/.gitignore b/bin/WinCE/emulatorDbg/.gitignore
deleted file mode 100644
index 42c6dc2c6..000000000
--- a/bin/WinCE/emulatorDbg/.gitignore
+++ /dev/null
@@ -1,2 +0,0 @@
-# DON'T REMOVE
-# This keeps the folder from disappearing
diff --git a/bin/WinCE/emulatorRel/.gitignore b/bin/WinCE/emulatorRel/.gitignore
deleted file mode 100644
index 42c6dc2c6..000000000
--- a/bin/WinCE/emulatorRel/.gitignore
+++ /dev/null
@@ -1,2 +0,0 @@
-# DON'T REMOVE
-# This keeps the folder from disappearing
diff --git a/bin/nds/Debug/.gitignore b/bin/nds/Debug/.gitignore
deleted file mode 100644
index 9bfc4a51d..000000000
--- a/bin/nds/Debug/.gitignore
+++ /dev/null
@@ -1,3 +0,0 @@
-*.arm9
-*.elf*
-*.nds
diff --git a/bin/nds/Release/.gitignore b/bin/nds/Release/.gitignore
deleted file mode 100644
index 9bfc4a51d..000000000
--- a/bin/nds/Release/.gitignore
+++ /dev/null
@@ -1,3 +0,0 @@
-*.arm9
-*.elf*
-*.nds
diff --git a/cmake/Modules/FindOPENMPT.cmake b/cmake/Modules/FindOPENMPT.cmake
new file mode 100644
index 000000000..2d334b6f0
--- /dev/null
+++ b/cmake/Modules/FindOPENMPT.cmake
@@ -0,0 +1,23 @@
+include(LibFindMacros)
+
+libfind_pkg_check_modules(OPENMPT_PKGCONF OPENMPT)
+
+find_path(OPENMPT_INCLUDE_DIR
+ NAMES libopenmpt.h
+ PATHS
+ ${OPENMPT_PKGCONF_INCLUDE_DIRS}
+ "/usr/include/libopenmpt"
+ "/usr/local/include/libopenmpt"
+)
+
+find_library(OPENMPT_LIBRARY
+ NAMES openmpt
+ PATHS
+ ${OPENMPT_PKGCONF_LIBRARY_DIRS}
+ "/usr/lib"
+ "/usr/local/lib"
+)
+
+set(OPENMPT_PROCESS_INCLUDES OPENMPT_INCLUDE_DIR)
+set(OPENMPT_PROCESS_LIBS OPENMPT_LIBRARY)
+libfind_process(OPENMPT)
\ No newline at end of file
diff --git a/debian/README.Debian b/debian-template/README.Debian
similarity index 62%
rename from debian/README.Debian
rename to debian-template/README.Debian
index 4b724816e..3aa52787e 100644
--- a/debian/README.Debian
+++ b/debian-template/README.Debian
@@ -10,10 +10,38 @@ and give them to your users to install with apt-key add. Thanks!
-- Callum Dickinson 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 " to match
+the identity of the key you will use to sign the package.
+
+
+Building for Launchpad PPA
+
+Use these steps to prepare building a source package for Launchpad:
+
+ 1. cd [repo-root]
+ 2. git reset --hard; git clean -fd; git clean -fx;
+ * Resets your repo folder to a committed state and removes untracked files
+ * If you built srb2-data in the assets/ folder, MAKE SURE THAT FOLDER DOES NOT HAVE ASSETS,
+ OR THEY MAY BE INCLUDED IN THE MAIN SOURCE PACKAGE!
+
+Build the source package:
+
+ 1. source [repo-root]/debian_template.sh
+ * Initializes defaults for the package variables and fills in templates.
+ 2. debuild -S (builds the source package for Launchpad)
+
Signing for Launchpad PPA
-First, follow the above instructions to generate a GnuPG key with your identity. You will need
+First, follow Callum's instructions to generate a GnuPG key with your identity. You will need
to publish the fingerprint of that key to Ubuntu's key server.
https://help.ubuntu.com/community/GnuPrivacyGuardHowto#Uploading_the_key_to_Ubuntu_keyserver
@@ -25,22 +53,18 @@ upload signed source packages and publish them onto your PPA.
IF YOU UPLOAD A PACKAGE and Launchpad does NOT send you a confirmation or rejection email, that
means your key is not set up correctly with your Launchpad account.
+Finally, if your packages have not already been signed, follow these steps:
-Building for Launchpad PPA
+ 1. cd ..
+ * Packages are located in the parent folder of where debuild was called
+ 2. debsign "srb2_[version]_source.changes"
+ * You may need to specify -k [key-fingerprint]
-Use these steps to prepare building a source package for Launchpad:
- 1. cd [srb2repo]
- 2. git reset --hard; git clean -fd; git clean -fx;
- * Resets your repo folder to a committed state and removes untracked files
- * If you built srb2-data in the assets/ folder, MAKE SURE THAT FOLDER DOES NOT HAVE ASSETS,
- OR THEY MAY BE INCLUDED IN THE MAIN SOURCE PACKAGE!
+Uploading for Launchpad PPA
-Building the source package takes just one step:
-
- 1. debuild -S (builds the source package for Launchpad)
-
-Then follow the instructions at to upload
+Follow the instructions at to upload
to your PPA and have Launchpad build your binary deb packages.
+
-- Marco Zafra Mon, 26 Nov 2018 21:13:00 -0500
diff --git a/debian/README.source b/debian-template/README.source
similarity index 100%
rename from debian/README.source
rename to debian-template/README.source
diff --git a/debian-template/changelog b/debian-template/changelog
new file mode 100644
index 000000000..fb08908cd
--- /dev/null
+++ b/debian-template/changelog
@@ -0,0 +1,5 @@
+${PACKAGE_NAME} (${PACKAGE_VERSION}${PACKAGE_SUBVERSION}${PACKAGE_REVISION}) ${PACKAGE_DISTRO}; urgency=${PACKAGE_URGENCY}
+
+ * ${PROGRAM_NAME} v${PROGRAM_VERSION} program build
+
+ -- ${PACKAGE_NAME_EMAIL} ${__PACKAGE_DATETIME}
diff --git a/debian/compat b/debian-template/compat
similarity index 100%
rename from debian/compat
rename to debian-template/compat
diff --git a/debian/control b/debian-template/control
similarity index 65%
rename from debian/control
rename to debian-template/control
index ce3b33fbd..e1348d704 100644
--- a/debian/control
+++ b/debian-template/control
@@ -1,24 +1,30 @@
# SRB2 Debian package control file.
-Source: srb2
+Source: ${PACKAGE_NAME}
Section: games
Priority: extra
-Maintainer: Sonic Team Junior
+Maintainer: ${PACKAGE_GROUP_NAME_EMAIL}
Build-Depends: debhelper (>= 7.0.50~),
libsdl2-dev,
libsdl2-mixer-dev,
- libpng12-dev (>= 1.2.7) | libpng-dev,
+ libpng-dev | libpng16-dev | libpng12-dev (>= 1.2.7),
zlib1g-dev,
libgme-dev,
libglu1-dev | libglu-dev,
libosmesa6-dev | libgl-dev,
nasm [i386]
Standards-Version: 3.8.4
-Homepage: http://www.srb2.org
+Homepage: ${PACKAGE_WEBSITE}
-Package: srb2
+Package: ${PACKAGE_NAME}
Architecture: any
-Depends: ${shlibs:Depends}, ${misc:Depends}, srb2-data (>= 2.1.15), srb2-data (<= 2.1.21)
+Depends: ${SHLIBS_DEPENDS}, ${MISC_DEPENDS},
+ ${PACKAGE_NAME}-data (>> ${PACKAGE_ASSET_MINVERSION}), ${PACKAGE_NAME}-data (<< ${PACKAGE_ASSET_MAXVERSION}),
+ libsdl2-2.0-0,
+ libsdl2-mixer-2.0-0,
+ zlib1g,
+ libgme0,
+ libpng | libpng16-16 | libpng12-0
Description: A cross-platform 3D Sonic fangame
Sonic Robo Blast 2 is a 3D open-source Sonic the Hedgehog
fangame built using a modified version of the Doom Legacy
@@ -28,10 +34,10 @@ Description: A cross-platform 3D Sonic fangame
and quite a lot of the fun that the original Sonic games provided.
-Package: srb2-dbg
+Package: ${PACKAGE_NAME}-dbg
Architecture: any
-# FIXME: should be Depends: ${shlibs:Depends}, ${misc:Depends}, srb2-data (= 2.1.14), srb2 but dh_shlibdeps is being an asshat
-Depends: libc6, ${misc:Depends}, srb2-data (>= 2.1.15), srb2-data (<= 2.1.21), srb2
+# FIXME: should be Depends: ${SHLIBS_DEPENDS}, ${MISC_DEPENDS}, srb2-data (= 2.1.14), srb2 but dh_shlibdeps is being an asshat
+Depends: libc6, ${MISC_DEPENDS}, ${PACKAGE_NAME}-data (>> ${PACKAGE_ASSET_MINVERSION}), ${PACKAGE_NAME}-data (<< ${PACKAGE_ASSET_MAXVERSION}), ${PACKAGE_NAME}
Description: A cross-platform 3D Sonic fangame
Sonic Robo Blast 2 is a 3D open-source Sonic the Hedgehog
fangame built using a modified version of the Doom Legacy
diff --git a/assets/debian/copyright b/debian-template/copyright
similarity index 57%
rename from assets/debian/copyright
rename to debian-template/copyright
index 97d606b0f..cc47c453b 100644
--- a/assets/debian/copyright
+++ b/debian-template/copyright
@@ -1,18 +1,18 @@
This work was packaged for Debian by:
- Marco Zafra Mon, 26 Nov 2018 14:31:00 -0500
+ ${PACKAGE_NAME_EMAIL} ${__PACKAGE_DATETIME}
It was downloaded from:
-
+ ${PACKAGE_WEBSITE}
Upstream Author(s):
- Sonic Team Junior
+ ${PACKAGE_GROUP_NAME_EMAIL}
Copyright:
- Copyright (C) 1998-2018 Sonic Team Junior
+ Copyright (C) 1998-2018 by Sonic Team Junior
License:
@@ -21,7 +21,7 @@ License:
The Debian packaging is:
Copyright (C) 2010 Callum Dickinson
- Copyright (C) 2010-2018 Sonic Team Junior
+ Copyright (C) 2010-2018 by Sonic Team Junior
and is licensed under the GPL version 2,
see "/usr/share/common-licenses/GPL-2".
diff --git a/debian/docs b/debian-template/docs
similarity index 100%
rename from debian/docs
rename to debian-template/docs
diff --git a/debian/rules b/debian-template/rules
old mode 100755
new mode 100644
similarity index 86%
rename from debian/rules
rename to debian-template/rules
index 02e3dc78e..0a77624cb
--- a/debian/rules
+++ b/debian-template/rules
@@ -23,6 +23,16 @@
#
#############################################################################
+#############################################################################
+#
+# !!!!!!!!!! DEPLOYER NOTE !!!!!!!!!!
+#
+# Variables to be templated are curly-braced ${PACKAGE_INSTALL_PATH}
+# Variables used by the rules script are parenthese'd $(PKGDIR)
+# See [repo-root]/debian_template.sh
+#
+#############################################################################
+
# Uncomment this to turn on verbose mode.
#export DH_VERBOSE=1
@@ -50,15 +60,16 @@ DIR := $(shell pwd)
# FIXME: hate hate hate head/tail hack :(
CONTROLF = $(DIR)/debian/control
-PACKAGE = srb2
-DBGPKG = $(PACKAGE)-dbg
-TITLE = Sonic Robo Blast 2
+PACKAGE = ${PACKAGE_NAME}
+DBGPKG = ${PACKAGE}-dbg
+TITLE = ${PROGRAM_NAME}
SECTION = Games/Action
-EXENAME = srb2
+EXENAME = ${PROGRAM_FILENAME}
DBGNAME = debug/$(EXENAME)
-PKGDIR = usr/games/SRB2
+PKGDIR = $(shell echo "${PACKAGE_INSTALL_PATH}" | sed -e 's/^\///')
DBGDIR = usr/lib/debug/$(PKGDIR)
+LINKDIR = $(shell echo "${PACKAGE_LINK_PATH}" | sed -e 's/^\///')
PIXMAPS_DIR = usr/share/pixmaps
DESKTOP_DIR = usr/share/applications
PREFIX = $(shell test "$(CROSS_COMPILE_BUILD)" != "$(CROSS_COMPILE_HOST)" && echo "PREFIX=$(CROSS_COMPILE_HOST)")
@@ -101,8 +112,8 @@ binary-arch:
$(INSTALL) $(BINDIR)/$(EXENAME) $(DIR)/debian/tmp/$(PKGDIR)/$(PACKAGE)
$(INSTALL) $(BINDIR)/$(DBGNAME) $(DIR)/debian/tmp/$(DBGDIR)/$(PACKAGE)
# Install desktop file and banner image
- $(INSTALL) $(DIR)/srb2.png $(DIR)/debian/tmp/usr/share/pixmaps
- $(INSTALL) $(DIR)/debian/srb2.desktop $(DIR)/debian/tmp/usr/share/applications
+ $(INSTALL) $(DIR)/srb2.png $(DIR)/debian/tmp/usr/share/pixmaps/${PROGRAM_FILENAME}.png
+ $(INSTALL) $(DIR)/debian/srb2.desktop $(DIR)/debian/tmp/usr/share/applications/${PROGRAM_FILENAME}.desktop
# add compiled binaries to include-binaries
echo $(BINDIR)/$(EXENAME) >> $(DIR)/debian/source/include-binaries
echo $(BINDIR)/$(EXENAME) >> $(DIR)/debian/source/include-binaries
@@ -133,7 +144,7 @@ binary-arch:
# dh_installcron
# dh_installinfo
# dh_installman
- # dh_link
+ dh_link $(PKGDIR)/$(EXENAME) $(LINKDIR)/$(EXENAME)
dh_compress
dh_fixperms
# dh_perl
diff --git a/debian/source/format b/debian-template/source/format
similarity index 100%
rename from debian/source/format
rename to debian-template/source/format
diff --git a/debian/source/options b/debian-template/source/options
similarity index 81%
rename from debian/source/options
rename to debian-template/source/options
index 841c65a6f..1ef771ddf 100644
--- a/debian/source/options
+++ b/debian-template/source/options
@@ -2,7 +2,7 @@ tar-ignore = "assets/*.srb"
tar-ignore = "assets/*.pk3"
tar-ignore = "assets/*.dta"
tar-ignore = "assets/*.wad"
-tar-ignore = "assets/debian/srb2-data/*"
+tar-ignore = "assets/debian/${PACKAGE_NAME}-data/*"
tar-ignore = "assets/debian/tmp/*"
tar-ignore = "*.obj"
tar-ignore = "*.dep"
diff --git a/debian-template/srb2.desktop b/debian-template/srb2.desktop
new file mode 100644
index 000000000..07c7906e0
--- /dev/null
+++ b/debian-template/srb2.desktop
@@ -0,0 +1,10 @@
+[Desktop Entry]
+Name=${PROGRAM_NAME}
+Comment=${PROGRAM_DESCRIPTION}
+Encoding=UTF-8
+Exec=${PACKAGE_INSTALL_PATH}/${PROGRAM_FILENAME}
+Icon=/usr/share/pixmaps/${PROGRAM_FILENAME}.png
+Terminal=false
+Type=Application
+StartupNotify=false
+Categories=Application;Game;
diff --git a/debian/changelog b/debian/changelog
deleted file mode 100644
index 855c1c1b3..000000000
--- a/debian/changelog
+++ /dev/null
@@ -1,12 +0,0 @@
-srb2 (2.1.21~9) trusty; urgency=high
-
- * SRB2 v2.1.21 release
-
- -- Marco Zafra Mon, 27 Nov 2018 16:45:00 -0500
-
-
-srb2 (2.0.6-5) maverick; urgency=high
-
- * Initial proper release..
-
- -- Callum Dickinson Sat, 29 Jan 2011 01:18:42 +1300
diff --git a/debian/srb2.desktop b/debian/srb2.desktop
deleted file mode 100644
index 3a1cac9f6..000000000
--- a/debian/srb2.desktop
+++ /dev/null
@@ -1,10 +0,0 @@
-[Desktop Entry]
-Name=Sonic Robo Blast 2
-Comment=A free 3D Sonic the Hedgehog fangame closely inspired by the original Sonic games on the Sega Genesis.
-Encoding=UTF-8
-Exec=/usr/games/SRB2/srb2
-Icon=/usr/share/pixmaps/srb2.png
-Terminal=false
-Type=Application
-StartupNotify=false
-Categories=Application;Game;
diff --git a/debian_template.sh b/debian_template.sh
new file mode 100644
index 000000000..c1af3c19f
--- /dev/null
+++ b/debian_template.sh
@@ -0,0 +1,166 @@
+#!/bin/bash
+
+# Deployer for Travis-CI
+# Debian package templating
+#
+# Call this script BEFORE running debuild!
+# source ./debian_template.sh [clean] [main/asset]
+#
+# Before running this script,
+# you should also set PACKAGE_NAME_EMAIL="John Doe " to match
+# the identity of the key you will use to sign the package.
+#
+
+# Get script's actual path
+DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )"
+
+# Recursive function for directory crawling
+# $1 = Directory root to crawl
+# $2 = Code to eval on file
+# $3 = Code to eval on directory
+# Exposes $dirtails, $dirlevel, and $dirtailname
+dirlevel=0 # initialize
+dirtails=()
+
+# Utility function to make dira/dirb/dirc string
+makedirtailname () {
+ dirtailname=""
+ for tail in $dirtails; do
+ if [[ "$dirtailname" == "" ]]; then
+ dirtailname="/$tail";
+ else
+ dirtailname="$dirtailname/$tail";
+ fi;
+ done;
+}
+
+evaldirectory () {
+ if [ -d "$1" ]; then
+ # Set contextual variables
+ # dirtails is an array of directory basenames after the crawl root
+ if (( $dirlevel > 0 )); then
+ dirtails+=( "$(basename $1)" );
+ else
+ dirtails=();
+ fi;
+ dirlevel=$((dirlevel+1));
+
+ # Generate directory path after the crawl root
+ makedirtailname;
+
+ # Eval our directory with the latest contextual info
+ # Don't eval on root
+ if (( $dirlevel > 1 )) && [[ "$3" != "" ]]; then
+ eval "$3";
+ fi;
+
+ # Iterate entries
+ for name in $1/*; do
+ if [ -d "$name" ]; then
+ # Name is a directory, but don't eval yet
+ # Recurse so our vars are updated
+ evaldirectory "$name" "$2" "$3";
+
+ # Decrement our directory level and remove a dirtail
+ unset 'dirtails[ ${#dirtails[@]}-1 ]';
+ dirlevel=$((dirlevel-1));
+ makedirtailname;
+ else
+ # Name is a file
+ if [ -f "$name" ] && [[ "$2" != "" ]]; then
+ eval "$2";
+ fi;
+ fi;
+ done;
+
+ # Reset our variables; we're done iterating
+ if (( $dirlevel == 1 )); then
+ dirlevel=0;
+ fi;
+ fi;
+}
+
+#
+# Initialize package parameter defaults
+#
+if [[ "$__DEBIAN_PARAMETERS_INITIALIZED" != "1" ]]; then
+ . ${DIR}/deployer/travis/deployer_defaults.sh;
+fi;
+
+# Clean up after ourselves; we only expect to run this script once
+# during buildboting
+__DEBIAN_PARAMETERS_INITIALIZED=0
+
+# for envsubst
+export __PACKAGE_DATETIME="$(date '+%a, %d %b %Y %H:%M:%S %z')"
+export __PACKAGE_DATETIME_DIGIT="$(date -u '+%Y%m%d%H%M%S')"
+
+if [[ "$PACKAGE_REVISION" == "" ]]; then
+ PACKAGE_REVISION="-$__PACKAGE_DATETIME_DIGIT";
+ __PACKAGE_REVISION_BY_DATE=1;
+ export PACKAGE_REVISION=${PACKAGE_REVISION}; # for envsubst
+fi;
+
+#
+# Clean the old debian/ directories
+#
+if [[ "$1" == "clean" ]]; then
+ toclean=$2;
+else
+ toclean=$1;
+fi;
+
+if [[ "$toclean" == "" ]] || [[ "$toclean" == "main" ]]; then
+ echo "Cleaning main package scripts";
+ if [[ ! -f ${DIR}/debian ]]; then
+ rm -rf ${DIR}/debian;
+ fi;
+fi;
+if [[ "$toclean" == "" ]] || [[ "$toclean" == "asset" ]]; then
+ echo "Cleaning asset package scripts";
+ if [[ ! -f ${DIR}/assets/debian ]]; then
+ rm -rf ${DIR}/assets/debian;
+ fi;
+fi;
+
+#
+# Make new templates
+#
+if [[ "$1" != "clean" ]]; then
+ totemplate=$1;
+
+ # HACK: ${shlibs:Depends} in the templates make the templating fail
+ # So just define replacemment variables
+ export SHLIBS_DEPENDS=${SHLIBS_DEPENDS};
+ export MISC_DEPENDS=${MISC_DEPENDS};
+ export DEBFILEVAR='$$file'; # used in assets/debian/rules
+
+ # Package parameters are exported for envsubst in deployer_defaults.sh
+
+ if [[ "$totemplate" == "" ]] || [[ "$totemplate" == "main" ]]; then
+ echo "Generating main package scripts";
+ fromroot=${DIR}/debian-template;
+ toroot=${DIR}/debian;
+ mkdir ${toroot};
+
+ evaldirectory ${fromroot} \
+ "cat \$name | envsubst > ${toroot}\${dirtailname}/\$( basename \$name )" \
+ "mkdir \"${toroot}\${dirtailname}\"";
+ fi;
+
+ if [[ "$totemplate" == "" ]] || [[ "$totemplate" == "asset" ]]; then
+ echo "Generating asset package scripts";
+ fromroot=${DIR}/assets/debian-template;
+ toroot=${DIR}/assets/debian;
+ mkdir ${toroot};
+
+ # Root dir to crawl; file eval; directory eval
+ evaldirectory ${fromroot} \
+ "cat \$name | envsubst > ${toroot}\${dirtailname}/\$( basename \$name )" \
+ "mkdir \"${toroot}\${dirtailname}\"";
+ fi;
+fi;
+
+if [[ "$__DPL_ACTIVE" != "1" ]] && [[ "$__PACKAGE_REVISION_BY_DATE" == "1" ]]; then
+ unset PACKAGE_REVISION; # so we can reset the date on subsequent runs
+fi;
diff --git a/deployer/appveyor/deployer.bat b/deployer/appveyor/deployer.bat
new file mode 100644
index 000000000..fae388590
--- /dev/null
+++ b/deployer/appveyor/deployer.bat
@@ -0,0 +1,195 @@
+@setlocal enableextensions enabledelayedexpansion
+
+::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+: Appveyor Deployer
+: See appveyor.yml for default variables
+::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+
+::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+: Evaluate whether we should be deploying
+::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+
+if not [%DPL_ENABLED%] == [1] (
+ echo Deployer is not enabled...
+ exit /b
+)
+
+: Don't do DD installs because fmodex DLL handling is not implemented.
+if [%CONFIGURATION%] == [DD] (
+ echo Deployer does not support DD builds...
+ exit /b
+)
+
+if [%CONFIGURATION%] == [DD64] (
+ echo Deployer does not support DD builds...
+ exit /b
+)
+
+: Substring match from https://stackoverflow.com/questions/7005951/batch-file-find-if-substring-is-in-string-not-in-a-file
+: The below line says "if deployer is NOT in string"
+: Note that APPVEYOR_REPO_BRANCH for pull request builds is the BASE branch that PR is merging INTO
+if x%APPVEYOR_REPO_BRANCH:deployer=%==x%APPVEYOR_REPO_BRANCH% (
+ if not [%APPVEYOR_REPO_TAG%] == [true] (
+ echo Deployer is enabled but we are not in a release tag or a 'deployer' branch...
+ exit /b
+ ) else (
+ if not [%DPL_TAG_ENABLED%] == [1] (
+ echo Deployer is not enabled for release tags...
+ exit /b
+ )
+ )
+)
+
+: Release tags always get optional assets (music.dta)
+if [%APPVEYOR_REPO_TAG%] == [true] (
+ set "ASSET_FILES_OPTIONAL_GET=1"
+)
+
+::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+: Get asset archives
+::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+
+if exist "C:\Users\appveyor\srb2_cache\archives\" (
+ if [%ASSET_CLEAN%] == [1] (
+ echo Cleaning asset archives...
+ rmdir /s /q "C:\Users\appveyor\srb2_cache\archives"
+ )
+)
+
+if not exist "C:\Users\appveyor\srb2_cache\archives\" mkdir "C:\Users\appveyor\srb2_cache\archives"
+
+goto EXTRACT_ARCHIVES
+
+::::::::::::::::::::::::::::::::
+: ARCHIVE_NAME_PARTS
+: Call this like a function. %archivepath% is the path to extract parts from.
+::::::::::::::::::::::::::::::::
+
+for %%a in (%archivepath%) do (
+ set "file=%%~fa"
+ set "filepath=%%~dpa"
+ set "filename=%%~nxa"
+)
+
+set "localarchivepath=C:\Users\appveyor\srb2_cache\archives\%filename%"
+
+goto EOF
+
+::::::::::::::::::::::::::::::::
+: EXTRACT_ARCHIVES
+::::::::::::::::::::::::::::::::
+
+set "archivepath=%ASSET_ARCHIVE_PATH%"
+call :ARCHIVE_NAME_PARTS
+set "ASSET_ARCHIVE_PATH_LOCAL=%localarchivepath%"
+if not exist "%localarchivepath%" appveyor DownloadFile "%ASSET_ARCHIVE_PATH%" -FileName "%localarchivepath%"
+
+set "archivepath=%ASSET_ARCHIVE_PATCH_PATH%"
+call :ARCHIVE_NAME_PARTS
+set "ASSET_ARCHIVE_PATCH_PATH_LOCAL=%localarchivepath%"
+if not exist "%localarchivepath%" appveyor DownloadFile "%ASSET_ARCHIVE_PATCH_PATH%" -FileName "%localarchivepath%"
+
+if not [%X86_64%] == [1] (
+ set "archivepath=%ASSET_ARCHIVE_X86_PATH%"
+ call :ARCHIVE_NAME_PARTS
+ set "ASSET_ARCHIVE_X86_PATH_LOCAL=!localarchivepath!"
+ if not exist "!localarchivepath!" appveyor DownloadFile "%ASSET_ARCHIVE_X86_PATH%" -FileName "!localarchivepath!"
+)
+
+if [%X86_64%] == [1] (
+ set "archivepath=%ASSET_ARCHIVE_X64_PATH%"
+ call :ARCHIVE_NAME_PARTS
+ set "ASSET_ARCHIVE_X64_PATH_LOCAL=!localarchivepath!"
+ if not exist "!localarchivepath!" appveyor DownloadFile "%ASSET_ARCHIVE_X64_PATH%" -FileName "!localarchivepath!"
+)
+
+if [%ASSET_FILES_OPTIONAL_GET%] == [1] (
+ set "archivepath=%ASSET_ARCHIVE_OPTIONAL_PATH%"
+ call :ARCHIVE_NAME_PARTS
+ set "ASSET_ARCHIVE_OPTIONAL_PATH_LOCAL=!localarchivepath!"
+ if not exist "!localarchivepath!" appveyor DownloadFile "%ASSET_ARCHIVE_OPTIONAL_PATH%" -FileName "!localarchivepath!"
+)
+
+::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+: Build the installers
+::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+
+mkdir "assets\installer"
+mkdir "assets\patch"
+
+7z x -y "%ASSET_ARCHIVE_PATH_LOCAL%" -o"assets\installer" >null
+7z x -y "%ASSET_ARCHIVE_PATCH_PATH_LOCAL%" -o"assets\patch" >null
+
+: Copy optional files to full installer (music.dta)
+if [%ASSET_FILES_OPTIONAL_GET%] == [1] (
+ 7z x -y "%ASSET_ARCHIVE_OPTIONAL_PATH_LOCAL%" -o"assets\installer" >null
+)
+
+: Copy EXE -- BUILD_PATH is from appveyor.yml
+robocopy /S /ns /nc /nfl /ndl /np /njh /njs "%BUILD_PATH%" "assets\installer" /XF "*.debug" ".gitignore"
+robocopy /S /ns /nc /nfl /ndl /np /njh /njs "%BUILD_PATH%" "assets\patch" /XF "*.debug" ".gitignore"
+
+: Are we building DD? (we were supposed to exit earlier!)
+if [%CONFIGURATION%] == [DD] ( set "DPL_INSTALLER_NAME=%DPL_INSTALLER_NAME%-DD" )
+if [%CONFIGURATION%] == [DD64] ( set "DPL_INSTALLER_NAME=%DPL_INSTALLER_NAME%-DD" )
+
+: If we are not a release tag, suffix the filename
+if not [%APPVEYOR_REPO_TAG%] == [true] (
+ set "INSTALLER_SUFFIX=-%APPVEYOR_REPO_BRANCH%-%GITSHORT%-%CONFIGURATION%"
+) else (
+ set "INSTALLER_SUFFIX="
+)
+
+if not [%X86_64%] == [1] ( goto X86_INSTALL )
+
+::::::::::::::::::::::::::::::::
+: X64_INSTALL
+::::::::::::::::::::::::::::::::
+
+: Extract DLL binaries
+7z x -y "%ASSET_ARCHIVE_X64_PATH_LOCAL%" -o"assets\installer" >null
+if [%PACKAGE_PATCH_DLL_GET%] == [1] (
+ 7z x -y "!ASSET_ARCHIVE_X64_PATH_LOCAL!" -o"assets\patch" >null
+)
+
+: Build the installer
+7z a -sfx7z.sfx "%DPL_INSTALLER_NAME%-x64-Installer%INSTALLER_SUFFIX%.exe" .\assets\installer\*
+
+: Build the patch
+7z a "%DPL_INSTALLER_NAME%-x64-Patch%INSTALLER_SUFFIX%.zip" .\assets\patch\*
+
+: Upload artifacts
+appveyor PushArtifact "%DPL_INSTALLER_NAME%-x64-Installer%INSTALLER_SUFFIX%.exe"
+appveyor PushArtifact "%DPL_INSTALLER_NAME%-x64-Patch%INSTALLER_SUFFIX%.zip"
+
+: We only do x86 OR x64, one at a time, so exit now.
+goto EOF
+
+::::::::::::::::::::::::::::::::
+: X86_INSTALL
+::::::::::::::::::::::::::::::::
+
+: Extract DLL binaries
+7z x -y "%ASSET_ARCHIVE_X86_PATH_LOCAL%" -o"assets\installer" >null
+if [%PACKAGE_PATCH_DLL_GET%] == [1] (
+ 7z x -y "!ASSET_ARCHIVE_X86_PATH_LOCAL!" -o"assets\patch" >null
+)
+
+: Build the installer
+7z a -sfx7z.sfx "%DPL_INSTALLER_NAME%-Installer%INSTALLER_SUFFIX%.exe" .\assets\installer\*
+
+: Build the patch
+7z a "%DPL_INSTALLER_NAME%-Patch%INSTALLER_SUFFIX%.zip" .\assets\patch\*
+
+: Upload artifacts
+appveyor PushArtifact "%DPL_INSTALLER_NAME%-Installer%INSTALLER_SUFFIX%.exe"
+appveyor PushArtifact "%DPL_INSTALLER_NAME%-Patch%INSTALLER_SUFFIX%.zip"
+
+: We only do x86 OR x64, one at a time, so exit now
+goto EOF
+
+::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+: EOF
+::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+
+endlocal
diff --git a/deployer/travis/deployer.sh b/deployer/travis/deployer.sh
new file mode 100644
index 000000000..c88155d21
--- /dev/null
+++ b/deployer/travis/deployer.sh
@@ -0,0 +1,157 @@
+#!/bin/bash
+
+# Deployer for Travis-CI
+# Initialization
+#
+# Performs validity checks to ensure that Deployer is allowed to run
+# e.g., is an FTP hostname specified? Are we whitelisted by OSNAMES and BRANCHES?
+#
+# Set these environment variables in your Travis-CI settings, where they are stored securely.
+# See other shell scripts for more options.
+#
+# DPL_ENABLED = 1 (leave blank to disable)
+# DPL_TAG_ENABLED = 1 (run Deployer on all tags)
+# DPL_JOB_ENABLE_ALL = 1 (run Deployer on all jobs; leave blank to act on specific jobs, see below)
+# DPL_JOBNAMES = name1,name2 (whitelist of job names to allow uploading; leave blank to upload from all jobs)
+# DPL_OSNAMES = osx (whitelist of OS names to allow uploading; leave blank to upload from all OSes)
+# DPL_BRANCHES = master,branch1,branch2 (whitelist of branches to upload; leave blank to upload all branches)
+#
+# To enable Deployer on specific jobs, set _DPL_JOB_ENABLED=1 for that job. Example:
+# - matrix:
+# - os: osx
+# env:
+# - _DPL_JOB_ENABLED=1
+#
+# DO NOT set __DPL_ACTIVE, because that would bypass these validity checks.
+
+# Validate Deployer state
+if [[ "$DPL_ENABLED" == "1" ]] && [[ "$TRAVIS_PULL_REQUEST" == "false" ]]; then
+ # Test for base eligibility:
+ # Are we in a deployer branch? Or
+ # Are we in a release tag AND DPL_TAG_ENABLED=1?
+ if [[ $TRAVIS_BRANCH == *"deployer"* ]]; then
+ __DPL_BASE_ELIGIBLE=1;
+ __DPL_TERMINATE_EARLY_ELIGIBLE=1;
+ fi;
+
+ if [[ "$TRAVIS_TAG" != "" ]] && [[ "$DPL_TAG_ENABLED" == "1" ]]; then
+ __DPL_BASE_ELIGIBLE=1;
+ __DPL_TAG_ELIGIBLE=1;
+ __DPL_TERMINATE_EARLY_ELIGIBLE=1;
+ fi;
+
+ # Logging message for trigger word
+ if [[ "$__DPL_TAG_ELIGIBLE" != "1" ]] && [[ "$DPL_TRIGGER" != "" ]]; then
+ echo "Testing for trigger $DPL_TRIGGER, commit message: $TRAVIS_COMMIT_MESSAGE";
+ echo "[${DPL_TRIGGER}]";
+ echo "[${DPL_TRIGGER}-${_DPL_JOB_NAME}]";
+ echo "[${DPL_TRIGGER}-${TRAVIS_OS_NAME}]";
+ fi;
+
+ #
+ # Search for the trigger word
+ # Force enable if release tags are eligible
+ #
+ if [[ "$__DPL_TAG_ELIGIBLE" == "1" ]] || [[ "$DPL_TRIGGER" == "" ]] \
+ || [[ $TRAVIS_COMMIT_MESSAGE == *"[$DPL_TRIGGER]"* ]] \
+ || [[ $TRAVIS_COMMIT_MESSAGE == *"[${DPL_TRIGGER}-${_DPL_JOB_NAME}]"* ]] \
+ || [[ $TRAVIS_COMMIT_MESSAGE == *"[${DPL_TRIGGER}-${TRAVIS_OS_NAME}]"* ]]; then
+ #
+ # Whitelist by branch name
+ # Force enable if release tags are eligible
+ #
+ if [[ "$__DPL_TAG_ELIGIBLE" == "1" ]] || [[ "$DPL_BRANCHES" == "" ]] || [[ $DPL_BRANCHES == *"$TRAVIS_BRANCH"* ]]; then
+ # Set this so we only early-terminate builds when we are specifically deploying
+ # Trigger string and branch are encompassing conditions; the rest are job-specific
+ # This check only matters for deployer branches and when DPL_TERMINATE_TESTS=1,
+ # because we're filtering non-deployer jobs.
+ #
+ # __DPL_TRY_TERMINATE_EARLY is invalidated in .travis.yml if __DPL_ACTIVE=1
+ if [[ "$__DPL_TERMINATE_EARLY_ELIGIBLE" == "1" ]] && [[ "$DPL_TERMINATE_TESTS" == "1" ]]; then
+ __DPL_TRY_TERMINATE_EARLY=1;
+ fi;
+
+ #
+ # Is the job enabled for deployment?
+ #
+ if [[ "$DPL_JOB_ENABLE_ALL" == "1" ]] || [[ "$_DPL_JOB_ENABLED" == "1" ]]; then
+ #
+ # Whitelist by job names
+ #
+ if [[ "$DPL_JOBNAMES" == "" ]] || [[ "$_DPL_JOB_NAME" == "" ]] || [[ $DPL_JOBNAMES == *"$_DPL_JOB_NAME"* ]]; then
+ #
+ # Whitelist by OS names
+ #
+ if [[ "$DPL_OSNAMES" == "" ]] || [[ $DPL_OSNAMES == *"$TRAVIS_OS_NAME"* ]]; then
+ # Base Deployer is eligible for becoming active
+
+ # Are we building for Linux?
+ if [[ "$_DPL_PACKAGE_BINARY" == "1" ]] || [[ "$_DPL_PACKAGE_SOURCE" == "1" ]]; then
+ if [[ "$_DPL_PACKAGE_MAIN" == "1" ]] || [[ "$_DPL_PACKAGE_ASSET" == "1" ]]; then
+ if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then
+ __DPL_DEBIAN_ACTIVE=1;
+ fi;
+ fi;
+ fi;
+
+ # Now check for deployment targets
+ if [[ "$_DPL_FTP_TARGET" == "1" ]] && [[ "$DPL_FTP_HOSTNAME" != "" ]]; then
+ if [[ "$TRAVIS_OS_HOST" == "linux" ]] && [[ "$DPL_FTP_PROTOCOL" == "ftp" ]]; then
+ echo "Non-secure FTP will not work on Linux Travis-CI jobs!";
+ echo "Try SFTP or another target. Details:";
+ echo "https://blog.travis-ci.com/2018-07-23-the-tale-of-ftp-at-travis-ci";
+ else
+ if [[ "$__DPL_DEBIAN_ACTIVE" == "1" ]] || [[ "$_DPL_PACKAGE_BINARY" == "1" ]] || [[ "$_DPL_BINARY" == "1" ]]; then
+ echo "Deployer FTP target is enabled";
+ __DPL_FTP_ACTIVE=1;
+ else
+ echo "Deployer FTP target cannot be enabled: You must specify _DPL_PACKAGE_BINARY=1,";
+ echo "and/or _DPL_BINARY=1 in your job's environment variables.";
+ fi;
+ fi;
+ fi;
+
+ if [[ "$_DPL_DPUT_TARGET" == "1" ]] && [[ "$__DPL_DEBIAN_ACTIVE" == "1" ]] \
+ && [[ "$DPL_DPUT_INCOMING" != "" ]]; then
+ if [[ "$DPL_DPUT_METHOD" == "ftp" ]]; then
+ echo "DPUT will not work with non-secure FTP on Linux Travis-CI jobs!";
+ echo "Try SFTP or another method for DPUT. Details:";
+ echo "https://blog.travis-ci.com/2018-07-23-the-tale-of-ftp-at-travis-ci";
+ else
+ echo "Deployer DPUT target is enabled";
+ __DPL_DPUT_ACTIVE=1;
+ fi;
+ fi;
+
+ # If any deployment targets are active, then so is the Deployer at large
+ if [[ "$__DPL_FTP_ACTIVE" == "1" ]] || [[ "$__DPL_DPUT_ACTIVE" == "1" ]]; then
+ __DPL_ACTIVE=1;
+ fi;
+ fi;
+ fi;
+ fi;
+ fi;
+ else
+ if [[ "$DPL_TRIGGER" != "" ]]; then
+ echo "Testing for global trigger [$DPL_TRIGGER, commit message: $TRAVIS_COMMIT_MESSAGE";
+ fi;
+ if [[ "$DPL_TRIGGER" != "" ]] && [[ $TRAVIS_COMMIT_MESSAGE == *"[$DPL_TRIGGER"* ]]; then
+ if [[ "$__DPL_TAG_ELIGIBLE" == "1" ]] || [[ "$DPL_BRANCHES" == "" ]] || [[ $DPL_BRANCHES == *"$TRAVIS_BRANCH"* ]]; then
+ # This check only matters for deployer branches and when DPL_TERMINATE_TESTS=1,
+ # because we're filtering non-deployer jobs.
+ if [[ "$__DPL_TERMINATE_EARLY_ELIGIBLE" == "1" ]] && [[ "$DPL_TERMINATE_TESTS" == "1" ]]; then
+ # Assume that some job received the trigger, so mark this for early termination
+ __DPL_TRY_TERMINATE_EARLY=1;
+ fi;
+ fi;
+ fi;
+ fi;
+fi;
+
+if [[ "$__DPL_TRY_TERMINATE_EARLY" == "1" ]] && [[ "$__DPL_ACTIVE" != "1" ]]; then
+ echo "Deployer is active in another job";
+fi;
+
+if [[ "$__DPL_TRY_TERMINATE_EARLY" != "1" ]] && [[ "$__DPL_ACTIVE" != "1" ]]; then
+ echo "Deployer is not active";
+fi;
diff --git a/deployer/travis/deployer_build.sh b/deployer/travis/deployer_build.sh
new file mode 100644
index 000000000..3817f025d
--- /dev/null
+++ b/deployer/travis/deployer_build.sh
@@ -0,0 +1,190 @@
+#!/bin/bash
+
+# Deployer for Travis-CI
+# Build Script
+#
+# Builds the required targets depending on which sub-modules are enabled
+
+if [[ "$__DPL_FTP_ACTIVE" == "1" ]] || [[ "$__DPL_DPUT_ACTIVE" == "1" ]]; then
+ if [[ "$__DPL_DEBIAN_ACTIVE" == "1" ]]; then
+ echo "Building Debian package(s)"
+
+ sudo apt-get install devscripts debhelper fakeroot secure-delete expect;
+
+ # Build source packages first, since they zip up the entire source folder,
+ # binaries and all
+ if [[ "$_DPL_PACKAGE_MAIN" == "1" ]]; then
+ . ../debian_template.sh main;
+ OLDPWD=$PWD; # [repo]/build
+ cd ..; # repo root
+
+ if [[ "$_DPL_PACKAGE_SOURCE" == "1" ]]; then
+ echo "Building main source Debian package";
+ expect <(cat < key.asc;
+ echo "$DPL_PGP_KEY_PASSPHRASE" > phrase.txt;
+ gpg --import key.asc;
+
+ if [[ "$_DPL_PACKAGE_MAIN" == "1" ]]; then
+ echo "Signing main package(s)";
+
+ PACKAGEFILENAME=${PACKAGE_NAME}_${PACKAGE_VERSION}${PACKAGE_SUBVERSION}${PACKAGE_REVISION};
+ PACKAGEDBGFILENAME=${PACKAGE_NAME}-dbg_${PACKAGE_VERSION}${PACKAGE_SUBVERSION}${PACKAGE_REVISION};
+ #PACKAGENIGHTLYFILENAME=${PACKAGE_NAME}-nightly_${PACKAGE_VERSION}${PACKAGE_SUBVERSION}${PACKAGE_REVISION};
+ #PACKAGENIGHTLYDBGFILENAME=${PACKAGE_NAME}-nightly-dbg_${PACKAGE_VERSION}${PACKAGE_SUBVERSION}${PACKAGE_REVISION};
+ #PACKAGEPATCHFILENAME=${PACKAGE_NAME}-patch_${PACKAGE_VERSION}${PACKAGE_SUBVERSION}${PACKAGE_REVISION};
+ #PACKAGEPATCHDBGFILENAME=${PACKAGE_NAME}-patch-dbg_${PACKAGE_VERSION}${PACKAGE_SUBVERSION}${PACKAGE_REVISION};
+ #PACKAGEPATCHNIGHTLYFILENAME=${PACKAGE_NAME}-patch-nightly_${PACKAGE_VERSION}${PACKAGE_SUBVERSION}${PACKAGE_REVISION};
+ #PACKAGEPATCHNIGHTLYDBGFILENAME=${PACKAGE_NAME}-patch-nightly-dbg_${PACKAGE_VERSION}${PACKAGE_SUBVERSION}${PACKAGE_REVISION};
+
+ PACKAGEFILENAMES=(
+ $PACKAGEFILENAME
+ $PACKAGEDBGFILENAME
+ #$PACKAGENIGHTLYFILENAME
+ #$PACKAGENIGHTLYDBGFILENAME
+ #$PACKAGEPATCHFILENAME
+ #$PACKAGEPATCHDBGFILENAME
+ #$PACKAGEPATCHNIGHTLYFILENAME
+ #$PACKAGEPATCHNIGHTLYDBGFILENAME
+ );
+
+ # Main packages are in parent of root repo folder
+ OLDPWD=$PWD; # [repo]/build
+ cd ../..; # parent of repo root
+
+ for n in ${PACKAGEFILENAMES}; do
+ for f in ./$n*.changes; do
+ debsign --no-re-sign -p"gpg --passphrase-file $OLDPWD/phrase.txt --batch" "$f";
+ done;
+ done;
+
+ cd $OLDPWD;
+ fi;
+
+ if [[ "$_DPL_PACKAGE_ASSET" == "1" ]]; then
+ echo "Signing asset package(s)";
+
+ PACKAGEFILENAME=${PACKAGE_NAME}-data_${PACKAGE_VERSION}${PACKAGE_SUBVERSION}${PACKAGE_REVISION};
+ #PACKAGENIGHTLYFILENAME=${PACKAGE_NAME}-nightly-data_${PACKAGE_VERSION}${PACKAGE_SUBVERSION}${PACKAGE_REVISION};
+ #PACKAGEPATCHFILENAME=${PACKAGE_NAME}-patch-data_${PACKAGE_VERSION}${PACKAGE_SUBVERSION}${PACKAGE_REVISION};
+ #PACKAGEPATCHNIGHTLYFILENAME=${PACKAGE_NAME}-patch-nightly-data_${PACKAGE_VERSION}${PACKAGE_SUBVERSION}${PACKAGE_REVISION};
+
+ PACKAGEFILENAMES=(
+ $PACKAGEFILENAME
+ #$PACKAGENIGHTLYFILENAME
+ #$PACKAGEPATCHFILENAME
+ #$PACKAGEPATCHNIGHTLYFILENAME
+ )
+
+ # Asset packages are in root repo folder
+ OLDPWD=$PWD; # [repo]/build
+ cd ..; # repo root
+
+ for n in ${PACKAGEFILENAMES}; do
+ for f in ./$n*.changes; do
+ debsign --no-re-sign -p"gpg --passphrase-file $OLDPWD/phrase.txt --batch" "$f";
+ done;
+ done;
+
+ cd $OLDPWD;
+ fi;
+
+ # Delete the keys :eyes:
+ srm key.asc;
+ srm phrase.txt;
+ fi;
+ fi;
+
+ # all other OSes
+ if [[ "$TRAVIS_OS_NAME" != "linux" ]]; then
+ #
+ # Check for binary building
+ #
+ if [[ "$_DPL_BINARY" == "1" ]]; then
+ echo "Building a Binary";
+ make -k;
+ fi;
+
+ #
+ # Check for package building
+ #
+ if [[ "$_DPL_PACKAGE_BINARY" == "1" ]]; then
+ echo "Building a Package";
+
+ # Make an OSX package; superuser is required for library bundling
+ #
+ # HACK: OSX packaging can't write libraries to .app package unless we're superuser
+ # because the original library files don't have WRITE permission
+ # Bug may be sidestepped by using CHMOD_BUNDLE_ITEMS=TRUE
+ # But I don't know where this is set. Not `cmake -D...` because this var is ignored.
+ # https://cmake.org/Bug/view.php?id=9284
+ if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then
+ sudo make -k package;
+ else
+ # Some day, when Windows is supported, we'll just make a standard package
+ make -k package;
+ fi;
+ fi;
+ fi;
+fi;
diff --git a/deployer/travis/deployer_defaults.sh b/deployer/travis/deployer_defaults.sh
new file mode 100644
index 000000000..bccb7409a
--- /dev/null
+++ b/deployer/travis/deployer_defaults.sh
@@ -0,0 +1,105 @@
+#!/bin/bash
+
+# Deployer for Travis-CI
+# Default Variables
+#
+# Here are all of the user-set variables used by Deployer.
+# See the "Cross-platform deployment" page on SRB2 Wiki for documentation.
+
+# Core Parameters
+: ${DPL_ENABLED} # Enable Deployer behavior; must be set for any deployment activity
+: ${DPL_TAG_ENABLED} # Trigger Deployer for all tag releases
+: ${DPL_JOB_ENABLE_ALL} # Enable all jobs for deployment
+: ${DPL_TERMINATE_TESTS} # Terminate all build test jobs (used in .travis.yml)
+: ${DPL_TRIGGER} # Use a [word] in the commit message to trigger Deployer
+: ${DPL_JOBNAMES} # Trigger Deployer by job name
+: ${DPL_OSNAMES} # Trigger Deployer by OS name (osx,linux)
+: ${DPL_BRANCHES} # Trigger Deployer by git branch name
+
+# Job Parameters
+: ${_DPL_JOB_ENABLED} # Enable Deployer for this specific job. DPL_ENABLED must be set too.
+: ${_DPL_JOB_NAME} # Identifier for the job, used for logging and trigger word matching
+: ${_DPL_FTP_TARGET} # Deploy to FTP
+: ${_DPL_DPUT_TARGET} # Deploy to DPUT
+: ${_DPL_PACKAGE_SOURCE} # Build packages into a Source distribution. Linux only.
+: ${_DPL_PACKAGE_BINARY} # Build packages into a Binary distribution.
+: ${_DPL_PACKAGE_MAIN:=1} # Build main installation package. Linux only; OS X assumes this.
+: ${_DPL_PACKAGE_ASSET} # Build asset installation package. Linux only.
+
+# Asset File Parameters
+: ${ASSET_ARCHIVE_PATH:=https://github.com/mazmazz/SRB2/releases/download/SRB2_assets/SRB2-v2122-assets.7z}
+: ${ASSET_ARCHIVE_OPTIONAL_PATH:=https://github.com/mazmazz/SRB2/releases/download/SRB2_assets/SRB2-v2122-optional-assets.7z}
+: ${ASSET_FILES_HASHED:=srb2.srb zones.dta player.dta rings.dta patch.dta}
+: ${ASSET_FILES_DOCS:=README.txt LICENSE.txt LICENSE-3RD-PARTY.txt}
+: ${ASSET_FILES_OPTIONAL_GET:=0}
+
+# FTP Parameters
+: ${DPL_FTP_PROTOCOL}
+: ${DPL_FTP_USER}
+: ${DPL_FTP_PASS}
+: ${DPL_FTP_HOSTNAME}
+: ${DPL_FTP_PORT}
+: ${DPL_FTP_PATH}
+
+# DPUT Parameters
+: ${DPL_DPUT_DOMAIN:=ppa.launchpad.net}
+: ${DPL_DPUT_METHOD:=sftp}
+: ${DPL_DPUT_INCOMING}
+: ${DPL_DPUT_LOGIN:=anonymous}
+: ${DPL_SSH_KEY_PRIVATE} # Base64-encoded private key file. Used to sign repository uploads
+: ${DPL_SSH_KEY_PASSPHRASE} # Decodes the private key file.
+
+# Package Parameters
+: ${PACKAGE_NAME:=srb2}
+: ${PACKAGE_VERSION:=2.1.23}
+: ${PACKAGE_SUBVERSION} # Highly recommended to set this to reflect the distro series target (e.g., ~18.04bionic)
+: ${PACKAGE_REVISION} # Defaults to UTC timestamp
+: ${PACKAGE_INSTALL_PATH:=/usr/games/SRB2}
+: ${PACKAGE_LINK_PATH:=/usr/games}
+: ${PACKAGE_DISTRO:=trusty}
+: ${PACKAGE_URGENCY:=high}
+: ${PACKAGE_NAME_EMAIL:=Sonic Team Junior }
+: ${PACKAGE_GROUP_NAME_EMAIL:=Sonic Team Junior }
+: ${PACKAGE_WEBSITE:=}
+
+: ${PACKAGE_ASSET_MINVERSION:=2.1.21} # Number this the version BEFORE the actual required version, because we do a > check
+: ${PACKAGE_ASSET_MAXVERSION:=2.1.24} # Number this the version AFTER the actual required version, because we do a < check
+
+: ${PROGRAM_NAME:=Sonic Robo Blast 2}
+: ${PROGRAM_VENDOR:=Sonic Team Junior}
+: ${PROGRAM_VERSION:=2.1.23}
+: ${PROGRAM_DESCRIPTION:=A free 3D Sonic the Hedgehog fangame closely inspired by the original Sonic games on the Sega Genesis.}
+: ${PROGRAM_FILENAME:=srb2}
+
+: ${DPL_PGP_KEY_PRIVATE} # Base64-encoded private key file. Used to sign Debian packages
+: ${DPL_PGP_KEY_PASSPHRASE} # Decodes the private key file.
+
+# Export Asset and Package Parameters for envsubst templating
+
+export ASSET_ARCHIVE_PATH="${ASSET_ARCHIVE_PATH}"
+export ASSET_ARCHIVE_OPTIONAL_PATH="${ASSET_ARCHIVE_OPTIONAL_PATH}"
+export ASSET_FILES_HASHED="${ASSET_FILES_HASHED}"
+export ASSET_FILES_DOCS="${ASSET_FILES_DOCS}"
+export ASSET_FILES_OPTIONAL_GET="${ASSET_FILES_OPTIONAL_GET}"
+
+export PACKAGE_NAME="${PACKAGE_NAME}"
+export PACKAGE_VERSION="${PACKAGE_VERSION}"
+export PACKAGE_SUBVERSION="${PACKAGE_SUBVERSION}" # in case we have this
+export PACKAGE_REVISION="${PACKAGE_REVISION}"
+export PACKAGE_ASSET_MINVERSION="${PACKAGE_ASSET_MINVERSION}"
+export PACKAGE_ASSET_MAXVERSION="${PACKAGE_ASSET_MAXVERSION}"
+export PACKAGE_INSTALL_PATH="${PACKAGE_INSTALL_PATH}"
+export PACKAGE_LINK_PATH="${PACKAGE_LINK_PATH}"
+export PACKAGE_DISTRO="${PACKAGE_DISTRO}"
+export PACKAGE_URGENCY="${PACKAGE_URGENCY}"
+export PACKAGE_NAME_EMAIL="${PACKAGE_NAME_EMAIL}"
+export PACKAGE_GROUP_NAME_EMAIL="${PACKAGE_GROUP_NAME_EMAIL}"
+export PACKAGE_WEBSITE="${PACKAGE_WEBSITE}"
+
+export PROGRAM_NAME="${PROGRAM_NAME}"
+export PROGRAM_VERSION="${PROGRAM_VERSION}"
+export PROGRAM_DESCRIPTION="${PROGRAM_DESCRIPTION}"
+export PROGRAM_FILENAME="${PROGRAM_FILENAME}"
+
+# This file is called in debian_template.sh, so mark our completion so we don't run it again
+__DEBIAN_PARAMETERS_INITIALIZED=1
diff --git a/deployer/travis/deployer_dput.sh b/deployer/travis/deployer_dput.sh
new file mode 100644
index 000000000..863a928cd
--- /dev/null
+++ b/deployer/travis/deployer_dput.sh
@@ -0,0 +1,133 @@
+#!/bin/bash
+
+# Deployer for Travis-CI
+# DPUT uploader (e.g., Launchpad PPA)
+#
+
+if [[ "$__DPL_DPUT_ACTIVE" == "1" ]]; then
+ # Install APT dependencies
+ # paramiko required for ssh
+ sudo apt-get install python-paramiko expect dput; # python-pip
+ #pip install paramiko;
+
+ # Output the DPUT config
+ # Dput only works if you're using secure FTP, so that's what we default to.
+ cat > "./dput.cf" << EOM
+[deployer]
+fqdn = ${DPL_DPUT_DOMAIN}
+method = ${DPL_DPUT_METHOD}
+incoming = ${DPL_DPUT_INCOMING}
+login = ${DPL_DPUT_LOGIN}
+allow_unsigned_uploads = 0
+EOM
+
+ # Output SSH config
+ # Don't let SSH prompt us for untrusted hosts
+ cat >> "./ssh_config" << EOM
+
+Host *
+ StrictHostKeyChecking no
+ UserKnownHostsFile=/dev/null
+ PubKeyAuthentication yes
+ IdentityFile ${PWD}/key.private
+ IdentitiesOnly yes
+EOM
+ sudo sh -c "cat < ${PWD}/ssh_config >> /etc/ssh/ssh_config";
+
+ # Get the private key
+ echo "$DPL_SSH_KEY_PRIVATE" | base64 --decode > key.private;
+ chmod 700 ./key.private;
+
+ if [[ "$_DPL_PACKAGE_MAIN" == "1" ]]; then
+ PACKAGEFILENAME=${PACKAGE_NAME}_${PACKAGE_VERSION}${PACKAGE_SUBVERSION}${PACKAGE_REVISION};
+ PACKAGEDBGFILENAME=${PACKAGE_NAME}-dbg_${PACKAGE_VERSION}${PACKAGE_SUBVERSION}${PACKAGE_REVISION};
+ #PACKAGENIGHTLYFILENAME=${PACKAGE_NAME}-nightly_${PACKAGE_VERSION}${PACKAGE_SUBVERSION}${PACKAGE_REVISION};
+ #PACKAGENIGHTLYDBGFILENAME=${PACKAGE_NAME}-nightly-dbg_${PACKAGE_VERSION}${PACKAGE_SUBVERSION}${PACKAGE_REVISION};
+ #PACKAGEPATCHFILENAME=${PACKAGE_NAME}-patch_${PACKAGE_VERSION}${PACKAGE_SUBVERSION}${PACKAGE_REVISION};
+ #PACKAGEPATCHDBGFILENAME=${PACKAGE_NAME}-patch-dbg_${PACKAGE_VERSION}${PACKAGE_SUBVERSION}${PACKAGE_REVISION};
+ #PACKAGEPATCHNIGHTLYFILENAME=${PACKAGE_NAME}-patch-nightly_${PACKAGE_VERSION}${PACKAGE_SUBVERSION}${PACKAGE_REVISION};
+ #PACKAGEPATCHNIGHTLYDBGFILENAME=${PACKAGE_NAME}-patch-nightly-dbg_${PACKAGE_VERSION}${PACKAGE_SUBVERSION}${PACKAGE_REVISION};
+
+ PACKAGEFILENAMES=(
+ $PACKAGEFILENAME
+ $PACKAGEDBGFILENAME
+ #$PACKAGENIGHTLYFILENAME
+ #$PACKAGENIGHTLYDBGFILENAME
+ #$PACKAGEPATCHFILENAME
+ #$PACKAGEPATCHDBGFILENAME
+ #$PACKAGEPATCHNIGHTLYFILENAME
+ #$PACKAGEPATCHNIGHTLYDBGFILENAME
+ );
+
+ # Main packages are in parent of root repo folder
+ OLDPWD=$PWD; # [repo]/build
+ cd ../..;
+
+ # Enter passphrase if required
+ for n in ${PACKAGEFILENAMES}; do
+ for f in $n*.changes; do
+ # Binary builds also generate source builds, so exclude the source
+ # builds if desired
+ if [[ "$_DPL_PACKAGE_SOURCE" != "1" ]]; then
+ if [[ "$f" == *"_source"* ]] || [[ "$f" == *".tar.xz"* ]]; then
+ continue;
+ fi;
+ fi;
+
+ expect <(cat < "commit.txt";
+ echo "Job ID $TRAVIS_JOB_ID" >> "commit.txt";
+ echo "" >> "commit.txt";
+ echo "Commit $TRAVIS_COMMIT" >> "commit.txt";
+ echo "$TRAVIS_COMMIT_MESSAGE" >> "commit.txt";
+ echo "" >> "commit.txt";
+
+ # Initialize FTP parameters
+ if [[ "$DPL_FTP_PORT" == "" ]]; then
+ DPL_FTP_PORT=21;
+ fi;
+ if [[ "$DPL_FTP_PROTOCOL" == "" ]]; then
+ DPL_FTP_PROTOCOL=ftp;
+ fi;
+ __DPL_FTP_LOCATION=$DPL_FTP_PROTOCOL://$DPL_FTP_HOSTNAME:$DPL_FTP_PORT/$DPL_FTP_PATH/$TRAVIS_REPO_SLUG/$TRAVIS_BRANCH/$TRAVIS_JOB_ID-$TRAVIS_JOB_NUMBER-$JOBNAME;
+
+ # Upload to FTP!
+ echo "Uploading to FTP...";
+ curl --ftp-create-dirs -T "commit.txt" -u $DPL_FTP_USER:$DPL_FTP_PASS "$__DPL_FTP_LOCATION/commit.txt";
+
+ if [[ "$__DPL_DEBIAN_ACTIVE" == "1" ]]; then
+ if [[ "$_DPL_PACKAGE_MAIN" == "1" ]]; then
+ PACKAGEFILENAME=${PACKAGE_NAME}_${PACKAGE_VERSION}${PACKAGE_SUBVERSION}${PACKAGE_REVISION};
+ PACKAGEDBGFILENAME=${PACKAGE_NAME}-dbg_${PACKAGE_VERSION}${PACKAGE_SUBVERSION}${PACKAGE_REVISION};
+ #PACKAGENIGHTLYFILENAME=${PACKAGE_NAME}-nightly_${PACKAGE_VERSION}${PACKAGE_SUBVERSION}${PACKAGE_REVISION};
+ #PACKAGENIGHTLYDBGFILENAME=${PACKAGE_NAME}-nightly-dbg_${PACKAGE_VERSION}${PACKAGE_SUBVERSION}${PACKAGE_REVISION};
+ #PACKAGEPATCHFILENAME=${PACKAGE_NAME}-patch_${PACKAGE_VERSION}${PACKAGE_SUBVERSION}${PACKAGE_REVISION};
+ #PACKAGEPATCHDBGFILENAME=${PACKAGE_NAME}-patch-dbg_${PACKAGE_VERSION}${PACKAGE_SUBVERSION}${PACKAGE_REVISION};
+ #PACKAGEPATCHNIGHTLYFILENAME=${PACKAGE_NAME}-patch-nightly_${PACKAGE_VERSION}${PACKAGE_SUBVERSION}${PACKAGE_REVISION};
+ #PACKAGEPATCHNIGHTLYDBGFILENAME=${PACKAGE_NAME}-patch-nightly-dbg_${PACKAGE_VERSION}${PACKAGE_SUBVERSION}${PACKAGE_REVISION};
+
+ PACKAGEFILENAMES=(
+ $PACKAGEFILENAME
+ $PACKAGEDBGFILENAME
+ #$PACKAGENIGHTLYFILENAME
+ #$PACKAGENIGHTLYDBGFILENAME
+ #$PACKAGEPATCHFILENAME
+ #$PACKAGEPATCHDBGFILENAME
+ #$PACKAGEPATCHNIGHTLYFILENAME
+ #$PACKAGEPATCHNIGHTLYDBGFILENAME
+ );
+
+ # Main packages are in parent of root repo folder
+ OLDPWD=$PWD; # [repo]/build
+ cd ../..;
+
+ for n in ${PACKAGEFILENAMES}; do
+ for f in ./$n*; do
+ # Binary builds also generate source builds, so exclude the source
+ # builds if desired
+ if [[ "$_DPL_PACKAGE_SOURCE" != "1" ]]; then
+ if [[ "$f" == *"_source"* ]] || [[ "$f" == *".tar.xz"* ]]; then
+ continue;
+ fi;
+ fi;
+ curl --ftp-create-dirs -T "$f" -u $DPL_FTP_USER:$DPL_FTP_PASS "$__DPL_FTP_LOCATION/package/main/$f";
+ done;
+ done;
+
+ # Go back to [repo]/build folder
+ cd $OLDPWD;
+ fi;
+
+ if [[ "$_DPL_PACKAGE_ASSET" == "1" ]]; then
+ PACKAGEFILENAME=${PACKAGE_NAME}-data_${PACKAGE_VERSION}${PACKAGE_SUBVERSION}${PACKAGE_REVISION};
+ #PACKAGENIGHTLYFILENAME=${PACKAGE_NAME}-nightly-data_${PACKAGE_VERSION}${PACKAGE_SUBVERSION}${PACKAGE_REVISION};
+ #PACKAGEPATCHFILENAME=${PACKAGE_NAME}-patch-data_${PACKAGE_VERSION}${PACKAGE_SUBVERSION}${PACKAGE_REVISION};
+ #PACKAGEPATCHNIGHTLYFILENAME=${PACKAGE_NAME}-patch-nightly-data_${PACKAGE_VERSION}${PACKAGE_SUBVERSION}${PACKAGE_REVISION};
+
+ PACKAGEFILENAMES=(
+ $PACKAGEFILENAME
+ #$PACKAGENIGHTLYFILENAME
+ #$PACKAGEPATCHFILENAME
+ #$PACKAGEPATCHNIGHTLYFILENAME
+ )
+
+ # Asset packages are in root repo folder
+ OLDPWD=$PWD; # [repo]/build
+ cd ..;
+
+ for n in ${PACKAGEFILENAMES}; do
+ for f in ./$n*; do
+ # Binary builds also generate source builds, so exclude the source
+ # builds if desired
+ if [[ "$_DPL_PACKAGE_SOURCE" != "1" ]]; then
+ if [[ "$f" == *"_source"* ]] || [[ "$f" == *".tar.xz"* ]]; then
+ continue;
+ fi;
+ fi;
+ curl --ftp-create-dirs -T "$f" -u $DPL_FTP_USER:$DPL_FTP_PASS "$__DPL_FTP_LOCATION/package/asset/$f";
+ done;
+ done;
+
+ # Go back to [repo]/build folder
+ cd $OLDPWD;
+ fi;
+ else
+ if [[ "$_DPL_BINARY" == "1" ]]; then
+ find bin -type f -exec curl -u $DPL_FTP_USER:$DPL_FTP_PASS --ftp-create-dirs -T {} $__DPL_FTP_LOCATION/{} \;;
+ fi;
+
+ if [[ "$_DPL_PACKAGE_BINARY" == "1" ]]; then
+ sudo rm -r package/_CPack_Packages
+ find package -type f -exec curl -u $DPL_FTP_USER:$DPL_FTP_PASS --ftp-create-dirs -T {} $__DPL_FTP_LOCATION/{} \;;
+ fi;
+ fi;
+fi
diff --git a/libs/DLL-README.txt b/libs/DLL-README.txt
index 058ec0685..45680c535 100644
--- a/libs/DLL-README.txt
+++ b/libs/DLL-README.txt
@@ -7,6 +7,7 @@ Here are the required DLLs, per build. For each architecture, copy all the binar
* libs\dll-binaries\[i686/x86_64]
* libs\SDL2\[i686/x86_64]...\bin
* libs\SDL2_mixer\[i686/x86_64]...\bin
+* libs\libopenmpt\[x86/x86_64]...\bin\mingw
and don't forget to build r_opengl.dll for srb2dd.
@@ -17,6 +18,7 @@ and don't forget to build r_opengl.dll for srb2dd.
* libs\dll-binaries\i686\mgwhelp.dll (depend for exchndl.dll)
* libs\SDL2\i686-w64-mingw32\bin\SDL2.dll
* libs\SDL2_mixer\i686-w64-mingw32\bin\*.dll (get everything)
+* libs\libopenmpt\x86\bin\mingw\libopenmpt.dll
## srb2win, 64-bit
@@ -25,6 +27,7 @@ and don't forget to build r_opengl.dll for srb2dd.
* libs\dll-binaries\x86_64\mgwhelp.dll (depend for exchndl.dll)
* libs\SDL2\x86_64-w64-mingw32\bin\SDL2.dll
* libs\SDL2_mixer\x86_64-w64-mingw32\bin\*.dll (get everything)
+* libs\libopenmpt\x86_64\bin\mingw\libopenmpt.dll
## srb2dd, 32-bit
diff --git a/libs/SDL2/lib/ARM/SDL2.lib b/libs/SDL2/lib/ARM/SDL2.lib
new file mode 100644
index 000000000..be9d86949
Binary files /dev/null and b/libs/SDL2/lib/ARM/SDL2.lib differ
diff --git a/libs/SDL2/lib/ARM64/SDL2.dll b/libs/SDL2/lib/ARM64/SDL2.dll
new file mode 100644
index 000000000..f9eac1c0b
Binary files /dev/null and b/libs/SDL2/lib/ARM64/SDL2.dll differ
diff --git a/libs/SDL2/lib/ARM64/SDL2.lib b/libs/SDL2/lib/ARM64/SDL2.lib
new file mode 100644
index 000000000..40904c308
Binary files /dev/null and b/libs/SDL2/lib/ARM64/SDL2.lib differ
diff --git a/libs/SDL2_mixer/lib/ARM/SDL2_mixer.lib b/libs/SDL2_mixer/lib/ARM/SDL2_mixer.lib
new file mode 100644
index 000000000..3886f3aa9
Binary files /dev/null and b/libs/SDL2_mixer/lib/ARM/SDL2_mixer.lib differ
diff --git a/libs/SDL2_mixer/lib/ARM64/SDL2_mixer.dll b/libs/SDL2_mixer/lib/ARM64/SDL2_mixer.dll
new file mode 100644
index 000000000..d5650b0d2
Binary files /dev/null and b/libs/SDL2_mixer/lib/ARM64/SDL2_mixer.dll differ
diff --git a/libs/SDL2_mixer/lib/ARM64/SDL2_mixer.lib b/libs/SDL2_mixer/lib/ARM64/SDL2_mixer.lib
new file mode 100644
index 000000000..58c3e6966
Binary files /dev/null and b/libs/SDL2_mixer/lib/ARM64/SDL2_mixer.lib differ
diff --git a/libs/SDLMixerX/CHANGES.X.txt b/libs/SDLMixerX/CHANGES.X.txt
new file mode 100644
index 000000000..17b43d9af
--- /dev/null
+++ b/libs/SDLMixerX/CHANGES.X.txt
@@ -0,0 +1,48 @@
+2.1.0:
+Vitaly Novichkov - Sat, Jan 20, 2018 18:06:00
+ * SDL Mixer X has been re-created from original again as official SDL Mixer had a big and incompatible rework
+ * Custom resampler is no more needed as SDL2 now finally uses new better resampler
+ * Added CMake build
+ * Added an ability to toggle MIDI playing libraries (NativeMidi, Timidity or FluidSynth)
+ * Added a full seekability with "tell" and "length" commands
+ * Added a basic support for Meta-Tags to show Title, Artist, Album and Copyright captured from music files.
+ * Added an extra arguments in music path string to support song individual settings per some codecs (for example, play different MIDI files with different MIDI playing libraries)
+ * Timidity: Added ability to set a config search pach, for example, inside of application directory API.
+ * Added OPNMIDI MIDI sequencer based on YM2612 chip emulation. Includes a complete General-MIDI embedded bank.
+ * Added functions to use custom bank files for ADL/OPN-MIDI sequencers (WOPL for ADLMIDI and WOPN for OPNMIDI)
+ * WAVE: Added support for PCM24, PCM32, Float32, Float64m, ALAW, and MULAW sample formats,
+ * AIFF: Added support for AIFF-C, also support for PCM24, PCM32, Float32, Float64, ALAW, and MULAW formats
+ * WAVE & AIFF: Added full seekability support (seek, tell, length)
+ * MP3: More accurate MP3 file detection as some weird MP3 files are can't be detected by existing code; Added usage lf libID3tag library to fetch ID3 tags and also detect begin offset inside of MP3 files as some MP3 files are causing libMAD play ID3 data as actual encoded sound data that causes weird playback and later crash. To avoid this, ID3 parse is needed to detect actual begin of audio data.
+ * Fixed: SMPEG: Fix a broken build
+ * Fixed: OGG: Fixed support for pre-defined count of loops when loop tags are presented
+ * Warning fixes
+ * Some C90 compatibility fixes
+ * Internally: Added MIX_UNUSED() macro to mute warnings on various compilers
+
+1.0.3:
+Vitaly Novichkov - 2016
+ * Implemented own resampler to don't use buggy SDL Audio's resampler
+ * Added support of path arguments to allow dynamic configuring of GME and MIDI playing per every file
+ * ModPlug now is part of SDL Mixer X in same project
+ * Link all dependent libraries (libOGG, libVorbis, libFLAC, libMAD) statically
+
+1.0.2:
+Vitaly Novichkov - 2015
+ * Added ADLMIDI MIDI sequencer which is completely independent MIDI sequencer which requires no extra bank files to play MIDI.
+ * Added ability to dynamically switch MIDI device (ADLMIDI, Timidity, Native MIDI, FluidSynth)
+ * Added meta-tag getting functions: Mix_GetMusicTitle, Mix_GetMusicTitleTag, Mix_GetMusicArtistTag, Mix_GetMusicAlbumTag, Mix_GetMusicCopyrightTag.
+ * Added ability to build VB6-Compatible version to use it as standalone audio library
+
+1.0.1:
+Vitaly Novichkov - 2015
+ * Added GME library to support many game music formats
+ * Added support of loop tags for OGG Vorbis files (based on vorbis comments "LOOPSTART" and "LOOPEND" (also supported "LOOPLENGTH" for RPG-Maker compatibility))
+ * Added MIX_Timidity_addToPathList(const char *path) to customize Timidity path
+
+1.0.0:
+Vitaly Novichkov - 2015
+ * Added support of SPC playback
+ * Attempt to fix resampling
+ * Using QMake instead of autotools to build library
+
diff --git a/libs/SDLMixerX/CHANGES.txt b/libs/SDLMixerX/CHANGES.txt
new file mode 100644
index 000000000..50c0fee0b
--- /dev/null
+++ b/libs/SDLMixerX/CHANGES.txt
@@ -0,0 +1,184 @@
+2.0.3:
+Sam Lantinga - Thu, Mar 1, 2018 9:06:58 AM
+ * Fixed regression where Mix_Init() would return 0 for available music formats
+
+2.0.2:
+Sam Lantinga - Fri Oct 20 22:04:50 PDT 2017
+ * Implemented 24-bit and surround sound support for FLAC audio files
+Sam Lantinga - Thu Oct 12 21:32:44 PDT 2017
+ * Updated external libraries flac-1.3.2, libmodplug-0.8.9.0, libogg-1.3.2 and libvorbis-1.3.5
+Ryan Gordon - Thu Oct 12 21:29:59 PDT 2017
+ * Updated for SDL 2.0.6 and newer
+Franc[e]sco - Thu Jul 20 22:03:19 2017 +0200
+ * Added support for MP3 playback using mpg123
+David Ludwig - Sun Apr 10 22:35:38 2016
+ * Added support for UWP / Windows 10 apps
+Juha Kuikka - Fri Jan 29 12:44:01 PST 2016
+ * Added Mix_OpenAudioDevice() so you can specify the audio device to open
+
+2.0.1:
+Sam Lantinga - Tue Jul 7 11:40:33 PDT 2015
+ * Added support for 'smpl' format loop points in music WAV files
+Sam Lantinga - Sat Aug 23 10:57:26 2014
+ * Fixed floating point exception in Mix_Volume()
+David Ludwig - Mon Apr 14 22:15:36 2014
+ * Added support for building for Windows RT and Windows Phone
+Isaac Burns - Sun Sep 15 21:50:27 PDT 2013
+ * Added support for loading MP3 files as sound chunks
+
+2.0.0:
+Sam Lantinga - Sun Jun 9 14:45:30 PDT 2013
+ * Made libmodplug the default MOD player as it is now in the public domain
+Sam Lantinga - Sat Jun 1 19:11:08 PDT 2013
+ * Updated for SDL 2.0 release
+ * SDL_LoadMUS_RW() now takes an argument telling whether or not the data source should be freed when done.
+
+1.2.13:
+Paul P Komkoff Jr - Sun Jul 22 16:12:28 PDT 2012
+ * Fixed malloc/free mismatch in the MikMod driver
+
+1.2.12:
+Sam Lantinga - Sat Jan 14 22:00:29 2012 -0500
+ * Fixed seek offset with SMPEG (was relative, should be absolute)
+Sam Lantinga - Fri Jan 13 03:04:27 EST 2012
+ * Fixed memory crash loading Ogg Vorbis files on Windows
+Sam Lantinga - Thu Jan 05 22:51:54 2012 -0500
+ * Added an Xcode project for iOS
+Nikos Chantziaras - 2012-01-02 17:37:36 PST
+ * Added Mix_LoadMUSType_RW() so you can tell SDL_mixer what type the music is
+Sam Lantinga - Sun Jan 01 16:45:58 2012 -0500
+ * Fixed looping native MIDI on Mac OS X and Windows
+Sam Lantinga - Sun Jan 01 01:00:51 2012 -0500
+ * Added /usr/local/share/timidity to the timidity data path
+Sam Lantinga - Sat Dec 31 21:26:46 2011 -0500
+ * Fixed timidity loading of some MIDI files
+Sam Lantinga - Sat Dec 31 19:11:59 EST 2011
+ * Fixed dropping audio in the FLAC audio decoding
+Sam Lantinga - Sat Dec 31 18:32:05 EST 2011
+ * Fixed memory leak in SDL_LoadMUS()
+Sam Lantinga - Sat Dec 31 10:22:05 EST 2011
+ * Removed GPL native MIDI code for new licensing
+Sam Lantinga - Sat Dec 31 10:22:05 EST 2011
+ * SDL_mixer is now under the zlib license
+Manuel Montezelo - 2011-12-28 11:42:44 PST
+ * Fixed drums playing on MIDI channel 16 with timidity
+Ryan C. Gordon - Wed Jun 15 03:41:31 2011 -0400
+ * The music-finished hook can start a track immediately
+James Le Cuirot - Mon Mar 21 16:54:11 PDT 2011
+ * Added support for FluidSynth
+Egor Suvorov - Tue Jan 18 11:06:47 PST 2011
+ * Added support for native MIDI on Haiku
+Sam Lantinga - Tue Jan 11 01:29:19 2011 -0800
+ * Added Android.mk to build on the Android platform
+Jon Atkins - Sat Nov 14 13:00:18 PST 2009
+ * Added support for libmodplug (disabled by default)
+
+1.2.11:
+Sam Lantinga - Sat Nov 14 12:38:01 PST 2009
+ * Fixed initialization error and crashes if MikMod library isn't available
+Sam Lantinga - Sat Nov 14 11:22:14 PST 2009
+ * Fixed bug loading multiple music files
+
+1.2.10:
+Sam Lantinga - Sun Nov 8 08:34:48 PST 2009
+ * Added Mix_Init()/Mix_Quit() to prevent constantly loading and unloading DLLs
+Mike Frysinger - 2009-11-05 09:11:43 PST
+ * Check for fork/vfork on any platform, don't just assume it on UNIX
+Jon Atkins - Thu Nov 5 00:02:50 2009 UTC
+ * Fixed export of Mix_GetNumChunkDecoders() and Mix_GetNumMusicDecoders()
+C.W. Betts - 2009-11-02 00:16:21 PST
+ * Use newer MIDI API on Mac OS X 10.5+
+
+1.2.9:
+Ryan Gordon - Sun Oct 18 11:42:31 PDT 2009
+ * Updated native MIDI support on Mac OS X for 10.6
+Ryan Gordon - Sun Oct 11 05:29:55 2009 UTC
+ * Reset channel volumes after a fade out interrupts a fade in.
+Ryan Gordon - Sun Oct 11 02:59:12 2009 UTC
+ * Fixed crash race condition with position audio functions
+Ryan Gordon - Sat Oct 10 17:05:45 2009 UTC
+ * Fixed stereo panning in 8-bit mode
+Sam Lantinga - Sat Oct 10 11:07:15 2009 UTC
+ * Added /usr/share/timidity to the default timidity.cfg locations
+Sam Lantinga - Sat Oct 3 13:33:36 PDT 2009
+ * MOD support uses libmikmod and is dynamically loaded by default
+ * A patched version of libmikmod is included in libmikmod-3.1.12.zip
+ * The libmikmod patches fix security issues CVE-2007-6720 and CVE-2009-0179.
+Sam Lantinga - Sat Oct 3 02:49:41 PDT 2009
+ * Added TIMIDITY_CFG environment variable to fully locate timidity.cfg
+Sam Lantinga - Fri Oct 2 07:15:35 PDT 2009
+ * Implemented seamless looping for music playback
+Forrest Voight - 2009-06-13 20:31:38 PDT
+ * ID3 files are now recognized as MP3 format
+Steven Noonan - 2008-05-13 13:31:36 PDT
+ * Fixed native MIDI crash on 64-bit Windows
+Ryan Gordon - Fri Jun 5 16:07:08 2009 UTC
+ * Added decoder enumeration API:
+ Mix_GetNumChunkDecoders(), Mix_GetChunkDecoder(),
+ Mix_GetNumMusicDecoders(), Mix_GetMusicDecoder()
+Austen Dicken - Tue Feb 26 23:28:27 PST 2008
+ * Added support for FLAC audio both as chunks and streaming
+Tilman Sauerbeck - Tue Feb 26 03:44:47 PST 2008
+ * Added support for streaming WAV files with Mix_LoadMUS_RW()
+Ryan Gordon - Mon Feb 4 17:10:08 UTC 2008
+ * Fixed crash caused by not resetting position_channels
+
+1.2.8:
+Sam Lantinga - Wed Jul 18 09:45:54 PDT 2007
+ * Improved detection of Ogg Vorbis and Tremor libraries
+Ryan Gordon - Sun Jul 15 12:03:54 EDT 2007
+ * Fixed memory leaks in Effects API.
+David Rose - Sat Jul 14 22:16:09 PDT 2007
+ * Added support for MP3 playback with libmad (for GPL projects only!)
+Sam Lantinga - Sat Jul 14 21:39:30 PDT 2007
+ * Fixed the final loop of audio samples of a certain size
+Sam Lantinga - Sat Jul 14 21:05:09 PDT 2007
+ * Fixed opening Ogg Vorbis files using different C runtimes on Windows
+Philippe Simons - Sat Jul 14 20:33:17 PDT 2007
+ * Added support for Ogg Vorbis playback with Tremor (an integer decoder)
+Sam Lantinga - Sat Jul 14 07:02:09 PDT 2007
+ * Fixed memory corruption in timidity resampling code
+Ryan Gordon - Tue Jul 3 10:44:29 2007 UTC
+ * Fixed building SDL_mixer with SDL 1.3 pre-release
+Ryan Gordon - Tue Feb 13 08:11:54 2007 UTC
+ * Fixed compiling both timidity and native midi in the same build
+Hans de Goede - Sun Aug 20 23:25:46 2006 UTC
+ * Added volume control to playmus
+Jonathan Atkins - Thu Aug 10 15:06:40 2006 UTC
+ * Fixed linking with system libmikmod
+David Ergo - Fri Jun 23 09:07:19 2006 UTC
+ * Corrected no-op conditions in SetDistance(), SetPanning() and SetPosition()
+ * Fixed copy/paste errors in channel amplitudes
+
+1.2.7:
+Sam Lantinga - Fri May 12 00:04:32 PDT 2006
+ * Added support for dynamically loading SMPEG library
+Sam Lantinga - Thu May 11 22:22:43 PDT 2006
+ * Added support for dynamically loading Ogg Vorbis library
+Sam Lantinga - Sun Apr 30 09:01:44 PDT 2006
+ * Removed automake dependency, to allow Universal binaries on Mac OS X
+ * Added gcc-fat.sh for generating Universal binaries on Mac OS X
+Sam Lantinga - Sun Apr 30 01:48:40 PDT 2006
+ * Updated libtool support to version 1.5.22
+Patrice Mandin - Sat Jul 16 16:43:24 UTC 2005
+ * Use SDL_RWops also for native midi mac and win32
+Patrice Mandin - Sat Jul 9 14:40:09 UTC 2005
+ * Use SDL_RWops also for native midi gpl (todo: mac and win32)
+Ryan C. Gordon - Sat Jul 9 01:54:03 EDT 2005
+ * Tweaked Mix_Chunk's definition to make predeclaration easier.
+Patrice Mandin - Mon Jul 4 19:45:40 UTC 2005
+ * Search timidity.cfg also in /etc
+ * Fix memory leaks in timidity player
+ * Use also SDL_RWops to read midifiles for timidity
+Ryan C. Gordon - Mon Jun 13 18:18:12 EDT 2005
+ * Patch from Eric Wing to fix native midi compiling on MacOS/x86.
+Sam Lantinga - Wed Dec 22 17:14:32 PST 2004
+ * Disabled support for the system version of libmikmod by default
+Sam Lantinga - Tue Dec 21 09:51:29 PST 2004
+ * Fixed building mikmod support on UNIX
+ * Always build SDL_RWops music support
+ * Added SDL_RWops support for reading MP3 files
+
+1.2.6:
+Jonathan Atkins - Wed, 15 Sep 2004 23:26:42 -0500
+ * Added support for using the system version of libmikmod
diff --git a/libs/SDLMixerX/CMakeLists.txt b/libs/SDLMixerX/CMakeLists.txt
new file mode 100644
index 000000000..af55b0265
--- /dev/null
+++ b/libs/SDLMixerX/CMakeLists.txt
@@ -0,0 +1,818 @@
+cmake_minimum_required (VERSION 2.8.11)
+project(SDLMixerX C)
+
+include(FindPkgConfig)
+include(CheckIncludeFiles)
+include(CheckFunctionExists)
+include(CheckLibraryExists)
+#include(CheckCSourceRuns)
+#include(CheckCCompilerFlag)
+
+if(NOT CMAKE_VERSION VERSION_LESS 2.8.12)
+ set(CMAKE_MACOSX_RPATH 0)
+endif()
+
+if(NOT CMAKE_BUILD_TYPE)
+ set(CMAKE_BUILD_TYPE "Release" CACHE STRING "Choose the type of build, options are: Debug Release RelWithDebInfo MinSizeRel." FORCE)
+ message("== Using default build configuration which is a Release!")
+endif()
+
+if(CMAKE_BUILD_TYPE STREQUAL "Debug")
+ set(MIX_DEBUG_SUFFIX "d")
+else()
+ set(MIX_DEBUG_SUFFIX "")
+endif()
+
+if(WIN32)
+ set(CMAKE_SHARED_LIBRARY_PREFIX "")
+endif()
+
+if(POLICY CMP0058)
+ cmake_policy(SET CMP0058 NEW)
+endif()
+
+option(SSEMATH "Allow GCC to use SSE floating point math" ${OPT_DEF_SSEMATH})
+option(MMX "Use MMX assembly routines" ${OPT_DEF_ASM})
+option(3DNOW "Use 3Dnow! MMX assembly routines" ${OPT_DEF_ASM})
+option(SSE "Use SSE assembly routines" ${OPT_DEF_ASM})
+option(SSE2 "Use SSE2 assembly routines" ${OPT_DEF_SSEMATH})
+option(SSE3 "Use SSE3 assembly routines" ${OPT_DEF_SSEMATH})
+
+# Settings
+option(SDL_MIXER_X_STATIC "Build static library of SDL Mixer X" ON)
+option(SDL_MIXER_X_SHARED "Build shared library of SDL Mixer X" ON)
+
+option(DOWNLOAD_AUDIO_CODECS_DEPENDENCY "Downloads and compiles AudioCodecs dependencies pack directly" OFF)
+set(AUDIO_CODECS_REPO_PATH "" CACHE PATH "Path to the AudioCodecs dependencies pack")
+set(AUDIO_CODECS_INSTALL_PATH "" CACHE PATH "Path to installed AudioCodecs prefix")
+
+if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX)
+ # Turn on warnings and legacy C/C++ standards to support more compilers
+ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -std=c90")
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -pedantic -std=c++98")
+ # Deny undefined symbols
+ if(NOT APPLE)
+ set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--no-undefined" )
+ set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} -Wl,--no-undefined" )
+ endif()
+endif()
+
+set(SDL_MIXER_INCLUDE_PATHS)
+
+if(NOT AUDIO_CODECS_REPO_PATH AND NOT AUDIO_CODECS_INSTALL_PATH)
+ # Try to resolve sqlite dependency
+ if(DOWNLOAD_AUDIO_CODECS_DEPENDENCY)
+ # Download and configure AudioCodecs dependency
+ set(SDL2_REPO_PATH ${CMAKE_INSTALL_PREFIX})
+ set(SDL2_INCLUDE_PATH ${CMAKE_INSTALL_PREFIX}/include/SDL2)
+ set(SDL2_LIBS_PATH ${CMAKE_INSTALL_PREFIX}/lib)
+ include(cmake/DownloadAudioCodecs.cmake)
+ set(AUDIO_CODECS_REPO_PATH ${AUDIO_CODECS_REPOSITORY_PATH})
+ set(AUDIO_CODECS_INSTALL_PATH ${AUDIO_CODECS_INSTALL_DIR})
+ endif()
+endif()
+
+set(FIND_PREFER_STATIC
+ "-static${MIX_DEBUG_SUFFIX}.a"
+ "-static${MIX_DEBUG_SUFFIX}.lib"
+ "${MIX_DEBUG_SUFFIX}.a"
+ "${MIX_DEBUG_SUFFIX}.lib"
+ "-static.a"
+ "-static.lib"
+ ".a"
+ ".lib"
+ "${MIX_DEBUG_SUFFIX}.dll.a"
+ "${MIX_DEBUG_SUFFIX}.dll.lib"
+ ".dll.a"
+ ".dll.lib"
+ "${MIX_DEBUG_SUFFIX}.so"
+ "${MIX_DEBUG_SUFFIX}.dylib"
+ ".so"
+ ".dylib"
+)
+
+set(FIND_PREFER_SHARED
+ "${MIX_DEBUG_SUFFIX}.dll.a"
+ "${MIX_DEBUG_SUFFIX}.dll.lib"
+ ".dll.a"
+ ".dll.lib"
+ "${MIX_DEBUG_SUFFIX}.so"
+ "${MIX_DEBUG_SUFFIX}.dylib"
+ ".so"
+ ".dylib"
+ "-static${MIX_DEBUG_SUFFIX}.a"
+ "-static${MIX_DEBUG_SUFFIX}.lib"
+ "${MIX_DEBUG_SUFFIX}.a"
+ "${MIX_DEBUG_SUFFIX}.lib"
+ "-static.a"
+ "-static.lib"
+ ".a"
+ ".lib"
+)
+
+if(AUDIO_CODECS_REPO_PATH OR AUDIO_CODECS_INSTALL_PATH)
+ set(AUDIO_CODECS_PATH ${AUDIO_CODECS_REPO_PATH})
+ set(AUDIO_CODECS_INSTALL_DIR ${AUDIO_CODECS_INSTALL_PATH})
+ set(SDL2_REPO_PATH ${AUDIO_CODECS_INSTALL_DIR})
+ set(SDL2_INCLUDE_PATH ${AUDIO_CODECS_INSTALL_DIR}/include/SDL2)
+ link_directories(${AUDIO_CODECS_INSTALL_DIR}/lib)
+ list(APPEND SDL_MIXER_INCLUDE_PATHS ${AUDIO_CODECS_INSTALL_DIR}/include ${SDL2_INCLUDE_PATH})
+ message("AudioCodecs will be used. No needed extra libraries installed in the system.")
+ set(USE_SYSTEM_AUDIO_LIBRARIES 0)
+ set(CMAKE_FIND_LIBRARY_SUFFIXES ${FIND_PREFER_STATIC})
+else()
+ message("AudioCodecs will NOT be used. Libraries will be recognized in the system.")
+ set(USE_SYSTEM_AUDIO_LIBRARIES 1)
+endif()
+
+add_definitions(-DHAVE_INTTYPES_H -DHAVE_SETENV -DHAVE_SINF)
+add_definitions(-Dmain=SDL_main -DPIC -D_REENTRANT -D_USE_MATH_DEFINES)
+
+set(SDLMixerX_SOURCES)
+set(SDLMixerX_LINK_LIBS)
+
+# Recognize SDL2 library from the system
+if(USE_SYSTEM_AUDIO_LIBRARIES)
+ find_package(PkgConfig)
+ pkg_check_modules(SDL2 REQUIRED sdl2)
+ list(APPEND SDL_MIXER_INCLUDE_PATHS ${SDL2_INCLUDE_DIRS})
+ list(APPEND SDLMixerX_LINK_LIBS ${SDL2_LIBRARIES})
+ message("== SDL2: ${SDL2_INCLUDE_DIRS} ${SDL2_LIBRARIES} ==")
+endif()
+
+option(USE_WAV "Build with WAV codec" ON)
+if(USE_WAV)
+ add_definitions(-DMUSIC_WAV)
+ list(APPEND SDLMixerX_SOURCES
+ ${SDLMixerX_SOURCE_DIR}/src/codecs/load_aiff.c
+ ${SDLMixerX_SOURCE_DIR}/src/codecs/load_voc.c
+ ${SDLMixerX_SOURCE_DIR}/src/codecs/music_wav.c)
+endif()
+
+option(USE_OGG_VORBIS "Build with OGG Vorbis codec" ON)
+if(USE_OGG_VORBIS)
+ if(USE_SYSTEM_AUDIO_LIBRARIES)
+ check_library_exists(vorbisfile ov_open "vorbis/vorbisfile.h" FOUND_VORBIS)
+ find_path(LIBVORBIS_INCLUDE_DIR vorbis/codec.h)
+ find_library(LIBVORBISFILE_LIB NAMES vorbisfile)
+ find_library(LIBVORBIS_LIB NAMES vorbis)
+ message("Vorbis: ${LIBVORBIS_INCLUDE_DIR} ${LIBVORBIS_LIB}")
+ else()
+ set(FOUND_VORBIS 1)
+ if(DOWNLOAD_AUDIO_CODECS_DEPENDENCY)
+ set(LIBVORBISFILE_LIB vorbisfile)
+ set(LIBVORBIS_LIB vorbis)
+ else()
+ find_library(LIBVORBISFILE_LIB NAMES vorbisfile
+ HINTS "${AUDIO_CODECS_INSTALL_PATH}/lib")
+ find_library(LIBVORBIS_LIB NAMES vorbis
+ HINTS "${AUDIO_CODECS_INSTALL_PATH}/lib")
+ endif()
+ endif()
+ if(FOUND_VORBIS)
+ message("== using Vorbis ==")
+ add_definitions(-DMUSIC_OGG)
+ list(APPEND SDL_MIXER_INCLUDE_PATHS
+ ${AUDIO_CODECS_PATH}/libogg/include
+ ${AUDIO_CODECS_PATH}/libvorbis/include
+ )
+ list(APPEND SDLMixerX_LINK_LIBS ${LIBVORBISFILE_LIB} ${LIBVORBIS_LIB})
+ set(LIBOGG_NEEDED ON)
+ list(APPEND SDLMixerX_SOURCES
+ ${SDLMixerX_SOURCE_DIR}/src/codecs/music_ogg.c)
+ endif()
+endif()
+
+option(USE_OPUS "Build with OPUS codec" ON)
+if(USE_OPUS)
+ if(USE_SYSTEM_AUDIO_LIBRARIES)
+ check_library_exists(opusfile op_open_file "opus/opusfile.h" FOUND_OPUS)
+ find_path(LIBOPUS_INCLUDE_DIR opus/opusfile.h)
+ find_library(LIBOPUSFILE_LIB NAMES opusfile)
+ find_library(LIBOPUS_LIB NAMES opusfile)
+ message("Opus: ${LIBOPUS_INCLUDE_DIR} ${LIBOPUSFILE_LIB} ${LIBOPUS_LIB}")
+ else()
+ set(FOUND_OPUS 1)
+ if(DOWNLOAD_AUDIO_CODECS_DEPENDENCY)
+ set(LIBOPUSFILE_LIB opusfile)
+ set(LIBOPUS_LIB opus)
+ else()
+ find_library(LIBOPUSFILE_LIB NAMES opusfile
+ HINTS "${AUDIO_CODECS_INSTALL_PATH}/lib")
+ find_library(LIBOPUS_LIB NAMES opus
+ HINTS "${AUDIO_CODECS_INSTALL_PATH}/lib")
+ endif()
+ endif()
+ if(FOUND_OPUS)
+ message("== using Opus ==")
+ add_definitions(-DMUSIC_OPUS)
+ if(AUDIO_CODECS_REPO_PATH)
+ list(APPEND SDL_MIXER_INCLUDE_PATHS
+ ${AUDIO_CODECS_PATH}/libogg/include
+ ${AUDIO_CODECS_PATH}/libopus/include
+ ${AUDIO_CODECS_PATH}/libopusfile/include
+ )
+ endif()
+ if(AUDIO_CODECS_INSTALL_DIR)
+ list(APPEND SDL_MIXER_INCLUDE_PATHS ${AUDIO_CODECS_INSTALL_DIR}/include/opus)
+ endif()
+ list(APPEND SDLMixerX_LINK_LIBS ${LIBOPUSFILE_LIB} ${LIBOPUS_LIB})
+ set(LIBOGG_NEEDED ON)
+ list(APPEND SDLMixerX_SOURCES
+ ${SDLMixerX_SOURCE_DIR}/src/codecs/music_opus.c)
+ endif()
+endif()
+
+option(USE_FLAC "Build with FLAC codec" ON)
+if(USE_FLAC)
+ if(USE_SYSTEM_AUDIO_LIBRARIES)
+ check_library_exists(FLAC FLAC__format_sample_rate_is_valid "FLAC/format.h" FOUND_FLAC)
+ find_path(LIBFLAC_INCLUDE_DIR "FLAC/all.h")
+ find_library(LIBFLAC_LIB NAMES FLAC)
+ message("FLAC: ${LIBFLAC_INCLUDE_DIR} ${LIBFLAC_LIB}")
+ else()
+ set(FOUND_FLAC 1)
+ if(DOWNLOAD_AUDIO_CODECS_DEPENDENCY)
+ set(LIBFLAC_LIB FLAC)
+ else()
+ find_library(LIBFLAC_LIB NAMES FLAC
+ HINTS "${AUDIO_CODECS_INSTALL_PATH}/lib")
+ endif()
+ endif()
+ if(FOUND_FLAC)
+ message("== using FLAC ==")
+ add_definitions(-DMUSIC_FLAC -DFLAC__NO_DLL)
+ if(AUDIO_CODECS_REPO_PATH)
+ list(APPEND SDL_MIXER_INCLUDE_PATHS
+ ${AUDIO_CODECS_PATH}/libogg/include
+ ${AUDIO_CODECS_PATH}/libFLAC/include
+ )
+ endif()
+ set(LIBOGG_NEEDED ON)
+ list(APPEND SDLMixerX_LINK_LIBS ${LIBFLAC_LIB})
+ list(APPEND SDLMixerX_SOURCES
+ ${SDLMixerX_SOURCE_DIR}/src/codecs/music_flac.c)
+ endif()
+endif()
+
+if(LIBOGG_NEEDED)
+ if(USE_SYSTEM_AUDIO_LIBRARIES)
+ find_library(LIBOGG_LIB NAMES ogg)
+ else()
+ if(DOWNLOAD_AUDIO_CODECS_DEPENDENCY)
+ set(LIBOGG_LIB ogg)
+ else()
+ find_library(LIBOGG_LIB NAMES ogg
+ HINTS "${AUDIO_CODECS_INSTALL_PATH}/lib")
+ endif()
+ endif()
+ list(APPEND SDLMixerX_LINK_LIBS ${LIBOGG_LIB})
+endif()
+
+option(USE_MP3_ID3TAG "Build with MP3 Meta tags support provided by libID3Tag library" ON)
+if(USE_MP3_ID3TAG AND NOT USE_SYSTEM_AUDIO_LIBRARIES)
+ message("== using ID3Tag (custom) ==")
+ add_definitions(-DMUSIC_MP3_ID3TAG)
+ if(AUDIO_CODECS_REPO_PATH)
+ list(APPEND SDL_MIXER_INCLUDE_PATHS ${AUDIO_CODECS_PATH}/libid3tag/include)
+ endif()
+ if(DOWNLOAD_AUDIO_CODECS_DEPENDENCY)
+ set(LIBID3TAG_LIB id3tag)
+ else()
+ find_library(LIBID3TAG_LIB NAMES id3tag
+ HINTS "${AUDIO_CODECS_INSTALL_PATH}/lib")
+ endif()
+ list(APPEND SDLMixerX_LINK_LIBS ${LIBID3TAG_LIB})
+endif()
+
+option(USE_MP3_MAD "Build with MAD MP3 codec" ON)
+option(USE_MP3_MAD_GPL_DITHERING "Enable GPL-Licensed dithering functions for MAD library" ON)
+if(USE_MP3_MAD)
+ if(USE_SYSTEM_AUDIO_LIBRARIES)
+ check_library_exists(mad mad_frame_init "mad.h" FOUND_MAD)
+ find_path(LIBMAD_INCLUDE_DIR "FLAC/all.h")
+ find_library(LIBMAD_LIB NAMES mad)
+ message("MAD: ${LIBMAD_INCLUDE_DIR} ${LIBMAD_LIB}")
+ else()
+ set(FOUND_MAD 1)
+ if(DOWNLOAD_AUDIO_CODECS_DEPENDENCY)
+ set(LIBMAD_LIB mad)
+ else()
+ find_library(LIBMAD_LIB NAMES mad
+ HINTS "${AUDIO_CODECS_INSTALL_PATH}/lib")
+ endif()
+ endif()
+ if(FOUND_MAD)
+ message("== using MAD ==")
+ add_definitions(-DMUSIC_MP3_MAD)
+ if(USE_MP3_MAD_GPL_DITHERING)
+ add_definitions(-DMUSIC_MP3_MAD_GPL_DITHERING)
+ endif()
+ list(APPEND SDLMixerX_LINK_LIBS ${LIBMAD_LIB})
+ if(AUDIO_CODECS_REPO_PATH)
+ list(APPEND SDL_MIXER_INCLUDE_PATHS ${AUDIO_CODECS_PATH}/libmad/include)
+ endif()
+ list(APPEND SDLMixerX_SOURCES
+ ${SDLMixerX_SOURCE_DIR}/src/codecs/music_mad.c)
+ endif()
+endif()
+
+option(USE_MP3_SMPEG "Build with SMPEG MP3 codec" OFF)
+if(USE_MP3_SMPEG)
+ if(USE_SYSTEM_AUDIO_LIBRARIES)
+ check_library_exists(smpeg SMPEG_new "smpeg/smpeg.h" FOUND_SMPEG)
+ find_path(LIBSMPEG_INCLUDE_DIR "smpeg/smpeg.h")
+ find_library(LIBSMPEG_LIB NAMES smpeg)
+ message("SMPEG: ${LIBSMPEG_INCLUDE_DIR} ${LIBSMPEG_LIB}")
+ else()
+ set(FOUND_SMPEG 1)
+ if(DOWNLOAD_AUDIO_CODECS_DEPENDENCY)
+ set(LIBSMPEG_LIB smpeg)
+ else()
+ find_library(LIBSMPEG_LIB NAMES smpeg
+ HINTS "${AUDIO_CODECS_INSTALL_PATH}/lib")
+ endif()
+ endif()
+ if(FOUND_SMPEG)
+ message("== using SMPEG ==")
+ add_definitions(-DMUSIC_MP3_SMPEG)
+ list(APPEND SDLMixerX_LINK_LIBS ${LIBSMPEG_LIB})
+ if(AUDIO_CODECS_REPO_PATH)
+ list(APPEND SDL_MIXER_INCLUDE_PATHS ${AUDIO_CODECS_PATH}/smpeg/include)
+ endif()
+ list(APPEND SDLMixerX_SOURCES
+ ${SDLMixerX_SOURCE_DIR}/src/codecs/music_smpeg.c)
+ endif()
+endif()
+
+option(USE_MP3_MPG123 "[WIP, DON'T USE IT] Build with MPG123 MP3 codec" OFF)
+if(USE_MP3_MPG123)
+ add_definitions(-DMUSIC_MP3_MPG123)
+
+ message(WARNING "MPG123 SUPPORT IS WIP, DON'T USE IT IN PRODUCTION!!!")
+ # ======= Until AudioCodecs will receive buildable mpg123, detect it externally =======
+ include(cmake/FindMpg123.cmake)
+
+ if(NOT MPG123_FOUND)
+ message(FATAL_ERROR "MPG123 is not found!")
+ else()
+ message("MPG123 found in ${MPG123_INCLUDE_DIR} folder")
+ endif()
+
+ list(APPEND SDL_MIXER_INCLUDE_PATHS ${MPG123_INCLUDE_DIRS})
+ set(LIBS ${LIBS} ${MPG123_LIBRARIES})
+ list(APPEND SDLMixerX_LINK_LIBS mpg123)
+ list(APPEND SDLMixerX_SOURCES
+ ${SDLMixerX_SOURCE_DIR}/src/codecs/music_mpg123.c)
+endif()
+
+if(USE_MP3_MAD OR USE_MP3_MPG123 OR USE_MP3_SMPEG)
+ list(APPEND SDLMixerX_SOURCES
+ ${SDLMixerX_SOURCE_DIR}/src/codecs/music_id3tag.c)
+endif()
+
+option(USE_MODPLUG "Build with ModPlug library" ON)
+if(USE_MODPLUG)
+ if(USE_SYSTEM_AUDIO_LIBRARIES)
+ check_library_exists(modplug ModPlug_Load "libmodplug/modplug.h" FOUND_MODPLUG)
+ find_path(LIBMODPLUG_INCLUDE_DIR libmodplug/modplug.h)
+ find_library(LIBMODPLUG_LIB NAMES modplug)
+ message("ModPlug: ${LIBMODPLUG_INCLUDE_DIR} ${LIBMODPLUG_LIB}")
+ else()
+ set(FOUND_MODPLUG 1)
+ if(DOWNLOAD_AUDIO_CODECS_DEPENDENCY)
+ set(LIBMODPLUG_LIB modplug)
+ else()
+ find_library(LIBMODPLUG_LIB NAMES modplug
+ HINTS "${AUDIO_CODECS_INSTALL_PATH}/lib")
+ endif()
+ endif()
+ if(FOUND_MODPLUG)
+ message("== using libModPlug ==")
+ add_definitions(-DMUSIC_MOD_MODPLUG -DMODPLUG_STATIC)
+ if(AUDIO_CODECS_REPO_PATH)
+ list(APPEND SDL_MIXER_INCLUDE_PATHS ${AUDIO_CODECS_PATH}/libmodplug/include)
+ endif()
+ list(APPEND SDLMixerX_LINK_LIBS ${LIBMODPLUG_LIB})
+ list(APPEND SDLMixerX_SOURCES
+ ${SDLMixerX_SOURCE_DIR}/src/codecs/music_modplug.c)
+ endif()
+endif()
+
+option(USE_MIKMOD "Build with MikMod library" OFF)
+if(USE_MIKMOD)
+ if(USE_SYSTEM_AUDIO_LIBRARIES)
+ check_library_exists(mikmod Player_Load "mikmod.h" FOUND_MIKMOD)
+ find_path(LIBMIKMOD_INCLUDE_DIR "mikmod.h")
+ find_library(LIBMIKMOD_LIB NAMES mikmod)
+ message("MikMod: ${LIBMIKMOD_INCLUDE_DIR} ${LIBMIKMOD_LIB}")
+ else()
+ set(FOUND_MIKMOD 1)
+ if(DOWNLOAD_AUDIO_CODECS_DEPENDENCY)
+ set(LIBMIKMOD_LIB mikmod)
+ else()
+ find_library(LIBMIKMOD_LIB NAMES mikmod
+ HINTS "${AUDIO_CODECS_INSTALL_PATH}/lib")
+ endif()
+ endif()
+ if(FOUND_MIKMOD)
+ message("== using MikMod ==")
+ add_definitions(-DMUSIC_MOD_MIKMOD)
+ if(AUDIO_CODECS_REPO_PATH)
+ list(APPEND SDL_MIXER_INCLUDE_PATHS ${AUDIO_CODECS_PATH}/libmikmod/include)
+ endif()
+ list(APPEND SDLMixerX_LINK_LIBS ${LIBMIKMOD_LIB})
+ list(APPEND SDLMixerX_SOURCES
+ ${SDLMixerX_SOURCE_DIR}/src/codecs/music_mikmod.c)
+ endif()
+endif()
+
+option(USE_GME "Build with Game Music Emulators library" ON)
+if(USE_GME)
+ if(USE_SYSTEM_AUDIO_LIBRARIES)
+ check_library_exists(gme gme_load_file "gme.h" FOUND_GME)
+ find_path(LIBGME_INCLUDE_DIR "gme.h")
+ find_library(LIBGME_LIB NAMES gme)
+ find_library(LIBZLIB_LIB NAMES z zlib)
+ message("GME: ${LIBGME_INCLUDE_DIR} ${LIBGME_LIB}")
+ else()
+ set(FOUND_GME 1)
+ if(DOWNLOAD_AUDIO_CODECS_DEPENDENCY)
+ set(LIBGME_LIB gme)
+ set(LIBZLIB_LIB zlib)
+ else()
+ find_library(LIBGME_LIB NAMES gme
+ HINTS "${AUDIO_CODECS_INSTALL_PATH}/lib")
+ find_library(LIBZLIB_LIB NAMES zlib z
+ HINTS "${AUDIO_CODECS_INSTALL_PATH}/lib")
+ endif()
+ endif()
+ if(FOUND_GME)
+ message("== using GME ==")
+ add_definitions(-DMUSIC_GME)
+ if(AUDIO_CODECS_REPO_PATH)
+ list(APPEND SDL_MIXER_INCLUDE_PATHS ${AUDIO_CODECS_PATH}/libgme/include)
+ list(APPEND SDL_MIXER_INCLUDE_PATHS ${AUDIO_CODECS_PATH}/zlib/include)
+ endif()
+ list(APPEND SDLMixerX_LINK_LIBS ${LIBGME_LIB} ${LIBZLIB_LIB})
+ list(APPEND SDLMixerX_SOURCES
+ ${SDLMixerX_SOURCE_DIR}/src/codecs/music_gme.c)
+ endif()
+endif()
+
+if(NOT WIN32) # CMD Music is not supported on Windows
+ option(USE_CMD "Build with CMD music player support" ON)
+ if(USE_CMD)
+ message("== using CMD Music ==")
+ add_definitions(-DMUSIC_CMD -D_POSIX_C_SOURCE=1)
+ CHECK_FUNCTION_EXISTS(fork HAVE_FORK)
+ if(HAVE_FORK)
+ add_definitions(-DHAVE_FORK)
+ endif()
+ list(APPEND SDLMixerX_SOURCES
+ ${SDLMixerX_SOURCE_DIR}/src/codecs/music_cmd.c)
+ endif()
+endif()
+
+option(USE_MIDI "Build with MIDI support" ON)
+if(USE_MIDI)
+
+ option(USE_MIDI_ADLMIDI "Build with libADLMIDI OPL3 Emulator based MIDI sequencer support" ON)
+ if(USE_MIDI_ADLMIDI)
+ if(USE_SYSTEM_AUDIO_LIBRARIES)
+ check_library_exists(ADLMIDI adl_init "adlmidi.h" FOUND_ADLMIDI)
+ find_path(LIBADLMIDI_INCLUDE_DIR "adlmidi.h")
+ find_library(LIBADLMIDI_LIB NAMES ADLMIDI)
+ message("ADLMIDI: ${LIBADLMIDI_INCLUDE_DIR} ${LIBADLMIDI_LIB}")
+ else()
+ set(FOUND_ADLMIDI 1)
+ if(DOWNLOAD_AUDIO_CODECS_DEPENDENCY)
+ set(LIBADLMIDI_LIB ADLMIDI)
+ else()
+ find_library(LIBADLMIDI_LIB NAMES ADLMIDI
+ HINTS "${AUDIO_CODECS_INSTALL_PATH}/lib")
+ endif()
+ endif()
+ if(FOUND_ADLMIDI)
+ message("== using ADLMIDI ==")
+ add_definitions(-DMUSIC_MID_ADLMIDI)
+ if(AUDIO_CODECS_REPO_PATH)
+ list(APPEND SDL_MIXER_INCLUDE_PATHS ${AUDIO_CODECS_PATH}/libADLMIDI/include)
+ endif()
+ set(LIBMATH_NEEDED 1)
+ list(APPEND SDLMixerX_LINK_LIBS ${LIBADLMIDI_LIB})
+ list(APPEND SDLMixerX_SOURCES
+ ${SDLMixerX_SOURCE_DIR}/src/codecs/music_midi_adl.c)
+ endif()
+ endif()
+
+ option(USE_MIDI_OPNMIDI "Build with libOPNMIDI OPN2 Emulator based MIDI sequencer support" ON)
+ if(USE_MIDI_OPNMIDI)
+ if(USE_SYSTEM_AUDIO_LIBRARIES)
+ check_library_exists(OPNMIDI opn_init "opnmidi.h" FOUND_OPNMIDI)
+ find_path(LIBOPNMIDI_INCLUDE_DIR "opnmidi.h")
+ find_library(LIBOPNMIDI_LIB NAMES OPNMIDI)
+ message("OPNMIDI: ${LIBOPNMIDI_INCLUDE_DIR} ${LIBOPNMIDI_LIB}")
+ else()
+ set(FOUND_OPNMIDI 1)
+ if(DOWNLOAD_AUDIO_CODECS_DEPENDENCY)
+ set(LIBOPNMIDI_LIB OPNMIDI)
+ else()
+ find_library(LIBOPNMIDI_LIB NAMES OPNMIDI
+ HINTS "${AUDIO_CODECS_INSTALL_PATH}/lib")
+ endif()
+ endif()
+ if(FOUND_OPNMIDI)
+ message("== using OPNMIDI ==")
+ add_definitions(-DMUSIC_MID_OPNMIDI)
+ if(AUDIO_CODECS_REPO_PATH)
+ list(APPEND SDL_MIXER_INCLUDE_PATHS ${AUDIO_CODECS_PATH}/libOPNMIDI/include)
+ endif()
+ set(LIBMATH_NEEDED 1)
+ list(APPEND SDLMixerX_LINK_LIBS ${LIBOPNMIDI_LIB})
+ list(APPEND SDLMixerX_SOURCES
+ ${SDLMixerX_SOURCE_DIR}/src/codecs/music_midi_opn.c)
+ endif()
+ endif()
+
+ option(USE_MIDI_TIMIDITY "Build with Timidity wave table MIDI sequencer support" ON)
+ if(USE_MIDI_TIMIDITY AND NOT USE_SYSTEM_AUDIO_LIBRARIES)
+ message("== using Timidity (custom) ==")
+ add_definitions(-DMUSIC_MID_TIMIDITY)
+ if(AUDIO_CODECS_REPO_PATH)
+ list(APPEND SDL_MIXER_INCLUDE_PATHS ${AUDIO_CODECS_PATH}/libtimidity/include)
+ endif()
+ if(DOWNLOAD_AUDIO_CODECS_DEPENDENCY)
+ set(LIBTIMIDITY_LIB timidity)
+ else()
+ find_library(LIBTIMIDITY_LIB NAMES timidity
+ HINTS "${AUDIO_CODECS_INSTALL_PATH}/lib")
+ endif()
+ list(APPEND SDLMixerX_LINK_LIBS ${LIBTIMIDITY_LIB})
+ list(APPEND SDLMixerX_SOURCES
+ ${SDLMixerX_SOURCE_DIR}/src/codecs/music_timidity.c)
+ endif()
+
+ option(USE_MIDI_FLUIDSYNTH "Build with FluidSynth wave table MIDI sequencer support" OFF)
+ if(USE_MIDI_FLUIDSYNTH)
+ if(USE_SYSTEM_AUDIO_LIBRARIES)
+ check_library_exists(fluidsynth new_fluid_midi_router "fluidsynth.h" FOUND_FLUIDSYNTH)
+ find_path(LIBFLUIDSYNTH_INCLUDE_DIR "fluidsynth.h")
+ find_library(LIBFLUIDSYNTH_LIB NAMES fluidsynth)
+ message("FluidSynth: ${LIBFLUIDSYNTH_INCLUDE_DIR} ${LIBFLUIDSYNTH_LIB}")
+ else()
+ set(FOUND_FLUIDSYNTH 1)
+ if(DOWNLOAD_AUDIO_CODECS_DEPENDENCY)
+ set(LIBFLUIDSYNTH_LIB fluidsynth)
+ else()
+ find_library(LIBFLUIDSYNTH_LIB NAMES fluidsynth
+ HINTS "${AUDIO_CODECS_INSTALL_PATH}/lib")
+ endif()
+ endif()
+ if(FOUND_FLUIDSYNTH)
+ message("== using FluidSynth ==")
+ add_definitions(-DMUSIC_MID_FLUIDSYNTH)
+ if(AUDIO_CODECS_REPO_PATH)
+ list(APPEND SDL_MIXER_INCLUDE_PATHS ${AUDIO_CODECS_PATH}/FluidLite/include)
+ endif()
+ list(APPEND SDLMixerX_LINK_LIBS ${LIBFLUIDSYNTH_LIB})
+ list(APPEND SDLMixerX_SOURCES
+ ${SDLMixerX_SOURCE_DIR}/src/codecs/music_fluidsynth.c)
+ endif()
+ endif()
+
+ # Native MIDI correctly works on Windows and macOS only.
+ if(WIN32 OR APPLE)
+ set(NATIVE_MIDI_SUPPORTED ON)
+ else()
+ set(NATIVE_MIDI_SUPPORTED OFF)
+ endif()
+
+ option(USE_MIDI_NATIVE "Build with operating system native MIDI output support" ${NATIVE_MIDI_SUPPORTED})
+ if(USE_MIDI_NATIVE)
+ add_definitions(-DMUSIC_MID_NATIVE)
+ list(APPEND SDLMixerX_SOURCES
+ ${SDLMixerX_SOURCE_DIR}/src/codecs/music_nativemidi.c
+ ${SDLMixerX_SOURCE_DIR}/src/codecs/native_midi/native_midi_common.c)
+ if(WIN32)
+ list(APPEND SDLMixerX_SOURCES
+ ${SDLMixerX_SOURCE_DIR}/src/codecs/native_midi/native_midi_win32.c)
+ list(APPEND SDLMixerX_LINK_LIBS winmm)
+ endif()
+ if(APPLE)
+ list(APPEND SDLMixerX_SOURCES
+ ${SDLMixerX_SOURCE_DIR}/src/codecs/native_midi/native_midi_macosx.c)
+ endif()
+ endif()
+ if(NOT USE_MIDI_ADLMIDI AND
+ NOT USE_MIDI_OPNMIDI AND
+ NOT USE_MIDI_TIMIDITY AND
+ NOT USE_MIDI_FLUIDSYNTH AND
+ NOT USE_MIDI_NATIVE)
+ message_error("To have MIDI support you must enable at least one MIDI sequencer library")
+ endif()
+
+endif()
+
+if(USE_SYSTEM_AUDIO_LIBRARIES)
+ find_library(LIBSDL2CUSTOM_LIB NAMES SDL2)
+else()
+ if(DOWNLOAD_AUDIO_CODECS_DEPENDENCY)
+ set(LIBSDL2CUSTOM_LIB SDL2$<$:d>)
+ else()
+ set(CMAKE_FIND_LIBRARY_SUFFIXES ${FIND_PREFER_SHARED})
+ find_library(LIBSDL2CUSTOM_LIB NAMES SDL2
+ HINTS "${AUDIO_CODECS_INSTALL_PATH}/lib")
+ endif()
+endif()
+list(APPEND SDLMixerX_LINK_LIBS ${LIBSDL2CUSTOM_LIB})
+
+if(LIBMATH_NEEDED AND NOT MSVC)
+ list(APPEND SDLMixerX_LINK_LIBS m)
+endif()
+
+if(WIN32)
+ option(BUILD_AS_VB6_BINDING "Compile library into solid module compatible with VisualBasic 6" OFF)
+ if(BUILD_AS_VB6_BINDING)
+ message("== SDL Mixer X will be built as solid module that is ready for MS-VB6 binding! ==")
+ list(APPEND SDLMixerX_SOURCES ${SDLMixerX_SOURCE_DIR}/src/vb6_binding/vb6_sdl_binds.c)
+ list(REMOVE_ITEM SDLMixerX_LINK_LIBS SDL2)
+ list(REMOVE_ITEM SDLMixerX_LINK_LIBS SDL2$<$:d>)
+ list(APPEND SDLMixerX_LINK_LIBS
+ SDL2-static
+ uuid winmm ole32 imm32 version oleaut32 user32 gdi32)
+ if(NOT MSVC)
+ list(APPEND SDLMixerX_LINK_LIBS stdc++ gcc pthread)
+ endif()
+ endif()
+endif()
+
+if(APPLE)
+ find_library(APPLE_CORE_AUDIO CoreAudio)
+ find_library(APPLE_IOKIT IOKit)
+ find_library(APPLE_COCOA Cocoa)
+ find_library(APPLE_AUDIOTOOLBOX AudioToolbox)
+ find_library(APPLE_CORE_VIDEO CoreVideo)
+ find_library(APPLE_CORE_FOUNDATION CoreFoundation)
+ find_library(APPLE_CARBON Carbon)
+ find_library(APPLE_FORCE_FEEDBACK ForceFeedback)
+ find_library(ICONV_LIB iconv)
+ list(APPEND SDLMixerX_LINK_LIBS
+ ${APPLE_CORE_AUDIO}
+ ${APPLE_COCOA}
+ ${APPLE_CORE_VIDEO}
+ ${APPLE_CORE_FOUNDATION}
+ ${APPLE_FORCE_FEEDBACK}
+ ${APPLE_IOKIT}
+ ${APPLE_CARBON}
+ ${APPLE_AUDIOTOOLBOX}
+ ${ICONV_LIB})
+ list(APPEND SDLMixerX_LINK_LIBS objc)
+endif()
+
+if(NOT MSVC)
+ list(APPEND SDLMixerX_LINK_LIBS stdc++)
+endif()
+
+list(APPEND SDLMixerX_SOURCES
+ ${SDLMixerX_SOURCE_DIR}/src/effect_position.c
+ ${SDLMixerX_SOURCE_DIR}/src/effects_internal.c
+ ${SDLMixerX_SOURCE_DIR}/src/effect_stereoreverse.c
+ ${SDLMixerX_SOURCE_DIR}/src/mixer.c
+ ${SDLMixerX_SOURCE_DIR}/src/music.c
+ ${SDLMixerX_SOURCE_DIR}/src/mixer_x_deprecated.c
+ )
+
+file(GLOB SDLMixerX_SOURCES ${SDLMixerX_SOURCES})
+
+set(SDLMixerX_INSTALLS)
+
+if(SDL_MIXER_X_STATIC AND NOT BUILD_AS_VB6_BINDING)
+ add_library(SDL2_mixer_ext_Static STATIC ${SDLMixerX_SOURCES})
+ if(WIN32)
+ set_target_properties(SDL2_mixer_ext_Static PROPERTIES OUTPUT_NAME SDL2_mixer_ext-static)
+ else()
+ set_target_properties(SDL2_mixer_ext_Static PROPERTIES OUTPUT_NAME SDL2_mixer_ext)
+ endif()
+ target_include_directories(SDL2_mixer_ext_Static PRIVATE
+ ${SDLMixerX_SOURCE_DIR}/include/SDL_mixer_ext
+ ${SDLMixerX_SOURCE_DIR}/src
+ ${SDLMixerX_SOURCE_DIR}/src/codecs
+ ${AUDIO_CODECS_INSTALL_DIR}/include/SDL2
+ )
+ target_include_directories(SDL2_mixer_ext_Static PUBLIC
+ ${SDLMixerX_SOURCE_DIR}/include
+ ${SDL_MIXER_INCLUDE_PATHS}
+ )
+ if(DOWNLOAD_AUDIO_CODECS_DEPENDENCY AND AUDIO_CODECS_INSTALL_PATH)
+ add_dependencies(SDL2_mixer_ext_Static AudioCodecs)
+ endif()
+ set_target_properties(SDL2_mixer_ext_Static
+ PROPERTIES
+ ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib"
+ LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib"
+ RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin"
+ )
+ if(DOWNLOAD_AUDIO_CODECS_DEPENDENCY)
+ add_custom_command(
+ TARGET SDL2_mixer_ext_Static POST_BUILD
+ COMMAND ${CMAKE_COMMAND} -E copy
+ ${CMAKE_SOURCE_DIR}/include/SDL_mixer_ext/SDL_mixer_ext.h
+ ${AUDIO_CODECS_INSTALL_DIR}/include/SDL2)
+ endif()
+ list(APPEND SDLMixerX_INSTALLS SDL2_mixer_ext_Static)
+endif()
+
+if(WIN32)
+ list(APPEND SDLMixerX_SOURCES ${SDLMixerX_SOURCE_DIR}/version.rc)
+endif()
+
+if(SDL_MIXER_X_SHARED AND NOT BUILD_AS_VB6_BINDING)
+ add_library(SDL2_mixer_ext SHARED ${SDLMixerX_SOURCES})
+ target_link_libraries(SDL2_mixer_ext ${SDLMixerX_LINK_LIBS})
+ target_include_directories(SDL2_mixer_ext PRIVATE
+ ${SDLMixerX_SOURCE_DIR}/include/SDL_mixer_ext
+ ${SDLMixerX_SOURCE_DIR}/src
+ ${SDLMixerX_SOURCE_DIR}/src/codecs
+ ${AUDIO_CODECS_INSTALL_DIR}/include/SDL2
+ )
+ target_include_directories(SDL2_mixer_ext PUBLIC
+ ${SDLMixerX_SOURCE_DIR}/include
+ ${SDL_MIXER_INCLUDE_PATHS}
+ )
+ if(DOWNLOAD_AUDIO_CODECS_DEPENDENCY AND AUDIO_CODECS_INSTALL_PATH)
+ add_dependencies(SDL2_mixer_ext AudioCodecs)
+ endif()
+ set_target_properties(SDL2_mixer_ext
+ PROPERTIES
+ ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib"
+ LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib"
+ RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin"
+ )
+ if(DOWNLOAD_AUDIO_CODECS_DEPENDENCY)
+ add_custom_command(
+ TARGET SDL2_mixer_ext POST_BUILD
+ COMMAND ${CMAKE_COMMAND} -E copy
+ ${CMAKE_SOURCE_DIR}/include/SDL_mixer_ext/SDL_mixer_ext.h
+ ${AUDIO_CODECS_INSTALL_DIR}/include/SDL2)
+ endif()
+ list(APPEND SDLMixerX_INSTALLS SDL2_mixer_ext)
+endif()
+
+if(BUILD_AS_VB6_BINDING)
+ add_library(SDL2_mixer_ext_VB6 MODULE ${SDLMixerX_SOURCES})
+ set_target_properties(SDL2_mixer_ext_VB6 PROPERTIES OUTPUT_NAME SDL2MixerVB)
+ set_target_properties(SDL2_mixer_ext_VB6 PROPERTIES PREFIX "")
+ target_compile_definitions(SDL2_mixer_ext_VB6 PRIVATE -DFORCE_STDCALLS)
+ target_link_libraries(SDL2_mixer_ext_VB6 ${SDLMixerX_LINK_LIBS})
+ target_include_directories(SDL2_mixer_ext_VB6 PUBLIC
+ ${SDLMixerX_SOURCE_DIR}/include/SDL_mixer_ext
+ ${SDLMixerX_SOURCE_DIR}/src
+ ${SDLMixerX_SOURCE_DIR}/src/codecs
+ ${AUDIO_CODECS_INSTALL_DIR}/include/SDL2
+ )
+ target_include_directories(SDL2_mixer_ext_VB6 PUBLIC
+ ${SDLMixerX_SOURCE_DIR}/include
+ ${SDL_MIXER_INCLUDE_PATHS}
+ )
+ set_target_properties(SDL2_mixer_ext_VB6 PROPERTIES LINK_FLAGS
+ "-Wl,--add-stdcall-alias -static-libgcc -static-libstdc++ -static -lpthread")
+ if(DOWNLOAD_AUDIO_CODECS_DEPENDENCY AND AUDIO_CODECS_INSTALL_PATH)
+ add_dependencies(SDL2_mixer_ext_VB6 AudioCodecs)
+ endif()
+ set_target_properties(SDL2_mixer_ext_VB6
+ PROPERTIES
+ ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/sdl-mixer-vb6"
+ LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/sdl-mixer-vb6"
+ RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/sdl-mixer-vb6"
+ )
+ add_custom_command(
+ TARGET SDL2_mixer_ext_VB6 POST_BUILD
+ COMMAND ${CMAKE_COMMAND} -E copy
+ ${CMAKE_SOURCE_DIR}/VB6_Wrapper/modSDL2_mixer_ext_vb6.bas
+ ${CMAKE_BINARY_DIR}/sdl-mixer-vb6)
+ list(APPEND SDLMixerX_INSTALLS SDL2_mixer_ext_VB6)
+endif()
+
+install(TARGETS ${SDLMixerX_INSTALLS}
+ RUNTIME DESTINATION "bin"
+ LIBRARY DESTINATION "lib"
+ ARCHIVE DESTINATION "lib"
+ FRAMEWORK DESTINATION "lib"
+ INCLUDES DESTINATION "include")
+
+if(DOWNLOAD_AUDIO_CODECS_DEPENDENCY)
+ install(DIRECTORY ${AUDIO_CODECS_INSTALL_DIR}/bin
+ DESTINATION .)
+ install(DIRECTORY ${AUDIO_CODECS_INSTALL_DIR}/lib
+ DESTINATION .)
+ install(DIRECTORY ${AUDIO_CODECS_INSTALL_DIR}/include
+ DESTINATION .)
+endif()
+
+install(FILES
+ include/SDL_mixer_ext/begin_code.h
+ include/SDL_mixer_ext/close_code.h
+ include/SDL_mixer_ext/SDL_mixer_ext.h
+ DESTINATION include/SDL2)
+
diff --git a/libs/SDLMixerX/COPYING.txt b/libs/SDLMixerX/COPYING.txt
new file mode 100644
index 000000000..e8f8643f2
--- /dev/null
+++ b/libs/SDLMixerX/COPYING.txt
@@ -0,0 +1,24 @@
+/*
+ SDL Mixer X: An extended audio mixer library, forked from SDL_mixer
+ Copyright (C) 2014-2018 Vitaly Novichkov
+
+ SDL_mixer: An audio mixer library based on the SDL library
+ Copyright (C) 1997-2018 Sam Lantinga
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+
+*/
diff --git a/libs/SDLMixerX/GPLv2.txt b/libs/SDLMixerX/GPLv2.txt
new file mode 100644
index 000000000..1f963da0d
--- /dev/null
+++ b/libs/SDLMixerX/GPLv2.txt
@@ -0,0 +1,340 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Lesser General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+
+ Copyright (C)
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) year name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ , 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.
+
diff --git a/libs/SDLMixerX/GPLv3.txt b/libs/SDLMixerX/GPLv3.txt
new file mode 100644
index 000000000..10926e87f
--- /dev/null
+++ b/libs/SDLMixerX/GPLv3.txt
@@ -0,0 +1,675 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc.
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+ The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works. By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users. We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors. You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+ To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights. Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received. You must make sure that they, too, receive
+or can get the source code. And you must show them these terms so they
+know their rights.
+
+ Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+ For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software. For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+ Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so. This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software. The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable. Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products. If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+ Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary. To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ TERMS AND CONDITIONS
+
+ 0. Definitions.
+
+ "This License" refers to version 3 of the GNU General Public License.
+
+ "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+ "The Program" refers to any copyrightable work licensed under this
+License. Each licensee is addressed as "you". "Licensees" and
+"recipients" may be individuals or organizations.
+
+ To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy. The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+ A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+ To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy. Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+ To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies. Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+ An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License. If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+ 1. Source Code.
+
+ The "source code" for a work means the preferred form of the work
+for making modifications to it. "Object code" means any non-source
+form of a work.
+
+ A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+ The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form. A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+ The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities. However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work. For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+ The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+ The Corresponding Source for a work in source code form is that
+same work.
+
+ 2. Basic Permissions.
+
+ All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met. This License explicitly affirms your unlimited
+permission to run the unmodified Program. The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work. This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+ You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force. You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright. Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+ Conveying under any other circumstances is permitted solely under
+the conditions stated below. Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+ 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+ No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+ When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+ 4. Conveying Verbatim Copies.
+
+ You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+ You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+ 5. Conveying Modified Source Versions.
+
+ You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+ a) The work must carry prominent notices stating that you modified
+ it, and giving a relevant date.
+
+ b) The work must carry prominent notices stating that it is
+ released under this License and any conditions added under section
+ 7. This requirement modifies the requirement in section 4 to
+ "keep intact all notices".
+
+ c) You must license the entire work, as a whole, under this
+ License to anyone who comes into possession of a copy. This
+ License will therefore apply, along with any applicable section 7
+ additional terms, to the whole of the work, and all its parts,
+ regardless of how they are packaged. This License gives no
+ permission to license the work in any other way, but it does not
+ invalidate such permission if you have separately received it.
+
+ d) If the work has interactive user interfaces, each must display
+ Appropriate Legal Notices; however, if the Program has interactive
+ interfaces that do not display Appropriate Legal Notices, your
+ work need not make them do so.
+
+ A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit. Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+ 6. Conveying Non-Source Forms.
+
+ You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+ a) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by the
+ Corresponding Source fixed on a durable physical medium
+ customarily used for software interchange.
+
+ b) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by a
+ written offer, valid for at least three years and valid for as
+ long as you offer spare parts or customer support for that product
+ model, to give anyone who possesses the object code either (1) a
+ copy of the Corresponding Source for all the software in the
+ product that is covered by this License, on a durable physical
+ medium customarily used for software interchange, for a price no
+ more than your reasonable cost of physically performing this
+ conveying of source, or (2) access to copy the
+ Corresponding Source from a network server at no charge.
+
+ c) Convey individual copies of the object code with a copy of the
+ written offer to provide the Corresponding Source. This
+ alternative is allowed only occasionally and noncommercially, and
+ only if you received the object code with such an offer, in accord
+ with subsection 6b.
+
+ d) Convey the object code by offering access from a designated
+ place (gratis or for a charge), and offer equivalent access to the
+ Corresponding Source in the same way through the same place at no
+ further charge. You need not require recipients to copy the
+ Corresponding Source along with the object code. If the place to
+ copy the object code is a network server, the Corresponding Source
+ may be on a different server (operated by you or a third party)
+ that supports equivalent copying facilities, provided you maintain
+ clear directions next to the object code saying where to find the
+ Corresponding Source. Regardless of what server hosts the
+ Corresponding Source, you remain obligated to ensure that it is
+ available for as long as needed to satisfy these requirements.
+
+ e) Convey the object code using peer-to-peer transmission, provided
+ you inform other peers where the object code and Corresponding
+ Source of the work are being offered to the general public at no
+ charge under subsection 6d.
+
+ A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+ A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling. In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage. For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product. A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+ "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source. The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+ If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information. But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+ The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed. Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+ Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+ 7. Additional Terms.
+
+ "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law. If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+ When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it. (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.) You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+ Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+ a) Disclaiming warranty or limiting liability differently from the
+ terms of sections 15 and 16 of this License; or
+
+ b) Requiring preservation of specified reasonable legal notices or
+ author attributions in that material or in the Appropriate Legal
+ Notices displayed by works containing it; or
+
+ c) Prohibiting misrepresentation of the origin of that material, or
+ requiring that modified versions of such material be marked in
+ reasonable ways as different from the original version; or
+
+ d) Limiting the use for publicity purposes of names of licensors or
+ authors of the material; or
+
+ e) Declining to grant rights under trademark law for use of some
+ trade names, trademarks, or service marks; or
+
+ f) Requiring indemnification of licensors and authors of that
+ material by anyone who conveys the material (or modified versions of
+ it) with contractual assumptions of liability to the recipient, for
+ any liability that these contractual assumptions directly impose on
+ those licensors and authors.
+
+ All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10. If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term. If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+ If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+ Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+ 8. Termination.
+
+ You may not propagate or modify a covered work except as expressly
+provided under this License. Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+ However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+ Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+ Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License. If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+ 9. Acceptance Not Required for Having Copies.
+
+ You are not required to accept this License in order to receive or
+run a copy of the Program. Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance. However,
+nothing other than this License grants you permission to propagate or
+modify any covered work. These actions infringe copyright if you do
+not accept this License. Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+ 10. Automatic Licensing of Downstream Recipients.
+
+ Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License. You are not responsible
+for enforcing compliance by third parties with this License.
+
+ An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations. If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+ You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License. For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+ 11. Patents.
+
+ A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based. The
+work thus licensed is called the contributor's "contributor version".
+
+ A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version. For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+ Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+ In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement). To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+ If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients. "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+ If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+ A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License. You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+ Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+ 12. No Surrender of Others' Freedom.
+
+ If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all. For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+ 13. Use with the GNU Affero General Public License.
+
+ Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work. The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+ 14. Revised Versions of this License.
+
+ The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation. If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+ If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+ Later license versions may give you additional or different
+permissions. However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+ 15. Disclaimer of Warranty.
+
+ THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. Limitation of Liability.
+
+ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+ 17. Interpretation of Sections 15 and 16.
+
+ If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+
+ Copyright (C)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+
+Also add information on how to contact you by electronic and paper mail.
+
+ If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+ Copyright (C)
+ This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+ You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+.
+
+ The GNU General Public License does not permit incorporating your program
+into proprietary programs. If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License. But first, please read
+.
+
diff --git a/libs/SDLMixerX/README.txt b/libs/SDLMixerX/README.txt
new file mode 100644
index 000000000..998e0d9d3
--- /dev/null
+++ b/libs/SDLMixerX/README.txt
@@ -0,0 +1,248 @@
+SDL Mixer X (aka SDL Mixer 2.0 Modded or SDL_mixer_ext),
+by Vitaly Novichkov ,
+forked from SDL Mixer 2.0 by Sam Lantinga
+
+vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
+WARNING: The licenses for libmad, ADLMIDI, OPNMIDI, and GME is GPL,
+ which means that in order to use it your application must
+ also be GPL!
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The latest original version of this library is available from:
+http://www.libsdl.org/projects/SDL_mixer/
+
+Sources of modified library version is available in the PGE Project's sources:
+https://github.com/Wohlhabend-Networks/PGE-Project/
+ in the folder: _Libs/SDL2_mixer_modified/
+or:
+https://bitbucket.org/Wohlstand/pge-project
+ in the folder: _Libs/SDL2_mixer_modified/
+
+=============================================================================
+Difference between original and this library:
+-----------------------------------------------------------------------------
++ Added new codecs:
+ - Game Music Emulators (LGPL v2.1) which adds support of chip tunes
+ like NSF, VGM, SPC, HES, etc.
+ - libADLMIDI (GPL v3, LGPL v3) (remake from ADLMIDI) to play MIDI with
+ emulated OPL3 synthesiser, also supports loop points
+ "loopStart" and "loopEnd"
+ - libOPNMIDI (GPL v3, LGPL v3) to play MIDI with
+ emulated OPN2 synthesiser, also supports loop points
+ "loopStart" and "loopEnd"
++ Added some new functions
++ Added support of loop points for OGG files (via "LOOPSTART" and "LOOPEND"
+ (or "LOOPLENGTH" to be compatible with RPG Maker) vorbis comments)
++ Reorganized music codecs processing system
++ Added support to get current position and track lenght for a seekable codecs
+
+vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
+IMPORTANT: To choice a track number of NSF, GBM, HES, etc file,
+ you must append "|xxx" to end of file path for
+ Mix_LoadMUS function.
+ Where xxx - actual number of chip track, (from 0 to N-1)
+ Examples: "file.nsf|12", "file.hes|2"
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
+Arguments are passing like argument for a GME-based files (NSF, HES, etc.):
+Syntax for MIDI is:
+ myfile.mid|xyy;xyy;xyy;...;
+ where x - parameter type
+ where y - value (every value must be ended with semicolon!)
+
+available parameters:
+ s - use a specific synthesiser
+ 0 - ADLMIDI
+ 1 - Native MIDI [Win32/OSX/Haiku only]
+ 2 - Timidity
+ 3 - Fluidsynth
+ b - value from 0 to 66 - number of ADLMIDI bank
+ t - (0 or 1) enable deep tremolo on ADLMIDI
+ v - (0 or 1) enable deep vibrato on ADLMIDI
+ m - (0 or 1) enable scalable modulation on ADLMIDI
+ a - (0 or 1) enable AdLib mode of percussion on ADLMIDI
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+=============================================================================
+Added music codecs:
+-----------------------------------------------------------------------------
+General:
+- MUS_GME - Game Music Emulatirs
+
+MIDI Playing:
+- ADLMIDI - A software synthesizer is based on Yamaha OPL3 (YMF262) chip emulator
+- OPNMIDI - A software synthesizer is based on Yamaha OPL3 (YM2612) chip emulator
+
+=============================================================================
+Added functions:
+-----------------------------------------------------------------------------
+/*
+ Allows you to set up custom path for Timidify patches
+*/
+void MIX_Timidity_addToPathList(const char *path);
+
+/*
+ Get music title from meta-tag if possible. If title tag is empty, filename will be returned
+*/
+const char* Mix_GetMusicTitle(const Mix_Music *music);
+
+/*
+ Get music title from meta-tag if possible
+*/
+const char* Mix_GetMusicTitleTag(const Mix_Music *music);
+
+/*
+ Get music artist from meta-tag if possible
+*/
+const char* Mix_GetMusicArtistTag(const Mix_Music *music);
+
+/*
+ Get music album from meta-tag if possible
+*/
+const char* Mix_GetMusicAlbumTag(const Mix_Music *music);
+
+/*
+ Get music copyright from meta-tag if possible
+*/
+const char* Mix_GetMusicCopyrightTag(const Mix_Music *music);
+
+/*
+ Load music from memory with passing of extra arguments
+*/
+Mix_Music * SDLCALLCC Mix_LoadMUS_RW_ARG(SDL_RWops *src, int freesrc, char *args)
+
+/*
+ Load music from memory with passing NSF/HES/etc. track number (accepts integer unlike SDLCALLCC Mix_LoadMUS_RW_ARG)
+*/
+Mix_Music * SDLCALLCC Mix_LoadMUS_RW_GME(SDL_RWops *src, int freesrc, int trackID)
+
+typedef enum
+{
+ MIDI_ADLMIDI,
+ MIDI_Native,
+ MIDI_Timidity,
+ MIDI_OPNMIDI,
+ MIDI_Fluidsynth,
+ MIDI_KnuwnDevices /* Count of MIDI device types */
+} Mix_MIDI_Device;
+
+/*
+ Allows you to toggle MIDI Devices!
+ (change will be applied on re-opening of MIDI file)
+ Attempt to toggle unsupported MIDI device takes no effect
+ (for case when library built without linking of required library)
+*/
+int Mix_SetMidiDevice(int device);
+
+/*
+ Returns current ADLMIDI bank number
+*/
+int MIX_ADLMIDI_getBankID();
+
+/*
+ Changes ADLMIDI bank number (changes applying on MIDI file reopen)
+*/
+void MIX_ADLMIDI_setBankID(int bnk);
+
+/*
+ Returns current state of ADLMIDI deep tremolo flag
+*/
+int MIX_ADLMIDI_getTremolo();
+
+/*
+ Changes ADLMIDI deep tremolo flag (changes applying on MIDI file reopen)
+*/
+void MIX_ADLMIDI_setTremolo(int tr);
+
+/*
+ Returns current state of ADLMIDI deep vibrato flag
+*/
+int MIX_ADLMIDI_getVibrato();
+
+/*
+ Changes ADLMIDI deep vibrato flag (changes applying on MIDI file reopen)
+*/
+void MIX_ADLMIDI_setVibrato(int vib);
+
+/*
+ Returns current state of ADLMIDI deep scaling modulation flag
+*/
+int MIX_ADLMIDI_getScaleMod();
+
+/*
+ Changes ADLMIDI scaling modulation flag (changes applying on MIDI file reopen)
+*/
+void MIX_ADLMIDI_setScaleMod(int sc);
+
+/*
+ Resets ADLMIDI flags and settings to default state
+*/
+void MIX_ADLMIDI_setSetDefaults();
+
+/*
+ Get the time current position of music stream
+ returns -1.0 if this feature is not supported for some codec
+*/
+double Mix_GetMusicPosition(Mix_Music *music);
+/*
+ Get the total time length of music stream
+ returns -1.0 if this feature is not supported for some codec
+ */
+double Mix_GetMusicTotalTime(Mix_Music *music);
+
+/*
+ Get the loop start time position of music stream
+ returns -1.0 if this feature is not used for this music or not supported for some codec
+*/
+double Mix_GetMusicLoopStartTime(Mix_Music *music);
+/*
+ Get the loop end time position of music stream
+ returns -1.0 if this feature is not used for this music or not supported for some codec
+*/
+double Mix_GetMusicLoopEndTime(Mix_Music *music);
+/*
+ Get the loop time length of music stream
+ returns -1.0 if this feature is not used for this music or not supported for some codec
+*/
+double Mix_GetMusicLoopLengthTime(Mix_Music *music);
+
+=============================================================================
+
+Due to popular demand, here is a simple multi-channel audio mixer.
+It supports 8 channels of 16 bit stereo audio, plus a single channel
+of music, mixed by the Modplug MOD, Timidity MIDI, ADLMIDI, GME
+and LibMAD MP3 libraries.
+
+See the header file SDL_mixer_ext.h for documentation on this mixer library.
+
+The mixer can currently load Microsoft WAVE files and Creative Labs VOC
+files as audio samples, and can load MIDI files via Timidity and the
+following music formats via MikMod: .MOD .S3M .IT .XM. It can load
+Ogg Vorbis streams as music if built with Ogg Vorbis or Tremor libraries,
+and finally it can load MP3 music using the SMPEG or libmad libraries.
+
+Tremor decoding is disabled by default; you can enable it by passing
+ --enable-music-ogg-tremor
+to configure, or by defining OGG_MUSIC and OGG_USE_TREMOR.
+
+libmad decoding is disabled by default; you can enable it by passing
+ --enable-music-mp3-mad
+to configure, or by defining MP3_MAD_MUSIC
+vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
+WARNING: The license for libmad is GPL, which means that in order to
+ use it your application must also be GPL!
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The process of mixing MIDI files to wave output is very CPU intensive,
+so if playing regular WAVE files sound great, but playing MIDI files
+sound choppy on slow computers, try using 8-bit audio, mono audio,
+or lower frequencies.
+
+To play MIDI files via Timidity, you'll need to get a complete set of GUS patches
+from:
+http://www.libsdl.org/projects/mixer/timidity/timidity.tar.gz
+and unpack them in /usr/local/lib under UNIX, and C:\ under Win32.
+
+This library is under the zlib license, see the file "COPYING.txt" for details.
+
+
+
diff --git a/libs/SDLMixerX/SDL2_mixer_ext.License.txt b/libs/SDLMixerX/SDL2_mixer_ext.License.txt
new file mode 100644
index 000000000..58806358d
--- /dev/null
+++ b/libs/SDLMixerX/SDL2_mixer_ext.License.txt
@@ -0,0 +1,104 @@
+========================================================================
+SDL_mixer_ext {aka SDL Mixer X, SDL Mixer 2.0 Modded}, by Vitaly Novichkov
+forked from SDL Mixer 2.0 by Sam Lantinga
+========================================================================
+
+SDL_mixer_ext: An extended audio mixer library, forked from SDL_mixer
+Copyright (C) 2014-2018 Vitaly Novichkov
+
+SDL_mixer: An audio mixer library based on the SDL library
+Copyright (C) 1997-2018 Sam Lantinga
+
+Sources of modified library version is available on GitHub:
+https://github.com/WohlSoft/SDL-Mixer-X
+
+This software is provided 'as-is', without any express or implied
+warranty. In no event will the authors be held liable for any damages
+arising from the use of this software.
+
+Permission is granted to anyone to use this software for any purpose,
+including commercial applications, and to alter it and redistribute it
+freely, subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+3. This notice may not be removed or altered from any source distribution.
+
+========================================================================
+Statically linked libraries:
+========================================================================
+------------------------------------------------------------------------
+libADLMIDI: is a free MIDI to WAV conversion library with OPL3 emulation
+
+Original ADLMIDI code: Copyright (c) 2010-2014 Joel Yliluoma
+ADLMIDI Library API: Copyright (c) 2015-2018 Vitaly Novichkov
+
+Library is based on the ADLMIDI, a MIDI player for Linux and Windows
+with OPL3 emulation:
+http://iki.fi/bisqwit/source/adlmidi.html
+
+Source code: https://github.com/Wohlstand/libADLMIDI
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see .
+
+------------------------------------------------------------------------
+
+Game Music Emulators: is a free chuptunes to WAV conversion library.
+
+Source code: https://bitbucket.org/mpyne/game-music-emu
+
+Copyright (C) 2003-2006 Shay Green.
+
+This module is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published
+by the Free Software Foundation; either version 2.1 of the License,
+or (at your option) any later version.
+
+This module is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this module;
+If not, see .
+
+------------------------------------------------------------------------
+
+libmad: MPEG audio decoder library
+
+Copyright (C) 2000-2004 Underbit Technologies, Inc.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+If you would like to negotiate alternate licensing terms, you may do
+so by contacting: Underbit Technologies, Inc.
+
+------------------------------------------------------------------------
diff --git a/libs/SDLMixerX/SRB2Note.txt b/libs/SDLMixerX/SRB2Note.txt
new file mode 100644
index 000000000..6036d394e
--- /dev/null
+++ b/libs/SDLMixerX/SRB2Note.txt
@@ -0,0 +1,7 @@
+i686-w64-mingw32/bin/libfluidsynth-2.dll was grabbed from GZDoom v3.5.1, because this build does not have glib, gthread, or sndfile external dependencies.
+
+sdl_mixer_ext2.dll requires libgcc and libstdc++ external dependencies. While passing to the linker "-Bstatic -lgcc" works fine, adding "-lstdc++" to -Bstatic generates linker errors.
+
+Hence, libstdc++ needs to be bundled as DLL (and consequently, libgcc.)
+
+If you try to build yourself, make sure -lstdc++ does not follow -Bdynamic in the linker flags, because otherwise it will link to the DLL.
diff --git a/libs/SDLMixerX/SRB2Note_cmakeflags.png b/libs/SDLMixerX/SRB2Note_cmakeflags.png
new file mode 100644
index 000000000..ffcf269a4
Binary files /dev/null and b/libs/SDLMixerX/SRB2Note_cmakeflags.png differ
diff --git a/libs/SDLMixerX/i686-w64-mingw32/bin/SDL2_mixer_ext.dll b/libs/SDLMixerX/i686-w64-mingw32/bin/SDL2_mixer_ext.dll
new file mode 100644
index 000000000..158aad8c3
Binary files /dev/null and b/libs/SDLMixerX/i686-w64-mingw32/bin/SDL2_mixer_ext.dll differ
diff --git a/libs/SDLMixerX/i686-w64-mingw32/bin/libfluidsynth-2.dll b/libs/SDLMixerX/i686-w64-mingw32/bin/libfluidsynth-2.dll
new file mode 100644
index 000000000..1b768a6c1
Binary files /dev/null and b/libs/SDLMixerX/i686-w64-mingw32/bin/libfluidsynth-2.dll differ
diff --git a/libs/SDLMixerX/i686-w64-mingw32/bin/libgcc_s_sjlj-1.dll b/libs/SDLMixerX/i686-w64-mingw32/bin/libgcc_s_sjlj-1.dll
new file mode 100644
index 000000000..0a62946cb
Binary files /dev/null and b/libs/SDLMixerX/i686-w64-mingw32/bin/libgcc_s_sjlj-1.dll differ
diff --git a/libs/SDLMixerX/i686-w64-mingw32/bin/libstdc++-6.dll b/libs/SDLMixerX/i686-w64-mingw32/bin/libstdc++-6.dll
new file mode 100644
index 000000000..e9feebaaa
Binary files /dev/null and b/libs/SDLMixerX/i686-w64-mingw32/bin/libstdc++-6.dll differ
diff --git a/libs/SDLMixerX/i686-w64-mingw32/include/SDL2/SDL_mixer_ext.h b/libs/SDLMixerX/i686-w64-mingw32/include/SDL2/SDL_mixer_ext.h
new file mode 100644
index 000000000..3a6b91b50
--- /dev/null
+++ b/libs/SDLMixerX/i686-w64-mingw32/include/SDL2/SDL_mixer_ext.h
@@ -0,0 +1,867 @@
+/*
+ SDL Mixer X: An extended audio mixer library, forked from SDL_mixer
+ Copyright (C) 2014-2018 Vitaly Novichkov
+
+ SDL_mixer: An audio mixer library based on the SDL library
+ Copyright (C) 1997-2018 Sam Lantinga
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#ifndef SDL_MIXER_H_
+#define SDL_MIXER_H_
+
+#include "SDL_stdinc.h"
+#include "SDL_rwops.h"
+#include "SDL_audio.h"
+#include "SDL_endian.h"
+#include "SDL_version.h"
+#include "begin_code.h"
+
+/* Let applications recogonize which SDL Mixer edition is in use: Official or Extended fork by Wohlstand */
+#define SDL_MIXER_X 1
+
+#define MIXSDLCALL
+
+#if defined(FORCE_STDCALLS) && defined(_WIN32)
+#ifdef SDLCALL
+#undef SDLCALL
+#endif
+#define SDLCALL __stdcall
+#define SDLCALLCC __stdcall
+#else
+#define SDLCALLCC
+#endif
+
+#ifndef DEPRECATED
+#ifdef __GNUC__
+#define DEPRECATED(func) func __attribute__ ((deprecated))
+#elif defined(_MSC_VER)
+#define DEPRECATED(func) __declspec(deprecated) func
+#else
+#pragma message("WARNING: You need to implement DEPRECATED for this compiler")
+#define DEPRECATED(func) func
+#endif
+#endif
+
+/* Set up for C function definitions, even when using C++ */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Printable format: "%d.%d.%d", MAJOR, MINOR, PATCHLEVEL
+*/
+#define SDL_MIXER_MAJOR_VERSION 2
+#define SDL_MIXER_MINOR_VERSION 2
+#define SDL_MIXER_PATCHLEVEL 0
+
+/* This macro can be used to fill a version structure with the compile-time
+ * version of the SDL_mixer library.
+ */
+#define SDL_MIXER_VERSION(X) \
+{ \
+ (X)->major = SDL_MIXER_MAJOR_VERSION; \
+ (X)->minor = SDL_MIXER_MINOR_VERSION; \
+ (X)->patch = SDL_MIXER_PATCHLEVEL; \
+}
+
+/* Backwards compatibility */
+#define MIX_MAJOR_VERSION SDL_MIXER_MAJOR_VERSION
+#define MIX_MINOR_VERSION SDL_MIXER_MINOR_VERSION
+#define MIX_PATCHLEVEL SDL_MIXER_PATCHLEVEL
+#define MIX_VERSION(X) SDL_MIXER_VERSION(X)
+
+/**
+ * This is the version number macro for the current SDL_mixer version.
+ */
+#define SDL_MIXER_COMPILEDVERSION \
+ SDL_VERSIONNUM(SDL_MIXER_MAJOR_VERSION, SDL_MIXER_MINOR_VERSION, SDL_MIXER_PATCHLEVEL)
+
+/**
+ * This macro will evaluate to true if compiled with SDL_mixer at least X.Y.Z.
+ */
+#define SDL_MIXER_VERSION_ATLEAST(X, Y, Z) \
+ (SDL_MIXER_COMPILEDVERSION >= SDL_VERSIONNUM(X, Y, Z))
+
+/* This function gets the version of the dynamically linked SDL_mixer library.
+ it should NOT be used to fill a version structure, instead you should
+ use the SDL_MIXER_VERSION() macro.
+ */
+extern DECLSPEC const SDL_version * SDLCALL Mix_Linked_Version(void);
+
+typedef enum
+{
+ MIX_INIT_FLAC = 0x00000001,
+ MIX_INIT_MOD = 0x00000002,
+ MIX_INIT_MP3 = 0x00000008,
+ MIX_INIT_OGG = 0x00000010,
+ MIX_INIT_MID = 0x00000020,
+ MIX_INIT_OPUS = 0x00000040
+} MIX_InitFlags;
+
+/* Loads dynamic libraries and prepares them for use. Flags should be
+ one or more flags from MIX_InitFlags OR'd together.
+ It returns the flags successfully initialized, or 0 on failure.
+ */
+extern DECLSPEC int SDLCALL Mix_Init(int flags);
+
+/* Unloads libraries loaded with Mix_Init */
+extern DECLSPEC void SDLCALL Mix_Quit(void);
+
+
+/* The default mixer has 8 simultaneous mixing channels */
+#ifndef MIX_CHANNELS
+#define MIX_CHANNELS 8
+#endif
+
+/* Good default values for a PC soundcard */
+#define MIX_DEFAULT_FREQUENCY 44100
+#if SDL_BYTEORDER == SDL_LIL_ENDIAN
+#define MIX_DEFAULT_FORMAT AUDIO_S16LSB
+#else
+#define MIX_DEFAULT_FORMAT AUDIO_S16MSB
+#endif
+#define MIX_DEFAULT_CHANNELS 2
+#define MIX_MAX_VOLUME SDL_MIX_MAXVOLUME /* Volume of a chunk */
+
+/* The internal format for an audio chunk */
+typedef struct Mix_Chunk {
+ int allocated;
+ Uint8 *abuf;
+ Uint32 alen;
+ Uint8 volume; /* Per-sample volume, 0-128 */
+} Mix_Chunk;
+
+/* The different fading types supported */
+typedef enum {
+ MIX_NO_FADING,
+ MIX_FADING_OUT,
+ MIX_FADING_IN
+} Mix_Fading;
+
+/* These are types of music files (not libraries used to load them) */
+typedef enum {
+ MUS_NONE,
+ MUS_CMD,
+ MUS_WAV,
+ MUS_MOD,
+ MUS_MID,
+ MUS_OGG,
+ MUS_MP3,
+ MUS_MP3_MAD_UNUSED,
+ MUS_FLAC,
+ MUS_MODPLUG_UNUSED,
+ MUS_OPUS,
+ MUS_GME,
+ MUS_ADLMIDI/*Use ADLMIDI coded for super-special formats like IMF, MUS or XMI are can't be played without ADLMIDI*/
+} Mix_MusicType;
+
+typedef enum {
+ MIDI_ADLMIDI,
+ MIDI_Native,
+ MIDI_Timidity,
+ MIDI_OPNMIDI,
+ MIDI_Fluidsynth,
+ MIDI_ANY,
+ MIDI_KnuwnDevices /* Count of MIDI device types */
+} Mix_MIDI_Device;
+
+/* Volume model type in the ADLMIDI */
+typedef enum {
+ ADLMIDI_VM_AUTO,
+ ADLMIDI_VM_GENERIC,
+ ADLMIDI_VM_CMF,
+ ADLMIDI_VM_DMX,
+ ADLMIDI_VM_APOGEE,
+ ADLMIDI_VM_9X
+} Mix_ADLMIDI_VolumeModel;
+
+/* OPL3 chip emulators for ADLMIDI */
+typedef enum {
+ ADLMIDI_OPL3_EMU_DEFAULT = -1,
+ ADLMIDI_OPL3_EMU_NUKED = 0,
+ ADLMIDI_OPL3_EMU_NUKED_1_7_4,
+ ADLMIDI_OPL3_EMU_DOSBOX,
+} Mix_ADLMIDI_Emulator;
+
+/* OPN2 chip emulators for OPNMIDI */
+typedef enum {
+ OPNMIDI_OPN2_EMU_DEFAULT = -1,
+ OPNMIDI_OPN2_EMU_MIME = 0,
+ OPNMIDI_OPN2_EMU_NUKED,
+ OPNMIDI_OPN2_EMU_GENS,
+} Mix_OPNMIDI_Emulator;
+
+/* The internal format for a music chunk interpreted via mikmod */
+typedef struct _Mix_Music Mix_Music;
+
+/* Open the mixer with a certain audio format */
+extern DECLSPEC int SDLCALL Mix_OpenAudio(int frequency, Uint16 format, int channels, int chunksize);
+
+/* Open the mixer with specific device and certain audio format */
+extern DECLSPEC int SDLCALL Mix_OpenAudioDevice(int frequency, Uint16 format, int channels, int chunksize, const char* device, int allowed_changes);
+
+/* Dynamically change the number of channels managed by the mixer.
+ If decreasing the number of channels, the upper channels are
+ stopped.
+ This function returns the new number of allocated channels.
+ */
+extern DECLSPEC int SDLCALL Mix_AllocateChannels(int numchans);
+
+/* Find out what the actual audio device parameters are.
+ This function returns 1 if the audio has been opened, 0 otherwise.
+ */
+extern DECLSPEC int SDLCALL Mix_QuerySpec(int *frequency,Uint16 *format,int *channels);
+
+/* Load a wave file or a music (.mod .s3m .it .xm) file
+ IMPORTANT: To choice a track number of NSF, GBM, HES, etc file,
+ you must append "|xxx" to end of file path for
+ Mix_LoadMUS function.
+ Where xxx - actual number of chip track, (from 0 to N-1)
+ Examples: "file.nsf|12", "file.hes|2"
+*/
+extern DECLSPEC Mix_Chunk * SDLCALL Mix_LoadWAV_RW(SDL_RWops *src, int freesrc);
+#define Mix_LoadWAV(file) Mix_LoadWAV_RW(SDL_RWFromFile(file, "rb"), 1)
+extern DECLSPEC Mix_Music * SDLCALL Mix_LoadMUS(const char *file);
+
+/* Load a music file from an SDL_RWop object
+ * Matt Campbell (matt@campbellhome.dhs.org) April 2000 */
+extern DECLSPEC Mix_Music * SDLCALL Mix_LoadMUS_RW(SDL_RWops *src, int freesrc);
+
+/* Load a music file from an SDL_RWop object with custom arguments (trackID for GME or settings for a MIDI playing)
+ * Arguments are taking no effect for file formats which are not supports extra arguments.
+ */
+extern DECLSPEC Mix_Music *SDLCALL Mix_LoadMUS_RW_ARG(SDL_RWops *src, int freesrc, const char *args);
+
+/* Load a music file from an SDL_RWop object with custom trackID for GME.
+ * trackID argument takes no effect for non-NSF,HES,GBM,etc. file formats.
+ * Default value should be 0
+ */
+extern DECLSPEC Mix_Music *SDLCALL Mix_LoadMUS_RW_GME(SDL_RWops *src, int freesrc, int trackID);
+
+/* Load a music file from an SDL_RWop object assuming a specific format */
+extern DECLSPEC Mix_Music * SDLCALL Mix_LoadMUSType_RW(SDL_RWops *src, Mix_MusicType type, int freesrc);
+
+/* Load a music file from an SDL_RWop object assuming a specific format
+ with custom arguments (trackID for GME or settings for a MIDI playing) */
+extern DECLSPEC Mix_Music * SDLCALL Mix_LoadMUSType_RW_ARG(SDL_RWops *src, Mix_MusicType type, int freesrc, const char *args);
+
+/* Load a wave file of the mixer format from a memory buffer */
+extern DECLSPEC Mix_Chunk * SDLCALL Mix_QuickLoad_WAV(Uint8 *mem);
+
+/* Load raw audio data of the mixer format from a memory buffer */
+extern DECLSPEC Mix_Chunk * SDLCALL Mix_QuickLoad_RAW(Uint8 *mem, Uint32 len);
+
+/* Free an audio chunk previously loaded */
+extern DECLSPEC void SDLCALL Mix_FreeChunk(Mix_Chunk *chunk);
+extern DECLSPEC void SDLCALL Mix_FreeMusic(Mix_Music *music);
+
+/* Get a list of chunk/music decoders that this build of SDL_mixer provides.
+ This list can change between builds AND runs of the program, if external
+ libraries that add functionality become available.
+ You must successfully call Mix_OpenAudio() before calling these functions.
+ This API is only available in SDL_mixer 1.2.9 and later.
+
+ // usage...
+ int i;
+ const int total = Mix_GetNumChunkDecoders();
+ for (i = 0; i < total; i++)
+ printf("Supported chunk decoder: [%s]\n", Mix_GetChunkDecoder(i));
+
+ Appearing in this list doesn't promise your specific audio file will
+ decode...but it's handy to know if you have, say, a functioning Timidity
+ install.
+
+ These return values are static, read-only data; do not modify or free it.
+ The pointers remain valid until you call Mix_CloseAudio().
+*/
+extern DECLSPEC int SDLCALL Mix_GetNumChunkDecoders(void);
+extern DECLSPEC const char * SDLCALL Mix_GetChunkDecoder(int index);
+extern DECLSPEC SDL_bool SDLCALL Mix_HasChunkDecoder(const char *name);
+extern DECLSPEC int SDLCALL Mix_GetNumMusicDecoders(void);
+extern DECLSPEC const char * SDLCALL Mix_GetMusicDecoder(int index);
+extern DECLSPEC SDL_bool SDLCALL Mix_HasMusicDecoder(const char *name);
+
+/* Find out the music format of a mixer music, or the currently playing
+ music, if 'music' is NULL.
+*/
+extern DECLSPEC Mix_MusicType SDLCALL Mix_GetMusicType(const Mix_Music *music);
+
+/* Get music title from meta-tag if possible. If title tag is empty, filename will be returned */
+extern DECLSPEC const char *SDLCALL Mix_GetMusicTitle(const Mix_Music *music);
+/* Get music title from meta-tag if possible */
+extern DECLSPEC const char *SDLCALL Mix_GetMusicTitleTag(const Mix_Music *music);
+/* Get music artist from meta-tag if possible */
+extern DECLSPEC const char *SDLCALL Mix_GetMusicArtistTag(const Mix_Music *music);
+/* Get music album from meta-tag if possible */
+extern DECLSPEC const char *SDLCALL Mix_GetMusicAlbumTag(const Mix_Music *music);
+/* Get music copyright from meta-tag if possible */
+extern DECLSPEC const char *SDLCALL Mix_GetMusicCopyrightTag(const Mix_Music *music);
+
+/* Set a function that is called after all mixing is performed.
+ This can be used to provide real-time visual display of the audio stream
+ or add a custom mixer filter for the stream data.
+*/
+extern DECLSPEC void SDLCALL Mix_SetPostMix(void (SDLCALL *mix_func)(void *udata, Uint8 *stream, int len), void *arg);
+
+/* Add your own music player or additional mixer function.
+ If 'mix_func' is NULL, the default music player is re-enabled.
+ */
+extern DECLSPEC void SDLCALL Mix_HookMusic(void (SDLCALL *mix_func)(void *udata, Uint8 *stream, int len), void *arg);
+
+/* Add your own callback for when the music has finished playing or when it is
+ * stopped from a call to Mix_HaltMusic.
+ */
+extern DECLSPEC void SDLCALL Mix_HookMusicFinished(void (SDLCALL *music_finished)(void));
+
+/* Get a pointer to the user data for the current music hook */
+extern DECLSPEC void * SDLCALL Mix_GetMusicHookData(void);
+
+/*
+ * Add your own callback when a channel has finished playing. NULL
+ * to disable callback. The callback may be called from the mixer's audio
+ * callback or it could be called as a result of Mix_HaltChannel(), etc.
+ * do not call SDL_LockAudio() from this callback; you will either be
+ * inside the audio callback, or SDL_mixer will explicitly lock the audio
+ * before calling your callback.
+ */
+extern DECLSPEC void SDLCALL Mix_ChannelFinished(void (SDLCALL *channel_finished)(int channel));
+
+
+/* Special Effects API by ryan c. gordon. (icculus@icculus.org) */
+
+#define MIX_CHANNEL_POST -2
+
+/* This is the format of a special effect callback:
+ *
+ * myeffect(int chan, void *stream, int len, void *udata);
+ *
+ * (chan) is the channel number that your effect is affecting. (stream) is
+ * the buffer of data to work upon. (len) is the size of (stream), and
+ * (udata) is a user-defined bit of data, which you pass as the last arg of
+ * Mix_RegisterEffect(), and is passed back unmolested to your callback.
+ * Your effect changes the contents of (stream) based on whatever parameters
+ * are significant, or just leaves it be, if you prefer. You can do whatever
+ * you like to the buffer, though, and it will continue in its changed state
+ * down the mixing pipeline, through any other effect functions, then finally
+ * to be mixed with the rest of the channels and music for the final output
+ * stream.
+ *
+ * DO NOT EVER call SDL_LockAudio() from your callback function!
+ */
+typedef void (SDLCALL *Mix_EffectFunc_t)(int chan, void *stream, int len, void *udata);
+
+/*
+ * This is a callback that signifies that a channel has finished all its
+ * loops and has completed playback. This gets called if the buffer
+ * plays out normally, or if you call Mix_HaltChannel(), implicitly stop
+ * a channel via Mix_AllocateChannels(), or unregister a callback while
+ * it's still playing.
+ *
+ * DO NOT EVER call SDL_LockAudio() from your callback function!
+ */
+typedef void (SDLCALL *Mix_EffectDone_t)(int chan, void *udata);
+
+
+/* Register a special effect function. At mixing time, the channel data is
+ * copied into a buffer and passed through each registered effect function.
+ * After it passes through all the functions, it is mixed into the final
+ * output stream. The copy to buffer is performed once, then each effect
+ * function performs on the output of the previous effect. Understand that
+ * this extra copy to a buffer is not performed if there are no effects
+ * registered for a given chunk, which saves CPU cycles, and any given
+ * effect will be extra cycles, too, so it is crucial that your code run
+ * fast. Also note that the data that your function is given is in the
+ * format of the sound device, and not the format you gave to Mix_OpenAudio(),
+ * although they may in reality be the same. This is an unfortunate but
+ * necessary speed concern. Use Mix_QuerySpec() to determine if you can
+ * handle the data before you register your effect, and take appropriate
+ * actions.
+ * You may also specify a callback (Mix_EffectDone_t) that is called when
+ * the channel finishes playing. This gives you a more fine-grained control
+ * than Mix_ChannelFinished(), in case you need to free effect-specific
+ * resources, etc. If you don't need this, you can specify NULL.
+ * You may set the callbacks before or after calling Mix_PlayChannel().
+ * Things like Mix_SetPanning() are just internal special effect functions,
+ * so if you are using that, you've already incurred the overhead of a copy
+ * to a separate buffer, and that these effects will be in the queue with
+ * any functions you've registered. The list of registered effects for a
+ * channel is reset when a chunk finishes playing, so you need to explicitly
+ * set them with each call to Mix_PlayChannel*().
+ * You may also register a special effect function that is to be run after
+ * final mixing occurs. The rules for these callbacks are identical to those
+ * in Mix_RegisterEffect, but they are run after all the channels and the
+ * music have been mixed into a single stream, whereas channel-specific
+ * effects run on a given channel before any other mixing occurs. These
+ * global effect callbacks are call "posteffects". Posteffects only have
+ * their Mix_EffectDone_t function called when they are unregistered (since
+ * the main output stream is never "done" in the same sense as a channel).
+ * You must unregister them manually when you've had enough. Your callback
+ * will be told that the channel being mixed is (MIX_CHANNEL_POST) if the
+ * processing is considered a posteffect.
+ *
+ * After all these effects have finished processing, the callback registered
+ * through Mix_SetPostMix() runs, and then the stream goes to the audio
+ * device.
+ *
+ * DO NOT EVER call SDL_LockAudio() from your callback function!
+ *
+ * returns zero if error (no such channel), nonzero if added.
+ * Error messages can be retrieved from Mix_GetError().
+ */
+extern DECLSPEC int SDLCALL Mix_RegisterEffect(int chan, Mix_EffectFunc_t f, Mix_EffectDone_t d, void *arg);
+
+
+/* You may not need to call this explicitly, unless you need to stop an
+ * effect from processing in the middle of a chunk's playback.
+ * Posteffects are never implicitly unregistered as they are for channels,
+ * but they may be explicitly unregistered through this function by
+ * specifying MIX_CHANNEL_POST for a channel.
+ * returns zero if error (no such channel or effect), nonzero if removed.
+ * Error messages can be retrieved from Mix_GetError().
+ */
+extern DECLSPEC int SDLCALL Mix_UnregisterEffect(int channel, Mix_EffectFunc_t f);
+
+
+/* You may not need to call this explicitly, unless you need to stop all
+ * effects from processing in the middle of a chunk's playback. Note that
+ * this will also shut off some internal effect processing, since
+ * Mix_SetPanning() and others may use this API under the hood. This is
+ * called internally when a channel completes playback.
+ * Posteffects are never implicitly unregistered as they are for channels,
+ * but they may be explicitly unregistered through this function by
+ * specifying MIX_CHANNEL_POST for a channel.
+ * returns zero if error (no such channel), nonzero if all effects removed.
+ * Error messages can be retrieved from Mix_GetError().
+ */
+extern DECLSPEC int SDLCALL Mix_UnregisterAllEffects(int channel);
+
+
+#define MIX_EFFECTSMAXSPEED "MIX_EFFECTSMAXSPEED"
+
+/*
+ * These are the internally-defined mixing effects. They use the same API that
+ * effects defined in the application use, but are provided here as a
+ * convenience. Some effects can reduce their quality or use more memory in
+ * the name of speed; to enable this, make sure the environment variable
+ * MIX_EFFECTSMAXSPEED (see above) is defined before you call
+ * Mix_OpenAudio().
+ */
+
+
+/* Set the panning of a channel. The left and right channels are specified
+ * as integers between 0 and 255, quietest to loudest, respectively.
+ *
+ * Technically, this is just individual volume control for a sample with
+ * two (stereo) channels, so it can be used for more than just panning.
+ * If you want real panning, call it like this:
+ *
+ * Mix_SetPanning(channel, left, 255 - left);
+ *
+ * ...which isn't so hard.
+ *
+ * Setting (channel) to MIX_CHANNEL_POST registers this as a posteffect, and
+ * the panning will be done to the final mixed stream before passing it on
+ * to the audio device.
+ *
+ * This uses the Mix_RegisterEffect() API internally, and returns without
+ * registering the effect function if the audio device is not configured
+ * for stereo output. Setting both (left) and (right) to 255 causes this
+ * effect to be unregistered, since that is the data's normal state.
+ *
+ * returns zero if error (no such channel or Mix_RegisterEffect() fails),
+ * nonzero if panning effect enabled. Note that an audio device in mono
+ * mode is a no-op, but this call will return successful in that case.
+ * Error messages can be retrieved from Mix_GetError().
+ */
+extern DECLSPEC int SDLCALL Mix_SetPanning(int channel, Uint8 left, Uint8 right);
+
+
+/* Set the position of a channel. (angle) is an integer from 0 to 360, that
+ * specifies the location of the sound in relation to the listener. (angle)
+ * will be reduced as neccesary (540 becomes 180 degrees, -100 becomes 260).
+ * Angle 0 is due north, and rotates clockwise as the value increases.
+ * For efficiency, the precision of this effect may be limited (angles 1
+ * through 7 might all produce the same effect, 8 through 15 are equal, etc).
+ * (distance) is an integer between 0 and 255 that specifies the space
+ * between the sound and the listener. The larger the number, the further
+ * away the sound is. Using 255 does not guarantee that the channel will be
+ * culled from the mixing process or be completely silent. For efficiency,
+ * the precision of this effect may be limited (distance 0 through 5 might
+ * all produce the same effect, 6 through 10 are equal, etc). Setting (angle)
+ * and (distance) to 0 unregisters this effect, since the data would be
+ * unchanged.
+ *
+ * If you need more precise positional audio, consider using OpenAL for
+ * spatialized effects instead of SDL_mixer. This is only meant to be a
+ * basic effect for simple "3D" games.
+ *
+ * If the audio device is configured for mono output, then you won't get
+ * any effectiveness from the angle; however, distance attenuation on the
+ * channel will still occur. While this effect will function with stereo
+ * voices, it makes more sense to use voices with only one channel of sound,
+ * so when they are mixed through this effect, the positioning will sound
+ * correct. You can convert them to mono through SDL before giving them to
+ * the mixer in the first place if you like.
+ *
+ * Setting (channel) to MIX_CHANNEL_POST registers this as a posteffect, and
+ * the positioning will be done to the final mixed stream before passing it
+ * on to the audio device.
+ *
+ * This is a convenience wrapper over Mix_SetDistance() and Mix_SetPanning().
+ *
+ * returns zero if error (no such channel or Mix_RegisterEffect() fails),
+ * nonzero if position effect is enabled.
+ * Error messages can be retrieved from Mix_GetError().
+ */
+extern DECLSPEC int SDLCALL Mix_SetPosition(int channel, Sint16 angle, Uint8 distance);
+
+
+/* Set the "distance" of a channel. (distance) is an integer from 0 to 255
+ * that specifies the location of the sound in relation to the listener.
+ * Distance 0 is overlapping the listener, and 255 is as far away as possible
+ * A distance of 255 does not guarantee silence; in such a case, you might
+ * want to try changing the chunk's volume, or just cull the sample from the
+ * mixing process with Mix_HaltChannel().
+ * For efficiency, the precision of this effect may be limited (distances 1
+ * through 7 might all produce the same effect, 8 through 15 are equal, etc).
+ * (distance) is an integer between 0 and 255 that specifies the space
+ * between the sound and the listener. The larger the number, the further
+ * away the sound is.
+ * Setting (distance) to 0 unregisters this effect, since the data would be
+ * unchanged.
+ * If you need more precise positional audio, consider using OpenAL for
+ * spatialized effects instead of SDL_mixer. This is only meant to be a
+ * basic effect for simple "3D" games.
+ *
+ * Setting (channel) to MIX_CHANNEL_POST registers this as a posteffect, and
+ * the distance attenuation will be done to the final mixed stream before
+ * passing it on to the audio device.
+ *
+ * This uses the Mix_RegisterEffect() API internally.
+ *
+ * returns zero if error (no such channel or Mix_RegisterEffect() fails),
+ * nonzero if position effect is enabled.
+ * Error messages can be retrieved from Mix_GetError().
+ */
+extern DECLSPEC int SDLCALL Mix_SetDistance(int channel, Uint8 distance);
+
+
+/*
+ * !!! FIXME : Haven't implemented, since the effect goes past the
+ * end of the sound buffer. Will have to think about this.
+ * --ryan.
+ */
+#if 0
+/* Causes an echo effect to be mixed into a sound. (echo) is the amount
+ * of echo to mix. 0 is no echo, 255 is infinite (and probably not
+ * what you want).
+ *
+ * Setting (channel) to MIX_CHANNEL_POST registers this as a posteffect, and
+ * the reverbing will be done to the final mixed stream before passing it on
+ * to the audio device.
+ *
+ * This uses the Mix_RegisterEffect() API internally. If you specify an echo
+ * of zero, the effect is unregistered, as the data is already in that state.
+ *
+ * returns zero if error (no such channel or Mix_RegisterEffect() fails),
+ * nonzero if reversing effect is enabled.
+ * Error messages can be retrieved from Mix_GetError().
+ */
+extern no_parse_DECLSPEC int SDLCALL Mix_SetReverb(int channel, Uint8 echo);
+#endif
+
+/* Causes a channel to reverse its stereo. This is handy if the user has his
+ * speakers hooked up backwards, or you would like to have a minor bit of
+ * psychedelia in your sound code. :) Calling this function with (flip)
+ * set to non-zero reverses the chunks's usual channels. If (flip) is zero,
+ * the effect is unregistered.
+ *
+ * This uses the Mix_RegisterEffect() API internally, and thus is probably
+ * more CPU intensive than having the user just plug in his speakers
+ * correctly. Mix_SetReverseStereo() returns without registering the effect
+ * function if the audio device is not configured for stereo output.
+ *
+ * If you specify MIX_CHANNEL_POST for (channel), then this the effect is used
+ * on the final mixed stream before sending it on to the audio device (a
+ * posteffect).
+ *
+ * returns zero if error (no such channel or Mix_RegisterEffect() fails),
+ * nonzero if reversing effect is enabled. Note that an audio device in mono
+ * mode is a no-op, but this call will return successful in that case.
+ * Error messages can be retrieved from Mix_GetError().
+ */
+extern DECLSPEC int SDLCALL Mix_SetReverseStereo(int channel, int flip);
+
+/* end of effects API. --ryan. */
+
+
+/* Reserve the first channels (0 -> n-1) for the application, i.e. don't allocate
+ them dynamically to the next sample if requested with a -1 value below.
+ Returns the number of reserved channels.
+ */
+extern DECLSPEC int SDLCALL Mix_ReserveChannels(int num);
+
+/* Channel grouping functions */
+
+/* Attach a tag to a channel. A tag can be assigned to several mixer
+ channels, to form groups of channels.
+ If 'tag' is -1, the tag is removed (actually -1 is the tag used to
+ represent the group of all the channels).
+ Returns true if everything was OK.
+ */
+extern DECLSPEC int SDLCALL Mix_GroupChannel(int which, int tag);
+/* Assign several consecutive channels to a group */
+extern DECLSPEC int SDLCALL Mix_GroupChannels(int from, int to, int tag);
+/* Finds the first available channel in a group of channels,
+ returning -1 if none are available.
+ */
+extern DECLSPEC int SDLCALL Mix_GroupAvailable(int tag);
+/* Returns the number of channels in a group. This is also a subtle
+ way to get the total number of channels when 'tag' is -1
+ */
+extern DECLSPEC int SDLCALL Mix_GroupCount(int tag);
+/* Finds the "oldest" sample playing in a group of channels */
+extern DECLSPEC int SDLCALL Mix_GroupOldest(int tag);
+/* Finds the "most recent" (i.e. last) sample playing in a group of channels */
+extern DECLSPEC int SDLCALL Mix_GroupNewer(int tag);
+
+/* Play an audio chunk on a specific channel.
+ If the specified channel is -1, play on the first free channel.
+ If 'loops' is greater than zero, loop the sound that many times.
+ If 'loops' is -1, loop inifinitely (~65000 times).
+ Returns which channel was used to play the sound.
+*/
+#define Mix_PlayChannel(channel,chunk,loops) Mix_PlayChannelTimed(channel,chunk,loops,-1)
+/* The same as above, but the sound is played at most 'ticks' milliseconds */
+extern DECLSPEC int SDLCALL Mix_PlayChannelTimed(int channel, Mix_Chunk *chunk, int loops, int ticks);
+extern DECLSPEC int SDLCALL Mix_PlayMusic(Mix_Music *music, int loops);
+#define Mix_PlayChannelVol(channel,chunk,loops,vol) Mix_PlayChannelTimedVolume(channel,chunk,loops,-1,vol)/*MIXER-X*/
+extern DECLSPEC int SDLCALL Mix_PlayChannelTimedVolume(int which, Mix_Chunk *chunk, int loops, int ticks, int volume);/*MIXER-X*/
+
+/* Fade in music or a channel over "ms" milliseconds, same semantics as the "Play" functions */
+extern DECLSPEC int SDLCALL Mix_FadeInMusic(Mix_Music *music, int loops, int ms);
+extern DECLSPEC int SDLCALL Mix_FadeInMusicPos(Mix_Music *music, int loops, int ms, double position);
+#define Mix_FadeInChannel(channel,chunk,loops,ms) Mix_FadeInChannelTimed(channel,chunk,loops,ms,-1)
+extern DECLSPEC int SDLCALL Mix_FadeInChannelTimed(int channel, Mix_Chunk *chunk, int loops, int ms, int ticks);
+#define Mix_FadeInChannelVolume(channel,chunk,loops,ms,vol) Mix_FadeInChannelTimed(channel,chunk,loops,ms,-1,vol)/*MIXER-X*/
+extern DECLSPEC int SDLCALL Mix_FadeInChannelTimedVolume(int which, Mix_Chunk *chunk, int loops, int ms, int ticks, int volume);/*MIXER-X*/
+
+
+/* Set the volume in the range of 0-128 of a specific channel or chunk.
+ If the specified channel is -1, set volume for all channels.
+ Returns the original volume.
+ If the specified volume is -1, just return the current volume.
+*/
+extern DECLSPEC int SDLCALL Mix_Volume(int channel, int volume);
+extern DECLSPEC int SDLCALL Mix_VolumeChunk(Mix_Chunk *chunk, int volume);
+extern DECLSPEC int SDLCALL Mix_VolumeMusic(int volume);
+
+/* Halt playing of a particular channel */
+extern DECLSPEC int SDLCALL Mix_HaltChannel(int channel);
+extern DECLSPEC int SDLCALL Mix_HaltGroup(int tag);
+extern DECLSPEC int SDLCALL Mix_HaltMusic(void);
+
+/* Change the expiration delay for a particular channel.
+ The sample will stop playing after the 'ticks' milliseconds have elapsed,
+ or remove the expiration if 'ticks' is -1
+*/
+extern DECLSPEC int SDLCALL Mix_ExpireChannel(int channel, int ticks);
+
+/* Halt a channel, fading it out progressively till it's silent
+ The ms parameter indicates the number of milliseconds the fading
+ will take.
+ */
+extern DECLSPEC int SDLCALL Mix_FadeOutChannel(int which, int ms);
+extern DECLSPEC int SDLCALL Mix_FadeOutGroup(int tag, int ms);
+extern DECLSPEC int SDLCALL Mix_FadeOutMusic(int ms);
+
+/* Query the fading status of a channel */
+extern DECLSPEC Mix_Fading SDLCALL Mix_FadingMusic(void);
+extern DECLSPEC Mix_Fading SDLCALL Mix_FadingChannel(int which);
+
+/* Pause/Resume a particular channel */
+extern DECLSPEC void SDLCALL Mix_Pause(int channel);
+extern DECLSPEC void SDLCALL Mix_Resume(int channel);
+extern DECLSPEC int SDLCALL Mix_Paused(int channel);
+
+/* Pause/Resume the music stream */
+extern DECLSPEC void SDLCALL Mix_PauseMusic(void);
+extern DECLSPEC void SDLCALL Mix_ResumeMusic(void);
+extern DECLSPEC void SDLCALL Mix_RewindMusic(void);
+extern DECLSPEC int SDLCALL Mix_PausedMusic(void);
+
+/* Set the current position in the music stream.
+ This returns 0 if successful, or -1 if it failed or isn't implemented.
+ This function is only implemented for MOD music formats (set pattern
+ order number) and for WAV, OGG, FLAC, MP3_MAD, MP3_MPG, and MODPLUG music
+ (set position in seconds), at the moment.
+*/
+extern DECLSPEC int SDLCALL Mix_SetMusicPosition(double position);
+/*
+ Get the time current position of music stream
+ returns -1.0 if this feature is not supported for some codec
+ */
+extern DECLSPEC double SDLCALL Mix_GetMusicPosition(Mix_Music *music);
+/*
+ Get the total time length of music stream
+ returns -1.0 if this feature is not supported for some codec
+ */
+extern DECLSPEC double SDLCALL Mix_GetMusicTotalTime(Mix_Music *music);
+
+/*
+ Get the loop start time position of music stream
+ returns -1.0 if this feature is not used for this music or not supported for some codec
+ */
+extern DECLSPEC double SDLCALL Mix_GetMusicLoopStartTime(Mix_Music *music);
+/*
+ Get the loop end time position of music stream
+ returns -1.0 if this feature is not used for this music or not supported for some codec
+ */
+extern DECLSPEC double SDLCALL Mix_GetMusicLoopEndTime(Mix_Music *music);
+/*
+ Get the loop time length of music stream
+ returns -1.0 if this feature is not used for this music or not supported for some codec
+ */
+extern DECLSPEC double SDLCALL Mix_GetMusicLoopLengthTime(Mix_Music *music);
+
+
+/* Check the status of a specific channel.
+ If the specified channel is -1, check all channels.
+*/
+extern DECLSPEC int SDLCALL Mix_Playing(int channel);
+extern DECLSPEC int SDLCALL Mix_PlayingMusic(void);
+
+/* Stop music and set external music playback command */
+extern DECLSPEC int SDLCALL Mix_SetMusicCMD(const char *command);
+
+/* Synchro value is set by MikMod from modules while playing */
+extern DECLSPEC int SDLCALL Mix_SetSynchroValue(int value);
+extern DECLSPEC int SDLCALL Mix_GetSynchroValue(void);
+
+/* Set/Get/Iterate SoundFonts paths to use by supported MIDI backends */
+extern DECLSPEC int SDLCALL Mix_SetSoundFonts(const char *paths);
+extern DECLSPEC const char* SDLCALL Mix_GetSoundFonts(void);
+extern DECLSPEC int SDLCALL Mix_EachSoundFont(int (SDLCALL *function)(const char*, void*), void *data);
+
+/* Get the Mix_Chunk currently associated with a mixer channel
+ Returns NULL if it's an invalid channel, or there's no chunk associated.
+*/
+extern DECLSPEC Mix_Chunk * SDLCALL Mix_GetChunk(int channel);
+
+/* Close the mixer, halting all playing audio */
+extern DECLSPEC void SDLCALL Mix_CloseAudio(void);
+
+/* Add additional Timidity bank path */
+extern DECLSPEC void SDLCALL Mix_Timidity_addToPathList(const char *path);
+
+/* ADLMIDI Setup functions */
+/* Get count of available hardcoded banks */
+extern DECLSPEC int SDLCALL Mix_ADLMIDI_getTotalBanks(void);
+/* Get array of the bank names */
+extern DECLSPEC const char *const *SDLCALL Mix_ADLMIDI_getBankNames(void);
+/* Get bank ID */
+extern DECLSPEC int SDLCALL Mix_ADLMIDI_getBankID(void);
+/* Set bank ID (Applying on stop/play) */
+extern DECLSPEC void SDLCALL Mix_ADLMIDI_setBankID(int bnk);
+/* Get state of deep vibrato */
+extern DECLSPEC int SDLCALL Mix_ADLMIDI_getTremolo(void);
+/* Set deep tremolo mode (0 off, 1 on) (Applying on stop/play) */
+extern DECLSPEC void SDLCALL Mix_ADLMIDI_setTremolo(int tr);
+/* Get state of deep vibrato */
+extern DECLSPEC int SDLCALL Mix_ADLMIDI_getVibrato(void);
+/* Set deep vibrato mode (0 off, 1 on) (Applying on stop/play) */
+extern DECLSPEC void SDLCALL Mix_ADLMIDI_setVibrato(int vib);
+/* Get state of scalable modulation mode */
+extern DECLSPEC int SDLCALL Mix_ADLMIDI_getScaleMod(void);
+/* Set scalable modulation mode (0 off, 1 on) (Applying on stop/play) */
+extern DECLSPEC void SDLCALL Mix_ADLMIDI_setScaleMod(int sc);
+/* Get state of adlib drums mode */
+extern DECLSPEC int SDLCALL Mix_ADLMIDI_getAdLibMode(void);
+/* Set adlib drums mode mode (0 off, 1 on) (Applying on stop/play) */
+extern DECLSPEC void SDLCALL Mix_ADLMIDI_setAdLibMode(int tr);
+/* Get state of logarithmic mode */
+extern DECLSPEC int SDLCALL Mix_ADLMIDI_getLogarithmicVolumes(void);
+/* Set logarithmic volumes mode in the generic/CMF volume models (0 off, 1 on) (Applying on stop/play) */
+extern DECLSPEC void SDLCALL Mix_ADLMIDI_setLogarithmicVolumes(int lv);
+/* Get current volume model ID */
+extern DECLSPEC int SDLCALL Mix_ADLMIDI_getVolumeModel(void);
+/* Change current volumes model (Applying on stop/play) */
+extern DECLSPEC void SDLCALL Mix_ADLMIDI_setVolumeModel(int vm);
+/* Get full range mode for CC74-Brightness controller */
+extern DECLSPEC int SDLCALL Mix_ADLMIDI_getFullRangeBrightness(void);
+/* Set full range mode for CC74-Brightness controller */
+extern DECLSPEC void SDLCALL Mix_ADLMIDI_setFullRangeBrightness(int frb);
+/* Get the current OPL3 Emulator for ADLMIDI */
+extern DECLSPEC int SDLCALL Mix_ADLMIDI_getEmulator(void);
+/* Select the OPL3 Emulator for ADLMIDI */
+extern DECLSPEC void SDLCALL Mix_ADLMIDI_setEmulator(int emu);
+/* Reset all ADLMIDI properties to default state */
+extern DECLSPEC void SDLCALL Mix_ADLMIDI_setSetDefaults(void);
+
+/* Sets WOPL bank file for ADLMIDI playing device, affects on MIDI file reopen */
+extern DECLSPEC void SDLCALL Mix_ADLMIDI_setCustomBankFile(const char *bank_wonl_path);
+
+/* Reset all OPNMIDI properties to default state */
+extern DECLSPEC void SDLCALL Mix_OPNMIDI_setSetDefaults(void);
+/* Get full range mode for CC74-Brightness controller */
+extern DECLSPEC int SDLCALL Mix_OPNMIDI_getFullRangeBrightness(void);
+/* Set full range mode for CC74-Brightness controller */
+extern DECLSPEC void SDLCALL Mix_OPNMIDI_setFullRangeBrightness(int frb);
+/* Get the OPN2 Emulator for OPNMIDI */
+extern DECLSPEC int SDLCALL Mix_OPNMIDI_getEmulator(void);
+/* Select the OPN2 Emulator for OPNMIDI */
+extern DECLSPEC void SDLCALL Mix_OPNMIDI_setEmulator(int emu);
+/* Sets WOPN bank file for OPNMIDI playing device, affects on MIDI file reopen */
+extern DECLSPEC void SDLCALL Mix_OPNMIDI_setCustomBankFile(const char *bank_wonp_path);
+
+/* Get type of MIDI player library currently in use */
+extern DECLSPEC int SDLCALL Mix_GetMidiPlayer(void);
+
+/* Get type of MIDI player library prepared for next opening of MIDI file */
+extern DECLSPEC int SDLCALL Mix_GetNextMidiPlayer(void);
+
+/* Set the MIDI playing library (ADLMIDI, Timidity, Native MIDI (if available) and FluidSynth) */
+extern DECLSPEC int SDLCALL Mix_SetMidiPlayer(int player);
+
+/* Disables support of MIDI file arguments */
+extern DECLSPEC void SDLCALL Mix_SetLockMIDIArgs(int lock_midiargs);
+
+/* DEPRECATED NAMES for new-added SDL Mixer X functions
+ Those names are made with mistake - beginning with "MIX_" than "Mix_"
+ which makes confusion when you looking for Mix_ function in your IDE
+ because some applications are still use them, to don't break ABI we will keep those
+ aliases until we will remove all usages of them from applications and libraries are used them
+*/
+DEPRECATED(extern DECLSPEC int SDLCALL Mix_GetMidiDevice(void));
+DEPRECATED(extern DECLSPEC int SDLCALL Mix_GetNextMidiDevice(void));
+DEPRECATED(extern DECLSPEC int SDLCALL Mix_SetMidiDevice(int player));
+
+/* We'll use SDL for reporting errors */
+#define Mix_SetError SDL_SetError
+#define Mix_GetError SDL_GetError
+#define Mix_ClearError SDL_ClearError
+
+/* Ends C function definitions when using C++ */
+#ifdef __cplusplus
+}
+#endif
+#include "close_code.h"
+
+#endif /* SDL_MIXER_H_ */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/libs/SDLMixerX/i686-w64-mingw32/include/SDL2/begin_code.h b/libs/SDLMixerX/i686-w64-mingw32/include/SDL2/begin_code.h
new file mode 100644
index 000000000..6c2106246
--- /dev/null
+++ b/libs/SDLMixerX/i686-w64-mingw32/include/SDL2/begin_code.h
@@ -0,0 +1,167 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+/**
+ * \file begin_code.h
+ *
+ * This file sets things up for C dynamic library function definitions,
+ * static inlined functions, and structures aligned at 4-byte alignment.
+ * If you don't like ugly C preprocessor code, don't look at this file. :)
+ */
+
+/* This shouldn't be nested -- included it around code only. */
+#ifdef _begin_code_h
+#error Nested inclusion of begin_code.h
+#endif
+#define _begin_code_h
+
+#ifndef SDL_DEPRECATED
+# if (__GNUC__ >= 4) /* technically, this arrived in gcc 3.1, but oh well. */
+# define SDL_DEPRECATED __attribute__((deprecated))
+# else
+# define SDL_DEPRECATED
+# endif
+#endif
+
+#ifndef SDL_UNUSED
+# ifdef __GNUC__
+# define SDL_UNUSED __attribute__((unused))
+# else
+# define SDL_UNUSED
+# endif
+#endif
+
+/* Some compilers use a special export keyword */
+#ifndef DECLSPEC
+# if defined(__WIN32__) || defined(__WINRT__)
+# ifdef __BORLANDC__
+# ifdef BUILD_SDL
+# define DECLSPEC
+# else
+# define DECLSPEC __declspec(dllimport)
+# endif
+# else
+# define DECLSPEC __declspec(dllexport)
+# endif
+# elif defined(__OS2__)
+# ifdef BUILD_SDL
+# define DECLSPEC __declspec(dllexport)
+# else
+# define DECLSPEC
+# endif
+# else
+# if defined(__GNUC__) && __GNUC__ >= 4
+# define DECLSPEC __attribute__ ((visibility("default")))
+# else
+# define DECLSPEC
+# endif
+# endif
+#endif
+
+/* By default SDL uses the C calling convention */
+#ifndef SDLCALL
+#if (defined(__WIN32__) || defined(__WINRT__)) && !defined(__GNUC__)
+#define SDLCALL __cdecl
+#elif defined(__OS2__) || defined(__EMX__)
+#define SDLCALL _System
+# if defined (__GNUC__) && !defined(_System)
+# define _System /* for old EMX/GCC compat. */
+# endif
+#else
+#define SDLCALL
+#endif
+#endif /* SDLCALL */
+
+/* Removed DECLSPEC on Symbian OS because SDL cannot be a DLL in EPOC */
+#ifdef __SYMBIAN32__
+#undef DECLSPEC
+#define DECLSPEC
+#endif /* __SYMBIAN32__ */
+
+/* Force structure packing at 4 byte alignment.
+ This is necessary if the header is included in code which has structure
+ packing set to an alternate value, say for loading structures from disk.
+ The packing is reset to the previous value in close_code.h
+ */
+#if defined(_MSC_VER) || defined(__MWERKS__) || defined(__BORLANDC__)
+#ifdef _MSC_VER
+#pragma warning(disable: 4103)
+#endif
+#ifdef __BORLANDC__
+#pragma nopackwarning
+#endif
+#ifdef _M_X64
+/* Use 8-byte alignment on 64-bit architectures, so pointers are aligned */
+#pragma pack(push,8)
+#else
+#pragma pack(push,4)
+#endif
+#endif /* Compiler needs structure packing set */
+
+#ifndef SDL_INLINE
+#if defined(__GNUC__)
+#define SDL_INLINE __inline__
+#elif defined(_MSC_VER) || defined(__BORLANDC__) || \
+ defined(__DMC__) || defined(__SC__) || \
+ defined(__WATCOMC__) || defined(__LCC__) || \
+ defined(__DECC) || defined(__CC_ARM)
+#define SDL_INLINE __inline
+#ifndef __inline__
+#define __inline__ __inline
+#endif
+#else
+#define SDL_INLINE inline
+#ifndef __inline__
+#define __inline__ inline
+#endif
+#endif
+#endif /* SDL_INLINE not defined */
+
+#ifndef SDL_FORCE_INLINE
+#if defined(_MSC_VER)
+#define SDL_FORCE_INLINE __forceinline
+#elif ( (defined(__GNUC__) && (__GNUC__ >= 4)) || defined(__clang__) )
+#define SDL_FORCE_INLINE __attribute__((always_inline)) static __inline__
+#else
+#define SDL_FORCE_INLINE static SDL_INLINE
+#endif
+#endif /* SDL_FORCE_INLINE not defined */
+
+#ifndef SDL_NORETURN
+#if defined(__GNUC__)
+#define SDL_NORETURN __attribute__((noreturn))
+#elif defined(_MSC_VER)
+#define SDL_NORETURN __declspec(noreturn)
+#else
+#define SDL_NORETURN
+#endif
+#endif /* SDL_NORETURN not defined */
+
+/* Apparently this is needed by several Windows compilers */
+#if !defined(__MACH__)
+#ifndef NULL
+#ifdef __cplusplus
+#define NULL 0
+#else
+#define NULL ((void *)0)
+#endif
+#endif /* NULL */
+#endif /* ! Mac OS X - breaks precompiled headers */
diff --git a/libs/SDLMixerX/i686-w64-mingw32/include/SDL2/close_code.h b/libs/SDLMixerX/i686-w64-mingw32/include/SDL2/close_code.h
new file mode 100644
index 000000000..b3b70a4c8
--- /dev/null
+++ b/libs/SDLMixerX/i686-w64-mingw32/include/SDL2/close_code.h
@@ -0,0 +1,37 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+/**
+ * \file close_code.h
+ *
+ * This file reverses the effects of begin_code.h and should be included
+ * after you finish any function and structure declarations in your headers
+ */
+
+#undef _begin_code_h
+
+/* Reset structure packing at previous byte alignment */
+#if defined(_MSC_VER) || defined(__MWERKS__) || defined(__BORLANDC__)
+#ifdef __BORLANDC__
+#pragma nopackwarning
+#endif
+#pragma pack(pop)
+#endif /* Compiler needs structure packing set */
diff --git a/libs/SDLMixerX/i686-w64-mingw32/lib/libSDL2_mixer_ext-static.a b/libs/SDLMixerX/i686-w64-mingw32/lib/libSDL2_mixer_ext-static.a
new file mode 100644
index 000000000..8a59b5a61
Binary files /dev/null and b/libs/SDLMixerX/i686-w64-mingw32/lib/libSDL2_mixer_ext-static.a differ
diff --git a/libs/SDLMixerX/i686-w64-mingw32/lib/libSDL2_mixer_ext.dll.a b/libs/SDLMixerX/i686-w64-mingw32/lib/libSDL2_mixer_ext.dll.a
new file mode 100644
index 000000000..b5e43ef62
Binary files /dev/null and b/libs/SDLMixerX/i686-w64-mingw32/lib/libSDL2_mixer_ext.dll.a differ
diff --git a/libs/SDLMixerX/x86_64-w64-mingw32/bin/SDL2_mixer_ext.dll b/libs/SDLMixerX/x86_64-w64-mingw32/bin/SDL2_mixer_ext.dll
new file mode 100644
index 000000000..7762d5e8d
Binary files /dev/null and b/libs/SDLMixerX/x86_64-w64-mingw32/bin/SDL2_mixer_ext.dll differ
diff --git a/libs/SDLMixerX/x86_64-w64-mingw32/bin/libfluidsynth-2.dll b/libs/SDLMixerX/x86_64-w64-mingw32/bin/libfluidsynth-2.dll
new file mode 100644
index 000000000..5dbcac34a
Binary files /dev/null and b/libs/SDLMixerX/x86_64-w64-mingw32/bin/libfluidsynth-2.dll differ
diff --git a/libs/SDLMixerX/x86_64-w64-mingw32/bin/libgcc_s_sjlj-1.dll b/libs/SDLMixerX/x86_64-w64-mingw32/bin/libgcc_s_sjlj-1.dll
new file mode 100644
index 000000000..9684a2155
Binary files /dev/null and b/libs/SDLMixerX/x86_64-w64-mingw32/bin/libgcc_s_sjlj-1.dll differ
diff --git a/libs/SDLMixerX/x86_64-w64-mingw32/bin/libstdc++-6.dll b/libs/SDLMixerX/x86_64-w64-mingw32/bin/libstdc++-6.dll
new file mode 100644
index 000000000..220099c40
Binary files /dev/null and b/libs/SDLMixerX/x86_64-w64-mingw32/bin/libstdc++-6.dll differ
diff --git a/libs/SDLMixerX/x86_64-w64-mingw32/include/SDL2/SDL_mixer_ext.h b/libs/SDLMixerX/x86_64-w64-mingw32/include/SDL2/SDL_mixer_ext.h
new file mode 100644
index 000000000..3a6b91b50
--- /dev/null
+++ b/libs/SDLMixerX/x86_64-w64-mingw32/include/SDL2/SDL_mixer_ext.h
@@ -0,0 +1,867 @@
+/*
+ SDL Mixer X: An extended audio mixer library, forked from SDL_mixer
+ Copyright (C) 2014-2018 Vitaly Novichkov
+
+ SDL_mixer: An audio mixer library based on the SDL library
+ Copyright (C) 1997-2018 Sam Lantinga
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#ifndef SDL_MIXER_H_
+#define SDL_MIXER_H_
+
+#include "SDL_stdinc.h"
+#include "SDL_rwops.h"
+#include "SDL_audio.h"
+#include "SDL_endian.h"
+#include "SDL_version.h"
+#include "begin_code.h"
+
+/* Let applications recogonize which SDL Mixer edition is in use: Official or Extended fork by Wohlstand */
+#define SDL_MIXER_X 1
+
+#define MIXSDLCALL
+
+#if defined(FORCE_STDCALLS) && defined(_WIN32)
+#ifdef SDLCALL
+#undef SDLCALL
+#endif
+#define SDLCALL __stdcall
+#define SDLCALLCC __stdcall
+#else
+#define SDLCALLCC
+#endif
+
+#ifndef DEPRECATED
+#ifdef __GNUC__
+#define DEPRECATED(func) func __attribute__ ((deprecated))
+#elif defined(_MSC_VER)
+#define DEPRECATED(func) __declspec(deprecated) func
+#else
+#pragma message("WARNING: You need to implement DEPRECATED for this compiler")
+#define DEPRECATED(func) func
+#endif
+#endif
+
+/* Set up for C function definitions, even when using C++ */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Printable format: "%d.%d.%d", MAJOR, MINOR, PATCHLEVEL
+*/
+#define SDL_MIXER_MAJOR_VERSION 2
+#define SDL_MIXER_MINOR_VERSION 2
+#define SDL_MIXER_PATCHLEVEL 0
+
+/* This macro can be used to fill a version structure with the compile-time
+ * version of the SDL_mixer library.
+ */
+#define SDL_MIXER_VERSION(X) \
+{ \
+ (X)->major = SDL_MIXER_MAJOR_VERSION; \
+ (X)->minor = SDL_MIXER_MINOR_VERSION; \
+ (X)->patch = SDL_MIXER_PATCHLEVEL; \
+}
+
+/* Backwards compatibility */
+#define MIX_MAJOR_VERSION SDL_MIXER_MAJOR_VERSION
+#define MIX_MINOR_VERSION SDL_MIXER_MINOR_VERSION
+#define MIX_PATCHLEVEL SDL_MIXER_PATCHLEVEL
+#define MIX_VERSION(X) SDL_MIXER_VERSION(X)
+
+/**
+ * This is the version number macro for the current SDL_mixer version.
+ */
+#define SDL_MIXER_COMPILEDVERSION \
+ SDL_VERSIONNUM(SDL_MIXER_MAJOR_VERSION, SDL_MIXER_MINOR_VERSION, SDL_MIXER_PATCHLEVEL)
+
+/**
+ * This macro will evaluate to true if compiled with SDL_mixer at least X.Y.Z.
+ */
+#define SDL_MIXER_VERSION_ATLEAST(X, Y, Z) \
+ (SDL_MIXER_COMPILEDVERSION >= SDL_VERSIONNUM(X, Y, Z))
+
+/* This function gets the version of the dynamically linked SDL_mixer library.
+ it should NOT be used to fill a version structure, instead you should
+ use the SDL_MIXER_VERSION() macro.
+ */
+extern DECLSPEC const SDL_version * SDLCALL Mix_Linked_Version(void);
+
+typedef enum
+{
+ MIX_INIT_FLAC = 0x00000001,
+ MIX_INIT_MOD = 0x00000002,
+ MIX_INIT_MP3 = 0x00000008,
+ MIX_INIT_OGG = 0x00000010,
+ MIX_INIT_MID = 0x00000020,
+ MIX_INIT_OPUS = 0x00000040
+} MIX_InitFlags;
+
+/* Loads dynamic libraries and prepares them for use. Flags should be
+ one or more flags from MIX_InitFlags OR'd together.
+ It returns the flags successfully initialized, or 0 on failure.
+ */
+extern DECLSPEC int SDLCALL Mix_Init(int flags);
+
+/* Unloads libraries loaded with Mix_Init */
+extern DECLSPEC void SDLCALL Mix_Quit(void);
+
+
+/* The default mixer has 8 simultaneous mixing channels */
+#ifndef MIX_CHANNELS
+#define MIX_CHANNELS 8
+#endif
+
+/* Good default values for a PC soundcard */
+#define MIX_DEFAULT_FREQUENCY 44100
+#if SDL_BYTEORDER == SDL_LIL_ENDIAN
+#define MIX_DEFAULT_FORMAT AUDIO_S16LSB
+#else
+#define MIX_DEFAULT_FORMAT AUDIO_S16MSB
+#endif
+#define MIX_DEFAULT_CHANNELS 2
+#define MIX_MAX_VOLUME SDL_MIX_MAXVOLUME /* Volume of a chunk */
+
+/* The internal format for an audio chunk */
+typedef struct Mix_Chunk {
+ int allocated;
+ Uint8 *abuf;
+ Uint32 alen;
+ Uint8 volume; /* Per-sample volume, 0-128 */
+} Mix_Chunk;
+
+/* The different fading types supported */
+typedef enum {
+ MIX_NO_FADING,
+ MIX_FADING_OUT,
+ MIX_FADING_IN
+} Mix_Fading;
+
+/* These are types of music files (not libraries used to load them) */
+typedef enum {
+ MUS_NONE,
+ MUS_CMD,
+ MUS_WAV,
+ MUS_MOD,
+ MUS_MID,
+ MUS_OGG,
+ MUS_MP3,
+ MUS_MP3_MAD_UNUSED,
+ MUS_FLAC,
+ MUS_MODPLUG_UNUSED,
+ MUS_OPUS,
+ MUS_GME,
+ MUS_ADLMIDI/*Use ADLMIDI coded for super-special formats like IMF, MUS or XMI are can't be played without ADLMIDI*/
+} Mix_MusicType;
+
+typedef enum {
+ MIDI_ADLMIDI,
+ MIDI_Native,
+ MIDI_Timidity,
+ MIDI_OPNMIDI,
+ MIDI_Fluidsynth,
+ MIDI_ANY,
+ MIDI_KnuwnDevices /* Count of MIDI device types */
+} Mix_MIDI_Device;
+
+/* Volume model type in the ADLMIDI */
+typedef enum {
+ ADLMIDI_VM_AUTO,
+ ADLMIDI_VM_GENERIC,
+ ADLMIDI_VM_CMF,
+ ADLMIDI_VM_DMX,
+ ADLMIDI_VM_APOGEE,
+ ADLMIDI_VM_9X
+} Mix_ADLMIDI_VolumeModel;
+
+/* OPL3 chip emulators for ADLMIDI */
+typedef enum {
+ ADLMIDI_OPL3_EMU_DEFAULT = -1,
+ ADLMIDI_OPL3_EMU_NUKED = 0,
+ ADLMIDI_OPL3_EMU_NUKED_1_7_4,
+ ADLMIDI_OPL3_EMU_DOSBOX,
+} Mix_ADLMIDI_Emulator;
+
+/* OPN2 chip emulators for OPNMIDI */
+typedef enum {
+ OPNMIDI_OPN2_EMU_DEFAULT = -1,
+ OPNMIDI_OPN2_EMU_MIME = 0,
+ OPNMIDI_OPN2_EMU_NUKED,
+ OPNMIDI_OPN2_EMU_GENS,
+} Mix_OPNMIDI_Emulator;
+
+/* The internal format for a music chunk interpreted via mikmod */
+typedef struct _Mix_Music Mix_Music;
+
+/* Open the mixer with a certain audio format */
+extern DECLSPEC int SDLCALL Mix_OpenAudio(int frequency, Uint16 format, int channels, int chunksize);
+
+/* Open the mixer with specific device and certain audio format */
+extern DECLSPEC int SDLCALL Mix_OpenAudioDevice(int frequency, Uint16 format, int channels, int chunksize, const char* device, int allowed_changes);
+
+/* Dynamically change the number of channels managed by the mixer.
+ If decreasing the number of channels, the upper channels are
+ stopped.
+ This function returns the new number of allocated channels.
+ */
+extern DECLSPEC int SDLCALL Mix_AllocateChannels(int numchans);
+
+/* Find out what the actual audio device parameters are.
+ This function returns 1 if the audio has been opened, 0 otherwise.
+ */
+extern DECLSPEC int SDLCALL Mix_QuerySpec(int *frequency,Uint16 *format,int *channels);
+
+/* Load a wave file or a music (.mod .s3m .it .xm) file
+ IMPORTANT: To choice a track number of NSF, GBM, HES, etc file,
+ you must append "|xxx" to end of file path for
+ Mix_LoadMUS function.
+ Where xxx - actual number of chip track, (from 0 to N-1)
+ Examples: "file.nsf|12", "file.hes|2"
+*/
+extern DECLSPEC Mix_Chunk * SDLCALL Mix_LoadWAV_RW(SDL_RWops *src, int freesrc);
+#define Mix_LoadWAV(file) Mix_LoadWAV_RW(SDL_RWFromFile(file, "rb"), 1)
+extern DECLSPEC Mix_Music * SDLCALL Mix_LoadMUS(const char *file);
+
+/* Load a music file from an SDL_RWop object
+ * Matt Campbell (matt@campbellhome.dhs.org) April 2000 */
+extern DECLSPEC Mix_Music * SDLCALL Mix_LoadMUS_RW(SDL_RWops *src, int freesrc);
+
+/* Load a music file from an SDL_RWop object with custom arguments (trackID for GME or settings for a MIDI playing)
+ * Arguments are taking no effect for file formats which are not supports extra arguments.
+ */
+extern DECLSPEC Mix_Music *SDLCALL Mix_LoadMUS_RW_ARG(SDL_RWops *src, int freesrc, const char *args);
+
+/* Load a music file from an SDL_RWop object with custom trackID for GME.
+ * trackID argument takes no effect for non-NSF,HES,GBM,etc. file formats.
+ * Default value should be 0
+ */
+extern DECLSPEC Mix_Music *SDLCALL Mix_LoadMUS_RW_GME(SDL_RWops *src, int freesrc, int trackID);
+
+/* Load a music file from an SDL_RWop object assuming a specific format */
+extern DECLSPEC Mix_Music * SDLCALL Mix_LoadMUSType_RW(SDL_RWops *src, Mix_MusicType type, int freesrc);
+
+/* Load a music file from an SDL_RWop object assuming a specific format
+ with custom arguments (trackID for GME or settings for a MIDI playing) */
+extern DECLSPEC Mix_Music * SDLCALL Mix_LoadMUSType_RW_ARG(SDL_RWops *src, Mix_MusicType type, int freesrc, const char *args);
+
+/* Load a wave file of the mixer format from a memory buffer */
+extern DECLSPEC Mix_Chunk * SDLCALL Mix_QuickLoad_WAV(Uint8 *mem);
+
+/* Load raw audio data of the mixer format from a memory buffer */
+extern DECLSPEC Mix_Chunk * SDLCALL Mix_QuickLoad_RAW(Uint8 *mem, Uint32 len);
+
+/* Free an audio chunk previously loaded */
+extern DECLSPEC void SDLCALL Mix_FreeChunk(Mix_Chunk *chunk);
+extern DECLSPEC void SDLCALL Mix_FreeMusic(Mix_Music *music);
+
+/* Get a list of chunk/music decoders that this build of SDL_mixer provides.
+ This list can change between builds AND runs of the program, if external
+ libraries that add functionality become available.
+ You must successfully call Mix_OpenAudio() before calling these functions.
+ This API is only available in SDL_mixer 1.2.9 and later.
+
+ // usage...
+ int i;
+ const int total = Mix_GetNumChunkDecoders();
+ for (i = 0; i < total; i++)
+ printf("Supported chunk decoder: [%s]\n", Mix_GetChunkDecoder(i));
+
+ Appearing in this list doesn't promise your specific audio file will
+ decode...but it's handy to know if you have, say, a functioning Timidity
+ install.
+
+ These return values are static, read-only data; do not modify or free it.
+ The pointers remain valid until you call Mix_CloseAudio().
+*/
+extern DECLSPEC int SDLCALL Mix_GetNumChunkDecoders(void);
+extern DECLSPEC const char * SDLCALL Mix_GetChunkDecoder(int index);
+extern DECLSPEC SDL_bool SDLCALL Mix_HasChunkDecoder(const char *name);
+extern DECLSPEC int SDLCALL Mix_GetNumMusicDecoders(void);
+extern DECLSPEC const char * SDLCALL Mix_GetMusicDecoder(int index);
+extern DECLSPEC SDL_bool SDLCALL Mix_HasMusicDecoder(const char *name);
+
+/* Find out the music format of a mixer music, or the currently playing
+ music, if 'music' is NULL.
+*/
+extern DECLSPEC Mix_MusicType SDLCALL Mix_GetMusicType(const Mix_Music *music);
+
+/* Get music title from meta-tag if possible. If title tag is empty, filename will be returned */
+extern DECLSPEC const char *SDLCALL Mix_GetMusicTitle(const Mix_Music *music);
+/* Get music title from meta-tag if possible */
+extern DECLSPEC const char *SDLCALL Mix_GetMusicTitleTag(const Mix_Music *music);
+/* Get music artist from meta-tag if possible */
+extern DECLSPEC const char *SDLCALL Mix_GetMusicArtistTag(const Mix_Music *music);
+/* Get music album from meta-tag if possible */
+extern DECLSPEC const char *SDLCALL Mix_GetMusicAlbumTag(const Mix_Music *music);
+/* Get music copyright from meta-tag if possible */
+extern DECLSPEC const char *SDLCALL Mix_GetMusicCopyrightTag(const Mix_Music *music);
+
+/* Set a function that is called after all mixing is performed.
+ This can be used to provide real-time visual display of the audio stream
+ or add a custom mixer filter for the stream data.
+*/
+extern DECLSPEC void SDLCALL Mix_SetPostMix(void (SDLCALL *mix_func)(void *udata, Uint8 *stream, int len), void *arg);
+
+/* Add your own music player or additional mixer function.
+ If 'mix_func' is NULL, the default music player is re-enabled.
+ */
+extern DECLSPEC void SDLCALL Mix_HookMusic(void (SDLCALL *mix_func)(void *udata, Uint8 *stream, int len), void *arg);
+
+/* Add your own callback for when the music has finished playing or when it is
+ * stopped from a call to Mix_HaltMusic.
+ */
+extern DECLSPEC void SDLCALL Mix_HookMusicFinished(void (SDLCALL *music_finished)(void));
+
+/* Get a pointer to the user data for the current music hook */
+extern DECLSPEC void * SDLCALL Mix_GetMusicHookData(void);
+
+/*
+ * Add your own callback when a channel has finished playing. NULL
+ * to disable callback. The callback may be called from the mixer's audio
+ * callback or it could be called as a result of Mix_HaltChannel(), etc.
+ * do not call SDL_LockAudio() from this callback; you will either be
+ * inside the audio callback, or SDL_mixer will explicitly lock the audio
+ * before calling your callback.
+ */
+extern DECLSPEC void SDLCALL Mix_ChannelFinished(void (SDLCALL *channel_finished)(int channel));
+
+
+/* Special Effects API by ryan c. gordon. (icculus@icculus.org) */
+
+#define MIX_CHANNEL_POST -2
+
+/* This is the format of a special effect callback:
+ *
+ * myeffect(int chan, void *stream, int len, void *udata);
+ *
+ * (chan) is the channel number that your effect is affecting. (stream) is
+ * the buffer of data to work upon. (len) is the size of (stream), and
+ * (udata) is a user-defined bit of data, which you pass as the last arg of
+ * Mix_RegisterEffect(), and is passed back unmolested to your callback.
+ * Your effect changes the contents of (stream) based on whatever parameters
+ * are significant, or just leaves it be, if you prefer. You can do whatever
+ * you like to the buffer, though, and it will continue in its changed state
+ * down the mixing pipeline, through any other effect functions, then finally
+ * to be mixed with the rest of the channels and music for the final output
+ * stream.
+ *
+ * DO NOT EVER call SDL_LockAudio() from your callback function!
+ */
+typedef void (SDLCALL *Mix_EffectFunc_t)(int chan, void *stream, int len, void *udata);
+
+/*
+ * This is a callback that signifies that a channel has finished all its
+ * loops and has completed playback. This gets called if the buffer
+ * plays out normally, or if you call Mix_HaltChannel(), implicitly stop
+ * a channel via Mix_AllocateChannels(), or unregister a callback while
+ * it's still playing.
+ *
+ * DO NOT EVER call SDL_LockAudio() from your callback function!
+ */
+typedef void (SDLCALL *Mix_EffectDone_t)(int chan, void *udata);
+
+
+/* Register a special effect function. At mixing time, the channel data is
+ * copied into a buffer and passed through each registered effect function.
+ * After it passes through all the functions, it is mixed into the final
+ * output stream. The copy to buffer is performed once, then each effect
+ * function performs on the output of the previous effect. Understand that
+ * this extra copy to a buffer is not performed if there are no effects
+ * registered for a given chunk, which saves CPU cycles, and any given
+ * effect will be extra cycles, too, so it is crucial that your code run
+ * fast. Also note that the data that your function is given is in the
+ * format of the sound device, and not the format you gave to Mix_OpenAudio(),
+ * although they may in reality be the same. This is an unfortunate but
+ * necessary speed concern. Use Mix_QuerySpec() to determine if you can
+ * handle the data before you register your effect, and take appropriate
+ * actions.
+ * You may also specify a callback (Mix_EffectDone_t) that is called when
+ * the channel finishes playing. This gives you a more fine-grained control
+ * than Mix_ChannelFinished(), in case you need to free effect-specific
+ * resources, etc. If you don't need this, you can specify NULL.
+ * You may set the callbacks before or after calling Mix_PlayChannel().
+ * Things like Mix_SetPanning() are just internal special effect functions,
+ * so if you are using that, you've already incurred the overhead of a copy
+ * to a separate buffer, and that these effects will be in the queue with
+ * any functions you've registered. The list of registered effects for a
+ * channel is reset when a chunk finishes playing, so you need to explicitly
+ * set them with each call to Mix_PlayChannel*().
+ * You may also register a special effect function that is to be run after
+ * final mixing occurs. The rules for these callbacks are identical to those
+ * in Mix_RegisterEffect, but they are run after all the channels and the
+ * music have been mixed into a single stream, whereas channel-specific
+ * effects run on a given channel before any other mixing occurs. These
+ * global effect callbacks are call "posteffects". Posteffects only have
+ * their Mix_EffectDone_t function called when they are unregistered (since
+ * the main output stream is never "done" in the same sense as a channel).
+ * You must unregister them manually when you've had enough. Your callback
+ * will be told that the channel being mixed is (MIX_CHANNEL_POST) if the
+ * processing is considered a posteffect.
+ *
+ * After all these effects have finished processing, the callback registered
+ * through Mix_SetPostMix() runs, and then the stream goes to the audio
+ * device.
+ *
+ * DO NOT EVER call SDL_LockAudio() from your callback function!
+ *
+ * returns zero if error (no such channel), nonzero if added.
+ * Error messages can be retrieved from Mix_GetError().
+ */
+extern DECLSPEC int SDLCALL Mix_RegisterEffect(int chan, Mix_EffectFunc_t f, Mix_EffectDone_t d, void *arg);
+
+
+/* You may not need to call this explicitly, unless you need to stop an
+ * effect from processing in the middle of a chunk's playback.
+ * Posteffects are never implicitly unregistered as they are for channels,
+ * but they may be explicitly unregistered through this function by
+ * specifying MIX_CHANNEL_POST for a channel.
+ * returns zero if error (no such channel or effect), nonzero if removed.
+ * Error messages can be retrieved from Mix_GetError().
+ */
+extern DECLSPEC int SDLCALL Mix_UnregisterEffect(int channel, Mix_EffectFunc_t f);
+
+
+/* You may not need to call this explicitly, unless you need to stop all
+ * effects from processing in the middle of a chunk's playback. Note that
+ * this will also shut off some internal effect processing, since
+ * Mix_SetPanning() and others may use this API under the hood. This is
+ * called internally when a channel completes playback.
+ * Posteffects are never implicitly unregistered as they are for channels,
+ * but they may be explicitly unregistered through this function by
+ * specifying MIX_CHANNEL_POST for a channel.
+ * returns zero if error (no such channel), nonzero if all effects removed.
+ * Error messages can be retrieved from Mix_GetError().
+ */
+extern DECLSPEC int SDLCALL Mix_UnregisterAllEffects(int channel);
+
+
+#define MIX_EFFECTSMAXSPEED "MIX_EFFECTSMAXSPEED"
+
+/*
+ * These are the internally-defined mixing effects. They use the same API that
+ * effects defined in the application use, but are provided here as a
+ * convenience. Some effects can reduce their quality or use more memory in
+ * the name of speed; to enable this, make sure the environment variable
+ * MIX_EFFECTSMAXSPEED (see above) is defined before you call
+ * Mix_OpenAudio().
+ */
+
+
+/* Set the panning of a channel. The left and right channels are specified
+ * as integers between 0 and 255, quietest to loudest, respectively.
+ *
+ * Technically, this is just individual volume control for a sample with
+ * two (stereo) channels, so it can be used for more than just panning.
+ * If you want real panning, call it like this:
+ *
+ * Mix_SetPanning(channel, left, 255 - left);
+ *
+ * ...which isn't so hard.
+ *
+ * Setting (channel) to MIX_CHANNEL_POST registers this as a posteffect, and
+ * the panning will be done to the final mixed stream before passing it on
+ * to the audio device.
+ *
+ * This uses the Mix_RegisterEffect() API internally, and returns without
+ * registering the effect function if the audio device is not configured
+ * for stereo output. Setting both (left) and (right) to 255 causes this
+ * effect to be unregistered, since that is the data's normal state.
+ *
+ * returns zero if error (no such channel or Mix_RegisterEffect() fails),
+ * nonzero if panning effect enabled. Note that an audio device in mono
+ * mode is a no-op, but this call will return successful in that case.
+ * Error messages can be retrieved from Mix_GetError().
+ */
+extern DECLSPEC int SDLCALL Mix_SetPanning(int channel, Uint8 left, Uint8 right);
+
+
+/* Set the position of a channel. (angle) is an integer from 0 to 360, that
+ * specifies the location of the sound in relation to the listener. (angle)
+ * will be reduced as neccesary (540 becomes 180 degrees, -100 becomes 260).
+ * Angle 0 is due north, and rotates clockwise as the value increases.
+ * For efficiency, the precision of this effect may be limited (angles 1
+ * through 7 might all produce the same effect, 8 through 15 are equal, etc).
+ * (distance) is an integer between 0 and 255 that specifies the space
+ * between the sound and the listener. The larger the number, the further
+ * away the sound is. Using 255 does not guarantee that the channel will be
+ * culled from the mixing process or be completely silent. For efficiency,
+ * the precision of this effect may be limited (distance 0 through 5 might
+ * all produce the same effect, 6 through 10 are equal, etc). Setting (angle)
+ * and (distance) to 0 unregisters this effect, since the data would be
+ * unchanged.
+ *
+ * If you need more precise positional audio, consider using OpenAL for
+ * spatialized effects instead of SDL_mixer. This is only meant to be a
+ * basic effect for simple "3D" games.
+ *
+ * If the audio device is configured for mono output, then you won't get
+ * any effectiveness from the angle; however, distance attenuation on the
+ * channel will still occur. While this effect will function with stereo
+ * voices, it makes more sense to use voices with only one channel of sound,
+ * so when they are mixed through this effect, the positioning will sound
+ * correct. You can convert them to mono through SDL before giving them to
+ * the mixer in the first place if you like.
+ *
+ * Setting (channel) to MIX_CHANNEL_POST registers this as a posteffect, and
+ * the positioning will be done to the final mixed stream before passing it
+ * on to the audio device.
+ *
+ * This is a convenience wrapper over Mix_SetDistance() and Mix_SetPanning().
+ *
+ * returns zero if error (no such channel or Mix_RegisterEffect() fails),
+ * nonzero if position effect is enabled.
+ * Error messages can be retrieved from Mix_GetError().
+ */
+extern DECLSPEC int SDLCALL Mix_SetPosition(int channel, Sint16 angle, Uint8 distance);
+
+
+/* Set the "distance" of a channel. (distance) is an integer from 0 to 255
+ * that specifies the location of the sound in relation to the listener.
+ * Distance 0 is overlapping the listener, and 255 is as far away as possible
+ * A distance of 255 does not guarantee silence; in such a case, you might
+ * want to try changing the chunk's volume, or just cull the sample from the
+ * mixing process with Mix_HaltChannel().
+ * For efficiency, the precision of this effect may be limited (distances 1
+ * through 7 might all produce the same effect, 8 through 15 are equal, etc).
+ * (distance) is an integer between 0 and 255 that specifies the space
+ * between the sound and the listener. The larger the number, the further
+ * away the sound is.
+ * Setting (distance) to 0 unregisters this effect, since the data would be
+ * unchanged.
+ * If you need more precise positional audio, consider using OpenAL for
+ * spatialized effects instead of SDL_mixer. This is only meant to be a
+ * basic effect for simple "3D" games.
+ *
+ * Setting (channel) to MIX_CHANNEL_POST registers this as a posteffect, and
+ * the distance attenuation will be done to the final mixed stream before
+ * passing it on to the audio device.
+ *
+ * This uses the Mix_RegisterEffect() API internally.
+ *
+ * returns zero if error (no such channel or Mix_RegisterEffect() fails),
+ * nonzero if position effect is enabled.
+ * Error messages can be retrieved from Mix_GetError().
+ */
+extern DECLSPEC int SDLCALL Mix_SetDistance(int channel, Uint8 distance);
+
+
+/*
+ * !!! FIXME : Haven't implemented, since the effect goes past the
+ * end of the sound buffer. Will have to think about this.
+ * --ryan.
+ */
+#if 0
+/* Causes an echo effect to be mixed into a sound. (echo) is the amount
+ * of echo to mix. 0 is no echo, 255 is infinite (and probably not
+ * what you want).
+ *
+ * Setting (channel) to MIX_CHANNEL_POST registers this as a posteffect, and
+ * the reverbing will be done to the final mixed stream before passing it on
+ * to the audio device.
+ *
+ * This uses the Mix_RegisterEffect() API internally. If you specify an echo
+ * of zero, the effect is unregistered, as the data is already in that state.
+ *
+ * returns zero if error (no such channel or Mix_RegisterEffect() fails),
+ * nonzero if reversing effect is enabled.
+ * Error messages can be retrieved from Mix_GetError().
+ */
+extern no_parse_DECLSPEC int SDLCALL Mix_SetReverb(int channel, Uint8 echo);
+#endif
+
+/* Causes a channel to reverse its stereo. This is handy if the user has his
+ * speakers hooked up backwards, or you would like to have a minor bit of
+ * psychedelia in your sound code. :) Calling this function with (flip)
+ * set to non-zero reverses the chunks's usual channels. If (flip) is zero,
+ * the effect is unregistered.
+ *
+ * This uses the Mix_RegisterEffect() API internally, and thus is probably
+ * more CPU intensive than having the user just plug in his speakers
+ * correctly. Mix_SetReverseStereo() returns without registering the effect
+ * function if the audio device is not configured for stereo output.
+ *
+ * If you specify MIX_CHANNEL_POST for (channel), then this the effect is used
+ * on the final mixed stream before sending it on to the audio device (a
+ * posteffect).
+ *
+ * returns zero if error (no such channel or Mix_RegisterEffect() fails),
+ * nonzero if reversing effect is enabled. Note that an audio device in mono
+ * mode is a no-op, but this call will return successful in that case.
+ * Error messages can be retrieved from Mix_GetError().
+ */
+extern DECLSPEC int SDLCALL Mix_SetReverseStereo(int channel, int flip);
+
+/* end of effects API. --ryan. */
+
+
+/* Reserve the first channels (0 -> n-1) for the application, i.e. don't allocate
+ them dynamically to the next sample if requested with a -1 value below.
+ Returns the number of reserved channels.
+ */
+extern DECLSPEC int SDLCALL Mix_ReserveChannels(int num);
+
+/* Channel grouping functions */
+
+/* Attach a tag to a channel. A tag can be assigned to several mixer
+ channels, to form groups of channels.
+ If 'tag' is -1, the tag is removed (actually -1 is the tag used to
+ represent the group of all the channels).
+ Returns true if everything was OK.
+ */
+extern DECLSPEC int SDLCALL Mix_GroupChannel(int which, int tag);
+/* Assign several consecutive channels to a group */
+extern DECLSPEC int SDLCALL Mix_GroupChannels(int from, int to, int tag);
+/* Finds the first available channel in a group of channels,
+ returning -1 if none are available.
+ */
+extern DECLSPEC int SDLCALL Mix_GroupAvailable(int tag);
+/* Returns the number of channels in a group. This is also a subtle
+ way to get the total number of channels when 'tag' is -1
+ */
+extern DECLSPEC int SDLCALL Mix_GroupCount(int tag);
+/* Finds the "oldest" sample playing in a group of channels */
+extern DECLSPEC int SDLCALL Mix_GroupOldest(int tag);
+/* Finds the "most recent" (i.e. last) sample playing in a group of channels */
+extern DECLSPEC int SDLCALL Mix_GroupNewer(int tag);
+
+/* Play an audio chunk on a specific channel.
+ If the specified channel is -1, play on the first free channel.
+ If 'loops' is greater than zero, loop the sound that many times.
+ If 'loops' is -1, loop inifinitely (~65000 times).
+ Returns which channel was used to play the sound.
+*/
+#define Mix_PlayChannel(channel,chunk,loops) Mix_PlayChannelTimed(channel,chunk,loops,-1)
+/* The same as above, but the sound is played at most 'ticks' milliseconds */
+extern DECLSPEC int SDLCALL Mix_PlayChannelTimed(int channel, Mix_Chunk *chunk, int loops, int ticks);
+extern DECLSPEC int SDLCALL Mix_PlayMusic(Mix_Music *music, int loops);
+#define Mix_PlayChannelVol(channel,chunk,loops,vol) Mix_PlayChannelTimedVolume(channel,chunk,loops,-1,vol)/*MIXER-X*/
+extern DECLSPEC int SDLCALL Mix_PlayChannelTimedVolume(int which, Mix_Chunk *chunk, int loops, int ticks, int volume);/*MIXER-X*/
+
+/* Fade in music or a channel over "ms" milliseconds, same semantics as the "Play" functions */
+extern DECLSPEC int SDLCALL Mix_FadeInMusic(Mix_Music *music, int loops, int ms);
+extern DECLSPEC int SDLCALL Mix_FadeInMusicPos(Mix_Music *music, int loops, int ms, double position);
+#define Mix_FadeInChannel(channel,chunk,loops,ms) Mix_FadeInChannelTimed(channel,chunk,loops,ms,-1)
+extern DECLSPEC int SDLCALL Mix_FadeInChannelTimed(int channel, Mix_Chunk *chunk, int loops, int ms, int ticks);
+#define Mix_FadeInChannelVolume(channel,chunk,loops,ms,vol) Mix_FadeInChannelTimed(channel,chunk,loops,ms,-1,vol)/*MIXER-X*/
+extern DECLSPEC int SDLCALL Mix_FadeInChannelTimedVolume(int which, Mix_Chunk *chunk, int loops, int ms, int ticks, int volume);/*MIXER-X*/
+
+
+/* Set the volume in the range of 0-128 of a specific channel or chunk.
+ If the specified channel is -1, set volume for all channels.
+ Returns the original volume.
+ If the specified volume is -1, just return the current volume.
+*/
+extern DECLSPEC int SDLCALL Mix_Volume(int channel, int volume);
+extern DECLSPEC int SDLCALL Mix_VolumeChunk(Mix_Chunk *chunk, int volume);
+extern DECLSPEC int SDLCALL Mix_VolumeMusic(int volume);
+
+/* Halt playing of a particular channel */
+extern DECLSPEC int SDLCALL Mix_HaltChannel(int channel);
+extern DECLSPEC int SDLCALL Mix_HaltGroup(int tag);
+extern DECLSPEC int SDLCALL Mix_HaltMusic(void);
+
+/* Change the expiration delay for a particular channel.
+ The sample will stop playing after the 'ticks' milliseconds have elapsed,
+ or remove the expiration if 'ticks' is -1
+*/
+extern DECLSPEC int SDLCALL Mix_ExpireChannel(int channel, int ticks);
+
+/* Halt a channel, fading it out progressively till it's silent
+ The ms parameter indicates the number of milliseconds the fading
+ will take.
+ */
+extern DECLSPEC int SDLCALL Mix_FadeOutChannel(int which, int ms);
+extern DECLSPEC int SDLCALL Mix_FadeOutGroup(int tag, int ms);
+extern DECLSPEC int SDLCALL Mix_FadeOutMusic(int ms);
+
+/* Query the fading status of a channel */
+extern DECLSPEC Mix_Fading SDLCALL Mix_FadingMusic(void);
+extern DECLSPEC Mix_Fading SDLCALL Mix_FadingChannel(int which);
+
+/* Pause/Resume a particular channel */
+extern DECLSPEC void SDLCALL Mix_Pause(int channel);
+extern DECLSPEC void SDLCALL Mix_Resume(int channel);
+extern DECLSPEC int SDLCALL Mix_Paused(int channel);
+
+/* Pause/Resume the music stream */
+extern DECLSPEC void SDLCALL Mix_PauseMusic(void);
+extern DECLSPEC void SDLCALL Mix_ResumeMusic(void);
+extern DECLSPEC void SDLCALL Mix_RewindMusic(void);
+extern DECLSPEC int SDLCALL Mix_PausedMusic(void);
+
+/* Set the current position in the music stream.
+ This returns 0 if successful, or -1 if it failed or isn't implemented.
+ This function is only implemented for MOD music formats (set pattern
+ order number) and for WAV, OGG, FLAC, MP3_MAD, MP3_MPG, and MODPLUG music
+ (set position in seconds), at the moment.
+*/
+extern DECLSPEC int SDLCALL Mix_SetMusicPosition(double position);
+/*
+ Get the time current position of music stream
+ returns -1.0 if this feature is not supported for some codec
+ */
+extern DECLSPEC double SDLCALL Mix_GetMusicPosition(Mix_Music *music);
+/*
+ Get the total time length of music stream
+ returns -1.0 if this feature is not supported for some codec
+ */
+extern DECLSPEC double SDLCALL Mix_GetMusicTotalTime(Mix_Music *music);
+
+/*
+ Get the loop start time position of music stream
+ returns -1.0 if this feature is not used for this music or not supported for some codec
+ */
+extern DECLSPEC double SDLCALL Mix_GetMusicLoopStartTime(Mix_Music *music);
+/*
+ Get the loop end time position of music stream
+ returns -1.0 if this feature is not used for this music or not supported for some codec
+ */
+extern DECLSPEC double SDLCALL Mix_GetMusicLoopEndTime(Mix_Music *music);
+/*
+ Get the loop time length of music stream
+ returns -1.0 if this feature is not used for this music or not supported for some codec
+ */
+extern DECLSPEC double SDLCALL Mix_GetMusicLoopLengthTime(Mix_Music *music);
+
+
+/* Check the status of a specific channel.
+ If the specified channel is -1, check all channels.
+*/
+extern DECLSPEC int SDLCALL Mix_Playing(int channel);
+extern DECLSPEC int SDLCALL Mix_PlayingMusic(void);
+
+/* Stop music and set external music playback command */
+extern DECLSPEC int SDLCALL Mix_SetMusicCMD(const char *command);
+
+/* Synchro value is set by MikMod from modules while playing */
+extern DECLSPEC int SDLCALL Mix_SetSynchroValue(int value);
+extern DECLSPEC int SDLCALL Mix_GetSynchroValue(void);
+
+/* Set/Get/Iterate SoundFonts paths to use by supported MIDI backends */
+extern DECLSPEC int SDLCALL Mix_SetSoundFonts(const char *paths);
+extern DECLSPEC const char* SDLCALL Mix_GetSoundFonts(void);
+extern DECLSPEC int SDLCALL Mix_EachSoundFont(int (SDLCALL *function)(const char*, void*), void *data);
+
+/* Get the Mix_Chunk currently associated with a mixer channel
+ Returns NULL if it's an invalid channel, or there's no chunk associated.
+*/
+extern DECLSPEC Mix_Chunk * SDLCALL Mix_GetChunk(int channel);
+
+/* Close the mixer, halting all playing audio */
+extern DECLSPEC void SDLCALL Mix_CloseAudio(void);
+
+/* Add additional Timidity bank path */
+extern DECLSPEC void SDLCALL Mix_Timidity_addToPathList(const char *path);
+
+/* ADLMIDI Setup functions */
+/* Get count of available hardcoded banks */
+extern DECLSPEC int SDLCALL Mix_ADLMIDI_getTotalBanks(void);
+/* Get array of the bank names */
+extern DECLSPEC const char *const *SDLCALL Mix_ADLMIDI_getBankNames(void);
+/* Get bank ID */
+extern DECLSPEC int SDLCALL Mix_ADLMIDI_getBankID(void);
+/* Set bank ID (Applying on stop/play) */
+extern DECLSPEC void SDLCALL Mix_ADLMIDI_setBankID(int bnk);
+/* Get state of deep vibrato */
+extern DECLSPEC int SDLCALL Mix_ADLMIDI_getTremolo(void);
+/* Set deep tremolo mode (0 off, 1 on) (Applying on stop/play) */
+extern DECLSPEC void SDLCALL Mix_ADLMIDI_setTremolo(int tr);
+/* Get state of deep vibrato */
+extern DECLSPEC int SDLCALL Mix_ADLMIDI_getVibrato(void);
+/* Set deep vibrato mode (0 off, 1 on) (Applying on stop/play) */
+extern DECLSPEC void SDLCALL Mix_ADLMIDI_setVibrato(int vib);
+/* Get state of scalable modulation mode */
+extern DECLSPEC int SDLCALL Mix_ADLMIDI_getScaleMod(void);
+/* Set scalable modulation mode (0 off, 1 on) (Applying on stop/play) */
+extern DECLSPEC void SDLCALL Mix_ADLMIDI_setScaleMod(int sc);
+/* Get state of adlib drums mode */
+extern DECLSPEC int SDLCALL Mix_ADLMIDI_getAdLibMode(void);
+/* Set adlib drums mode mode (0 off, 1 on) (Applying on stop/play) */
+extern DECLSPEC void SDLCALL Mix_ADLMIDI_setAdLibMode(int tr);
+/* Get state of logarithmic mode */
+extern DECLSPEC int SDLCALL Mix_ADLMIDI_getLogarithmicVolumes(void);
+/* Set logarithmic volumes mode in the generic/CMF volume models (0 off, 1 on) (Applying on stop/play) */
+extern DECLSPEC void SDLCALL Mix_ADLMIDI_setLogarithmicVolumes(int lv);
+/* Get current volume model ID */
+extern DECLSPEC int SDLCALL Mix_ADLMIDI_getVolumeModel(void);
+/* Change current volumes model (Applying on stop/play) */
+extern DECLSPEC void SDLCALL Mix_ADLMIDI_setVolumeModel(int vm);
+/* Get full range mode for CC74-Brightness controller */
+extern DECLSPEC int SDLCALL Mix_ADLMIDI_getFullRangeBrightness(void);
+/* Set full range mode for CC74-Brightness controller */
+extern DECLSPEC void SDLCALL Mix_ADLMIDI_setFullRangeBrightness(int frb);
+/* Get the current OPL3 Emulator for ADLMIDI */
+extern DECLSPEC int SDLCALL Mix_ADLMIDI_getEmulator(void);
+/* Select the OPL3 Emulator for ADLMIDI */
+extern DECLSPEC void SDLCALL Mix_ADLMIDI_setEmulator(int emu);
+/* Reset all ADLMIDI properties to default state */
+extern DECLSPEC void SDLCALL Mix_ADLMIDI_setSetDefaults(void);
+
+/* Sets WOPL bank file for ADLMIDI playing device, affects on MIDI file reopen */
+extern DECLSPEC void SDLCALL Mix_ADLMIDI_setCustomBankFile(const char *bank_wonl_path);
+
+/* Reset all OPNMIDI properties to default state */
+extern DECLSPEC void SDLCALL Mix_OPNMIDI_setSetDefaults(void);
+/* Get full range mode for CC74-Brightness controller */
+extern DECLSPEC int SDLCALL Mix_OPNMIDI_getFullRangeBrightness(void);
+/* Set full range mode for CC74-Brightness controller */
+extern DECLSPEC void SDLCALL Mix_OPNMIDI_setFullRangeBrightness(int frb);
+/* Get the OPN2 Emulator for OPNMIDI */
+extern DECLSPEC int SDLCALL Mix_OPNMIDI_getEmulator(void);
+/* Select the OPN2 Emulator for OPNMIDI */
+extern DECLSPEC void SDLCALL Mix_OPNMIDI_setEmulator(int emu);
+/* Sets WOPN bank file for OPNMIDI playing device, affects on MIDI file reopen */
+extern DECLSPEC void SDLCALL Mix_OPNMIDI_setCustomBankFile(const char *bank_wonp_path);
+
+/* Get type of MIDI player library currently in use */
+extern DECLSPEC int SDLCALL Mix_GetMidiPlayer(void);
+
+/* Get type of MIDI player library prepared for next opening of MIDI file */
+extern DECLSPEC int SDLCALL Mix_GetNextMidiPlayer(void);
+
+/* Set the MIDI playing library (ADLMIDI, Timidity, Native MIDI (if available) and FluidSynth) */
+extern DECLSPEC int SDLCALL Mix_SetMidiPlayer(int player);
+
+/* Disables support of MIDI file arguments */
+extern DECLSPEC void SDLCALL Mix_SetLockMIDIArgs(int lock_midiargs);
+
+/* DEPRECATED NAMES for new-added SDL Mixer X functions
+ Those names are made with mistake - beginning with "MIX_" than "Mix_"
+ which makes confusion when you looking for Mix_ function in your IDE
+ because some applications are still use them, to don't break ABI we will keep those
+ aliases until we will remove all usages of them from applications and libraries are used them
+*/
+DEPRECATED(extern DECLSPEC int SDLCALL Mix_GetMidiDevice(void));
+DEPRECATED(extern DECLSPEC int SDLCALL Mix_GetNextMidiDevice(void));
+DEPRECATED(extern DECLSPEC int SDLCALL Mix_SetMidiDevice(int player));
+
+/* We'll use SDL for reporting errors */
+#define Mix_SetError SDL_SetError
+#define Mix_GetError SDL_GetError
+#define Mix_ClearError SDL_ClearError
+
+/* Ends C function definitions when using C++ */
+#ifdef __cplusplus
+}
+#endif
+#include "close_code.h"
+
+#endif /* SDL_MIXER_H_ */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/libs/SDLMixerX/x86_64-w64-mingw32/include/SDL2/begin_code.h b/libs/SDLMixerX/x86_64-w64-mingw32/include/SDL2/begin_code.h
new file mode 100644
index 000000000..6c2106246
--- /dev/null
+++ b/libs/SDLMixerX/x86_64-w64-mingw32/include/SDL2/begin_code.h
@@ -0,0 +1,167 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+/**
+ * \file begin_code.h
+ *
+ * This file sets things up for C dynamic library function definitions,
+ * static inlined functions, and structures aligned at 4-byte alignment.
+ * If you don't like ugly C preprocessor code, don't look at this file. :)
+ */
+
+/* This shouldn't be nested -- included it around code only. */
+#ifdef _begin_code_h
+#error Nested inclusion of begin_code.h
+#endif
+#define _begin_code_h
+
+#ifndef SDL_DEPRECATED
+# if (__GNUC__ >= 4) /* technically, this arrived in gcc 3.1, but oh well. */
+# define SDL_DEPRECATED __attribute__((deprecated))
+# else
+# define SDL_DEPRECATED
+# endif
+#endif
+
+#ifndef SDL_UNUSED
+# ifdef __GNUC__
+# define SDL_UNUSED __attribute__((unused))
+# else
+# define SDL_UNUSED
+# endif
+#endif
+
+/* Some compilers use a special export keyword */
+#ifndef DECLSPEC
+# if defined(__WIN32__) || defined(__WINRT__)
+# ifdef __BORLANDC__
+# ifdef BUILD_SDL
+# define DECLSPEC
+# else
+# define DECLSPEC __declspec(dllimport)
+# endif
+# else
+# define DECLSPEC __declspec(dllexport)
+# endif
+# elif defined(__OS2__)
+# ifdef BUILD_SDL
+# define DECLSPEC __declspec(dllexport)
+# else
+# define DECLSPEC
+# endif
+# else
+# if defined(__GNUC__) && __GNUC__ >= 4
+# define DECLSPEC __attribute__ ((visibility("default")))
+# else
+# define DECLSPEC
+# endif
+# endif
+#endif
+
+/* By default SDL uses the C calling convention */
+#ifndef SDLCALL
+#if (defined(__WIN32__) || defined(__WINRT__)) && !defined(__GNUC__)
+#define SDLCALL __cdecl
+#elif defined(__OS2__) || defined(__EMX__)
+#define SDLCALL _System
+# if defined (__GNUC__) && !defined(_System)
+# define _System /* for old EMX/GCC compat. */
+# endif
+#else
+#define SDLCALL
+#endif
+#endif /* SDLCALL */
+
+/* Removed DECLSPEC on Symbian OS because SDL cannot be a DLL in EPOC */
+#ifdef __SYMBIAN32__
+#undef DECLSPEC
+#define DECLSPEC
+#endif /* __SYMBIAN32__ */
+
+/* Force structure packing at 4 byte alignment.
+ This is necessary if the header is included in code which has structure
+ packing set to an alternate value, say for loading structures from disk.
+ The packing is reset to the previous value in close_code.h
+ */
+#if defined(_MSC_VER) || defined(__MWERKS__) || defined(__BORLANDC__)
+#ifdef _MSC_VER
+#pragma warning(disable: 4103)
+#endif
+#ifdef __BORLANDC__
+#pragma nopackwarning
+#endif
+#ifdef _M_X64
+/* Use 8-byte alignment on 64-bit architectures, so pointers are aligned */
+#pragma pack(push,8)
+#else
+#pragma pack(push,4)
+#endif
+#endif /* Compiler needs structure packing set */
+
+#ifndef SDL_INLINE
+#if defined(__GNUC__)
+#define SDL_INLINE __inline__
+#elif defined(_MSC_VER) || defined(__BORLANDC__) || \
+ defined(__DMC__) || defined(__SC__) || \
+ defined(__WATCOMC__) || defined(__LCC__) || \
+ defined(__DECC) || defined(__CC_ARM)
+#define SDL_INLINE __inline
+#ifndef __inline__
+#define __inline__ __inline
+#endif
+#else
+#define SDL_INLINE inline
+#ifndef __inline__
+#define __inline__ inline
+#endif
+#endif
+#endif /* SDL_INLINE not defined */
+
+#ifndef SDL_FORCE_INLINE
+#if defined(_MSC_VER)
+#define SDL_FORCE_INLINE __forceinline
+#elif ( (defined(__GNUC__) && (__GNUC__ >= 4)) || defined(__clang__) )
+#define SDL_FORCE_INLINE __attribute__((always_inline)) static __inline__
+#else
+#define SDL_FORCE_INLINE static SDL_INLINE
+#endif
+#endif /* SDL_FORCE_INLINE not defined */
+
+#ifndef SDL_NORETURN
+#if defined(__GNUC__)
+#define SDL_NORETURN __attribute__((noreturn))
+#elif defined(_MSC_VER)
+#define SDL_NORETURN __declspec(noreturn)
+#else
+#define SDL_NORETURN
+#endif
+#endif /* SDL_NORETURN not defined */
+
+/* Apparently this is needed by several Windows compilers */
+#if !defined(__MACH__)
+#ifndef NULL
+#ifdef __cplusplus
+#define NULL 0
+#else
+#define NULL ((void *)0)
+#endif
+#endif /* NULL */
+#endif /* ! Mac OS X - breaks precompiled headers */
diff --git a/libs/SDLMixerX/x86_64-w64-mingw32/include/SDL2/close_code.h b/libs/SDLMixerX/x86_64-w64-mingw32/include/SDL2/close_code.h
new file mode 100644
index 000000000..b3b70a4c8
--- /dev/null
+++ b/libs/SDLMixerX/x86_64-w64-mingw32/include/SDL2/close_code.h
@@ -0,0 +1,37 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+/**
+ * \file close_code.h
+ *
+ * This file reverses the effects of begin_code.h and should be included
+ * after you finish any function and structure declarations in your headers
+ */
+
+#undef _begin_code_h
+
+/* Reset structure packing at previous byte alignment */
+#if defined(_MSC_VER) || defined(__MWERKS__) || defined(__BORLANDC__)
+#ifdef __BORLANDC__
+#pragma nopackwarning
+#endif
+#pragma pack(pop)
+#endif /* Compiler needs structure packing set */
diff --git a/libs/SDLMixerX/x86_64-w64-mingw32/lib/libSDL2_mixer_ext.dll.a b/libs/SDLMixerX/x86_64-w64-mingw32/lib/libSDL2_mixer_ext.dll.a
new file mode 100644
index 000000000..c1cede98d
Binary files /dev/null and b/libs/SDLMixerX/x86_64-w64-mingw32/lib/libSDL2_mixer_ext.dll.a differ
diff --git a/libs/dll-binaries/i686/libgme.dll b/libs/dll-binaries/i686/libgme.dll
index ddf8b0d82..9a31bc4d2 100644
Binary files a/libs/dll-binaries/i686/libgme.dll and b/libs/dll-binaries/i686/libgme.dll differ
diff --git a/libs/dll-binaries/x86_64/libgme.dll b/libs/dll-binaries/x86_64/libgme.dll
index 2ba99450f..598c2d71c 100644
Binary files a/libs/dll-binaries/x86_64/libgme.dll and b/libs/dll-binaries/x86_64/libgme.dll differ
diff --git a/libs/gme/CMakeLists.txt b/libs/gme/CMakeLists.txt
index 8beee872f..392b01856 100644
--- a/libs/gme/CMakeLists.txt
+++ b/libs/gme/CMakeLists.txt
@@ -4,7 +4,7 @@ project(libgme)
include (CheckCXXCompilerFlag)
# When version is changed, also change the one in gme/gme.h to match
-set(GME_VERSION 0.6.0 CACHE INTERNAL "libgme Version")
+set(GME_VERSION 0.6.2 CACHE INTERNAL "libgme Version")
# 2.6+ always assumes FATAL_ERROR, but 2.4 and below don't.
# Of course, 2.4 might work, in which case you're welcome to drop
@@ -57,6 +57,8 @@ if (USE_GME_NSFE AND NOT USE_GME_NSF)
SET(USE_GME_NSF 1 CACHE BOOL "Enable NES NSF music emulation" FORCE)
endif()
+option(BUILD_SHARED_LIBS "Build shared library (set to OFF for static library)" ON)
+
# Check for GCC "visibility" support.
if (CMAKE_COMPILER_IS_GNUCXX)
check_cxx_compiler_flag (-fvisibility=hidden __LIBGME_TEST_VISIBILITY)
@@ -79,10 +81,10 @@ if (CMAKE_COMPILER_IS_GNUCXX)
endif()
endif()
endif() # test visibility
-endif (CMAKE_COMPILER_IS_GNUCXX)
-# Cache this result
-set( LIBGME_HAVE_GCC_VISIBILITY ${ENABLE_VISIBILITY} CACHE BOOL "GCC support for hidden visibility")
+ # Cache this result
+ set( LIBGME_HAVE_GCC_VISIBILITY ${ENABLE_VISIBILITY} CACHE BOOL "GCC support for hidden visibility")
+endif (CMAKE_COMPILER_IS_GNUCXX)
# Shared library defined here
add_subdirectory(gme)
diff --git a/libs/gme/changes.txt b/libs/gme/changes.txt
index 62391ebb5..034ba4821 100644
--- a/libs/gme/changes.txt
+++ b/libs/gme/changes.txt
@@ -1,262 +1,5 @@
Game_Music_Emu Change Log
-------------------------
-Game_Music_Emu 0.6.0
---------------------
-
-- Note: A 0.5.6 release was referenced but never tagged or packaged.
-
-- SPC improvements:
- - Switched to newer snes_spc 0.9.0 for SPC emulation. Uses fast DSP.
- - Fixed Spc_Emu::gain().
- - Fixed support for files <0x10200 bytes.
-
-- Other bugfixes:
- - Fixed a couple of GBS bugs, one involving access of memory after
- realloc.
- - Blip_Buffer works on systems where 'double' is a single-precision
- floating-point type.
- - Fix uninitialized buffer size in dual_resampler.
- - Compilation warnings squashed out as of clang 3.3-pre and gcc 4.7.2.
-
-- API changes/additions:
- - Removed documentation of C++ interface, as the C interface in gme.h is
- the only supported one.
- - Added gme_enable_accuracy() for enabling more accurate sound emulation
- options (currently affects SPC only).
-
-- Build system improvements:
- - Add pkg_config support.
- - Fix build on case-insensitive systems.
- - Allow for install on Cygwin.
- - Fix install on multilib systems, such as many 64-bit distros (CMake must
- be able to figure out your system's libsuffix, if any).
- - C++ implementation symbols are not leaked into the resultant library
- file (requires symbol visibility support).
-
-- Sample player improvements:
- - Can toggle fast/accurate emulation (with the 'A' key).
-
-Game_Music_Emu 0.5.5
---------------------
-- CMake build support has been added. You can build Game_Music_Emu as
-a shared library and install it so that you do not have to include your
-own copy if you know libgme will be present on your target system.
-Requires CMake 2.6 or higher.
-
-
-Game_Music_Emu 0.5.2
---------------------
-- *TONS* of changes and improvements. You should re-read the new header
-files and documentation as the changes will allow you to simplify your
-code a lot (it might even be simpler to just rewrite it). Existing code
-should continue to work without changes in most cases (see Deprecated
-features in gme.txt).
-
-- New file formats: AY, HES, KSS, SAP, NSFE
-
-- All-new comprehensive C interface (also usable from C++). Simplifies
-many things, especially file loading, and brings everything together in
-one header file (gme.h).
-
-- Information tags and track names and times can be accessed for all
-game music formats
-
-- New features supported by all emulators: end of track fading,
-automatic silence detection, adjustable song tempo, seek to new time in
-track
-
-- Updated mini player example to support track names and times, echo,
-tempo, and channel muting, and added visual waveform display
-
-- Improved configuration to use blargg_config.h, which you can modify
-and keep when you update to a newer libary version. Includes flag for
-library to automatically handle gzipped files using zlib (so you don't
-need to use Gzip_File_Reader anymore).
-
-- GBS: Fixed wave channel to not reset waveform when APU is powered off
-(affected Garfield). Also improved invalid bank selection (affected Game
-& Watch and others).
-
-- VGM: Added support for alternate noise shifter register
-configurations, used by other systems like the BBC Micro.
-
-- SPC: Removed IPL ROM dump from emulator, as none of the SPC files I
-scanned needed it, and an SPC file can include a copy if necessary. Also
-re-enabled supposed clamping in gaussian interpolation between the third
-and fourth lookups, though I don't know whether it matters
-
-- Added Music_Emu::load_mem() to use music data already in memory
-(without copying it)
-
-- Added Music_Emu::warning(), which reports minor problems when loading
-and playing a music file
-
-- Added Music_Emu::set_gain() for uniform adjustment of gain. Can only
-be set during initialization, so not useful as a general volume control.
-
-- Added custom operator new to ensure that no exceptions are thrown in
-the library (I'd use std::nothrow if it were part of pre-ISO (ARM) C++)
-
-- Added BLIP_BUFFER_FAST flag to blargg_config.h to use a lower quality
-bandlimited synthesis in "classic" emulators, which might help
-performance on ancient processors (measure first!). Don't use this
-unless absolutely necessary, as quality suffers.
-
-- Improved performance a bit for x86 platforms
-
-- Text files now in DOS newline format so they will open in Notepad
-properly
-
-- Removed requirement that file header structures not have any padding
-added to the end
-
-- Fixed common bug in all CPU emulators where negative program counter
-could crash emulator (occurred during a negative branch from the
-beginning of memory). Also fixed related bug in Z80 emulator for
-IX/IY+displacement mode.
-
-- Eliminated all warnings when compiling on gcc 4.0. The following
-generates no diagnostics:
-
- gcc -S gme/*.cpp -o /dev/null -ansi -fno-gnu-keywords
- -fno-nonansi-builtins -pedantic -W -Wabi -Wall -Wcast-align
- -Wcast-qual -Wchar-subscripts -Wdisabled-optimization -Werror
- -Winline -Wlong-long -Wmultichar -Winvalid-offsetof
- -Wnon-virtual-dtor -Woverloaded-virtual -Wparentheses
- -Wpointer-arith -Wredundant-decls -Wreorder -Wsign-compare
- -Wsign-promo -Wunknown-pragmas -Wwrite-strings
-
-
-Game_Music_Emu 0.3.0
---------------------
-- Added more demos, including music player using the SDL multimedia
-library for sound, and improved documentation
-
-- All: Improved interface to emulators to allow simpler setup and
-loading. Instead of various init() functions, all now support
-set_sample_rate( long rate ) and load( const char* file_path ).
-
-- All: Removed error return from start_track() and play(), and added
-error_count() to get the total number of emulation errors since the
-track was last started. See demos for examples of new usage.
-
-- All: Fixed mute_voices() muting to be preserved after loading files
-and starting tracks, instead of being cleared as it was whenever a track
-was started
-
-- VGM: Rewrote Vgm_Emu to support Sega Genesis/Mega Drive FM sound at
-any sample rate with optional FM oversampling, support for alternate
-YM2612 sound cores, and support for optional YM2413
-
-- VGM: Added tempo control, useful for slowing 60Hz NTSC Sega Genesis
-music to 50Hz PAL
-
-- VGM: Removed Vgm_Emu::track_data(), since I realized that this
-information is already present in the VGM header (oops!)
-
-- GYM: Changed Gym_Emu::track_length() operation (see Gym_Emu.h)
-
-- NSF: Added support for Sunsoft FME-7 sound chip used by Gimmick
-soundtrack
-
-- NSF: Fixed Namco 106 problems with Final Lap and others
-
-- Moved library sources to gme/ directory to reduce clutter, and merged
-boost/ functionality into blargg_common.h
-
-- Added Gzip_File_Reader for transparently using gzipped files
-
-
-Game_Music_Emu 0.2.4
---------------------
-- Created a discussion forum for problems and feedback:
-http://groups-beta.google.com/group/blargg-sound-libs
-
-- Changed error return value of Blip_Buffer::sample_rate() (also for
-Stereo_Buffer, Effects_Buffer, etc.) to blargg_err_t (defined in
-blargg_common.h), to make error reporting consistent with other
-functions. This means the "no error" return value is the opposite of
-what it was before, which will break current code which checks the error
-return value:
-
- // current code (broken)
- if ( !buf.sample_rate( samples_per_sec ) )
- out_of_memory();
-
- // quick-and-dirty fix (just remove the ! operation)
- if ( buf.sample_rate( samples_per_sec ) )
- out_of_memory();
-
- // proper fix
- blargg_err_t error = buf.sample_rate( samples_per_sec );
- if ( error )
- report_error( error );
-
-- Implemented workaround for MSVC++ 6 compiler limitations, allowing it
-to work on that compiler again
-
-- Added sample clamping to avoid wrap-around at high volumes, allowing
-higher volume with little distortion
-
-- Added to-do list and design notes
-
-- Added Music_Emu::skip( long sample_count ) to skip ahead in current
-track
-
-- Added Gym_Emu::track_length() and Vgm_Emu::track_length() for
-determining the length of non-looped GYM and VGM files
-
-- Partially implemented DMC non-linearity when its value is directly set
-using $4011, which reduces previously over-emphasized "popping" of
-percussion on some games (TMNT II in particular)
-
-- Fixed Fir_Resampler, used for SPC and GYM playback (was incorrectly
-using abs() instead of fabs()...argh)
-
-- Fixed SPC emulation bugs: eliminated clicks in Plok! soundtrack and
-now stops sample slightly earlier than the end, as the SNES does. Fixed
-a totally broken CPU addressing mode.
-
-- Fixed Konami VRC6 saw wave (was very broken before). Now VRC6 music
-sounds decent
-
-- Fixed a minor GBS emulation bug
-
-- Fixed GYM loop point bug when track was restarted before loop point
-had been reached
-
-- Made default GBS frequency equalization less muffled
-
-- Added pseudo-surround effect removal for SPC files
-
-- Added Music_Emu::voice_names() which returns names for each voice.
-
-- Added BLARGG_SOURCE_BEGIN which allows custom compiler options to be
-easily set for library sources
-
-- Changed assignment of expansion sound chips in Nsf_Emu to be spread
-more evenly when using Effects_Buffer
-
-- Changed 'size_t' values in Blip_Buffer interface to 'long'
-
-- Changed demo to generate a WAVE sound file rather than an AIFF file
-
-
-Game_Music_Emu 0.2.0
---------------------
-- Redid framework and rewrote/cleaned up emulators
-
-- Changed licensing to GNU Lesser General Public License (LGPL)
-
-- Added Sega Genesis GYM and Super Nintendo SPC emulators
-
-- Added Namco-106 and Konami VRC6 sound chip support to NSF emulator
-
-- Eliminated use of static mutable data in emulators, allowing
-multi-instance safety
-
-
-Game_Music_Emu 0.1.0
---------------------
-- First release
+Please see the git version history (e.g. git shortlog tags/0.6.0..tags/0.6.1)
+for the accurate change log.
diff --git a/libs/gme/demo/basics.c b/libs/gme/demo/basics.c
index 551782518..741574afe 100644
--- a/libs/gme/demo/basics.c
+++ b/libs/gme/demo/basics.c
@@ -1,7 +1,5 @@
/* C example that opens a game music file and records 10 seconds to "out.wav" */
-static char filename [] = "test.nsf"; /* opens this file (can be any music type) */
-
#include "gme/gme.h"
#include "Wave_Writer.h" /* wave_ functions for writing sound file */
@@ -10,10 +8,15 @@ static char filename [] = "test.nsf"; /* opens this file (can be any music type)
void handle_error( const char* str );
-int main()
+int main(int argc, char *argv[])
{
+ const char *filename = "test.nsf"; /* Default file to open */
+ if ( argc >= 2 )
+ filename = argv[1];
+
long sample_rate = 44100; /* number of samples per second */
- int track = 0; /* index of track to play (0 = first) */
+ /* index of track to play (0 = first) */
+ int track = argc >= 3 ? atoi(argv[2]) : 0;
/* Open music file in new emulator */
Music_Emu* emu;
diff --git a/libs/gme/demo/cpp_basics.cpp b/libs/gme/demo/cpp_basics.cpp
index 53fab4186..5222fe271 100644
--- a/libs/gme/demo/cpp_basics.cpp
+++ b/libs/gme/demo/cpp_basics.cpp
@@ -1,7 +1,5 @@
// C++ example that opens a game music file and records 10 seconds to "out.wav"
-static char filename [] = "test.nsf"; /* opens this file (can be any music type) */
-
#include "gme/Music_Emu.h"
#include "Wave_Writer.h"
@@ -10,10 +8,15 @@ static char filename [] = "test.nsf"; /* opens this file (can be any music type)
void handle_error( const char* str );
-int main()
+int main(int argc, char *argv[])
{
+ const char *filename = "test.nsf"; /* Default file to open */
+ if ( argc >= 2 )
+ filename = argv[1];
+
long sample_rate = 44100; // number of samples per second
- int track = 0; // index of track to play (0 = first)
+ // index of track to play (0 = first)
+ int track = argc >= 3 ? atoi(argv[2]) : 0;
// Determine file type
gme_type_t file_type;
diff --git a/libs/gme/gme.txt b/libs/gme/gme.txt
index d9a2452c7..5a7d2f560 100644
--- a/libs/gme/gme.txt
+++ b/libs/gme/gme.txt
@@ -1,10 +1,10 @@
-Game_Music_Emu 0.6.0
+Game_Music_Emu 0.6.2
--------------------
-Author : Shay Green
-Website: http://www.slack.net/~ant/libs/
-Forum : http://groups.google.com/group/blargg-sound-libs
-Source : https://code.google.com/p/game-music-emu/
-License: GNU Lesser General Public License (LGPL)
+Author : Shay Green
+Maintainer : Michael Pyne
+Website : https://bitbucket.org/mpyne/game-music-emu/
+Source : https://bitbucket.org/mpyne/game-music-emu/
+License : GNU Lesser General Public License (LGPL), see LICENSE.txt
Contents
--------
diff --git a/libs/gme/gme/CMakeLists.txt b/libs/gme/gme/CMakeLists.txt
index 3c6464fc7..534be8a85 100644
--- a/libs/gme/gme/CMakeLists.txt
+++ b/libs/gme/gme/CMakeLists.txt
@@ -143,7 +143,7 @@ add_definitions(-DBLARGG_BUILD_DLL)
include_directories(${CMAKE_CURRENT_BINARY_DIR})
# Add library to be compiled.
-add_library(gme SHARED ${libgme_SRCS})
+add_library(gme ${libgme_SRCS})
# The version is the release. The "soversion" is the API version. As long
# as only build fixes are performed (i.e. no backwards-incompatible changes
@@ -159,4 +159,4 @@ install(TARGETS gme LIBRARY DESTINATION lib${LIB_SUFFIX}
ARCHIVE DESTINATION lib) # DLL platforms
install(FILES ${EXPORTED_HEADERS} DESTINATION include/gme)
-install(FILES ${CMAKE_CURRENT_BINARY_DIR}/libgme.pc DESTINATION lib/pkgconfig)
+install(FILES ${CMAKE_CURRENT_BINARY_DIR}/libgme.pc DESTINATION lib${LIB_SUFFIX}/pkgconfig)
diff --git a/libs/gme/gme/Data_Reader.cpp b/libs/gme/gme/Data_Reader.cpp
index 5bbfbf551..f18928f4b 100644
--- a/libs/gme/gme/Data_Reader.cpp
+++ b/libs/gme/gme/Data_Reader.cpp
@@ -22,8 +22,13 @@ Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
const char Data_Reader::eof_error [] = "Unexpected end of file";
+#define RETURN_VALIDITY_CHECK( cond ) \
+ do { if ( unlikely( !(cond) ) ) return "Corrupt file"; } while(0)
+
blargg_err_t Data_Reader::read( void* p, long s )
{
+ RETURN_VALIDITY_CHECK( s > 0 );
+
long result = read_avail( p, s );
if ( result != s )
{
@@ -38,6 +43,8 @@ blargg_err_t Data_Reader::read( void* p, long s )
blargg_err_t Data_Reader::skip( long count )
{
+ RETURN_VALIDITY_CHECK( count >= 0 );
+
char buf [512];
while ( count )
{
@@ -54,7 +61,8 @@ long File_Reader::remain() const { return size() - tell(); }
blargg_err_t File_Reader::skip( long n )
{
- assert( n >= 0 );
+ RETURN_VALIDITY_CHECK( n >= 0 );
+
if ( !n )
return 0;
return seek( tell() + n );
@@ -67,13 +75,14 @@ Subset_Reader::Subset_Reader( Data_Reader* dr, long size )
in = dr;
remain_ = dr->remain();
if ( remain_ > size )
- remain_ = size;
+ remain_ = max( 0l, size );
}
long Subset_Reader::remain() const { return remain_; }
long Subset_Reader::read_avail( void* p, long s )
{
+ s = max( 0l, s );
if ( s > remain_ )
s = remain_;
remain_ -= s;
@@ -85,7 +94,7 @@ long Subset_Reader::read_avail( void* p, long s )
Remaining_Reader::Remaining_Reader( void const* h, long size, Data_Reader* r )
{
header = (char const*) h;
- header_end = header + size;
+ header_end = header + max( 0l, size );
in = r;
}
@@ -93,6 +102,7 @@ long Remaining_Reader::remain() const { return header_end - header + in->remain(
long Remaining_Reader::read_first( void* out, long count )
{
+ count = max( 0l, count );
long first = header_end - header;
if ( first )
{
@@ -107,8 +117,9 @@ long Remaining_Reader::read_first( void* out, long count )
long Remaining_Reader::read_avail( void* out, long count )
{
+ count = max( 0l, count );
long first = read_first( out, count );
- long second = count - first;
+ long second = max( 0l, count - first );
if ( second )
{
second = in->read_avail( (char*) out + first, second );
@@ -120,8 +131,9 @@ long Remaining_Reader::read_avail( void* out, long count )
blargg_err_t Remaining_Reader::read( void* out, long count )
{
+ count = max( 0l, count );
long first = read_first( out, count );
- long second = count - first;
+ long second = max( 0l, count - first );
if ( !second )
return 0;
return in->read( (char*) out + first, second );
@@ -131,7 +143,7 @@ blargg_err_t Remaining_Reader::read( void* out, long count )
Mem_File_Reader::Mem_File_Reader( const void* p, long s ) :
begin( (const char*) p ),
- size_( s )
+ size_( max( 0l, s ) )
{
pos = 0;
}
@@ -141,6 +153,7 @@ long Mem_File_Reader::size() const { return size_; }
long Mem_File_Reader::read_avail( void* p, long s )
{
long r = remain();
+ s = max( 0l, s );
if ( s > r )
s = r;
memcpy( p, begin + pos, s );
@@ -152,6 +165,7 @@ long Mem_File_Reader::tell() const { return pos; }
blargg_err_t Mem_File_Reader::seek( long n )
{
+ RETURN_VALIDITY_CHECK( n >= 0 );
if ( n > size_ )
return eof_error;
pos = n;
@@ -164,7 +178,7 @@ Callback_Reader::Callback_Reader( callback_t c, long size, void* d ) :
callback( c ),
data( d )
{
- remain_ = size;
+ remain_ = max( 0l, size );
}
long Callback_Reader::remain() const { return remain_; }
@@ -173,13 +187,14 @@ long Callback_Reader::read_avail( void* out, long count )
{
if ( count > remain_ )
count = remain_;
- if ( Callback_Reader::read( out, count ) )
+ if ( count < 0 || Callback_Reader::read( out, count ) )
count = -1;
return count;
}
blargg_err_t Callback_Reader::read( void* out, long count )
{
+ RETURN_VALIDITY_CHECK( count >= 0 );
if ( count > remain_ )
return eof_error;
return callback( data, out, count );
@@ -210,11 +225,12 @@ long Std_File_Reader::size() const
long Std_File_Reader::read_avail( void* p, long s )
{
- return fread( p, 1, s, (FILE*) file_ );
+ return fread( p, 1, max( 0l, s ), (FILE*) file_ );
}
blargg_err_t Std_File_Reader::read( void* p, long s )
{
+ RETURN_VALIDITY_CHECK( s > 0 );
if ( s == (long) fread( p, 1, s, (FILE*) file_ ) )
return 0;
if ( feof( (FILE*) file_ ) )
diff --git a/libs/gme/gme/Data_Reader.h b/libs/gme/gme/Data_Reader.h
index acf571f67..6c22b678e 100644
--- a/libs/gme/gme/Data_Reader.h
+++ b/libs/gme/gme/Data_Reader.h
@@ -129,6 +129,8 @@ private:
};
#ifdef HAVE_ZLIB_H
+#include
+
// Gzip compressed file reader
class Gzip_File_Reader : public File_Reader {
public:
@@ -143,7 +145,7 @@ public:
long tell() const;
blargg_err_t seek( long );
private:
- void* file_;
+ gzFile file_;
long size_;
};
#endif
diff --git a/libs/gme/gme/Music_Emu.cpp b/libs/gme/gme/Music_Emu.cpp
index 30b25dcfc..942e86e27 100644
--- a/libs/gme/gme/Music_Emu.cpp
+++ b/libs/gme/gme/Music_Emu.cpp
@@ -178,6 +178,11 @@ blargg_long Music_Emu::msec_to_samples( blargg_long msec ) const
return (sec * sample_rate() + msec * sample_rate() / 1000) * stereo;
}
+long Music_Emu::tell_samples() const
+{
+ return out_time;
+}
+
long Music_Emu::tell() const
{
blargg_long rate = sample_rate() * stereo;
@@ -185,14 +190,18 @@ long Music_Emu::tell() const
return sec * 1000 + (out_time - sec * rate) * 1000 / rate;
}
-blargg_err_t Music_Emu::seek( long msec )
+blargg_err_t Music_Emu::seek_samples( long time )
{
- blargg_long time = msec_to_samples( msec );
if ( time < out_time )
RETURN_ERR( start_track( current_track_ ) );
return skip( time - out_time );
}
+blargg_err_t Music_Emu::seek( long msec )
+{
+ return seek_samples( msec_to_samples( msec ) );
+}
+
blargg_err_t Music_Emu::skip( long count )
{
require( current_track() >= 0 ); // start_track() must have been called already
diff --git a/libs/gme/gme/Music_Emu.h b/libs/gme/gme/Music_Emu.h
index b96f4b611..d98f7ce7e 100644
--- a/libs/gme/gme/Music_Emu.h
+++ b/libs/gme/gme/Music_Emu.h
@@ -41,9 +41,15 @@ public:
// Number of milliseconds (1000 msec = 1 second) played since beginning of track
long tell() const;
+ // Number of samples generated since beginning of track
+ long tell_samples() const;
+
// Seek to new time in track. Seeking backwards or far forward can take a while.
blargg_err_t seek( long msec );
+ // Equivalent to restarting track then skipping n samples
+ blargg_err_t seek_samples( long n );
+
// Skip n samples
blargg_err_t skip( long n );
diff --git a/libs/gme/gme/Nsfe_Emu.cpp b/libs/gme/gme/Nsfe_Emu.cpp
index 824a1a240..55ac4688f 100644
--- a/libs/gme/gme/Nsfe_Emu.cpp
+++ b/libs/gme/gme/Nsfe_Emu.cpp
@@ -134,6 +134,9 @@ blargg_err_t Nsfe_Info::load( Data_Reader& in, Nsf_Emu* nsf_emu )
RETURN_ERR( in.read( block_header, sizeof block_header ) );
blargg_long size = get_le32( block_header [0] );
blargg_long tag = get_le32( block_header [1] );
+
+ if ( size <= 0 )
+ return "Corrupt file";
//debug_printf( "tag: %c%c%c%c\n", char(tag), char(tag>>8), char(tag>>16), char(tag>>24) );
diff --git a/libs/gme/gme/Spc_Cpu.cpp b/libs/gme/gme/Spc_Cpu.cpp
index 90f60ed29..19aae1135 100644
--- a/libs/gme/gme/Spc_Cpu.cpp
+++ b/libs/gme/gme/Spc_Cpu.cpp
@@ -433,9 +433,7 @@ void Snes_Spc::cpu_write( int data, int addr, rel_time_t time )
#endif
// Registers other than $F2 and $F4-$F7
- //if ( reg != 2 && reg != 4 && reg != 5 && reg != 6 && reg != 7 )
- // TODO: this is a bit on the fragile side
- if ( ((~0x2F00 << (bits_in_int - 16)) << reg) < 0 ) // 36%
+ if ( reg != 2 && (reg < 4 || reg > 7) ) // 36%
cpu_write_smp_reg( data, time, reg );
}
// High mem/address wrap-around
diff --git a/libs/gme/gme/Spc_Cpu.h b/libs/gme/gme/Spc_Cpu.h
index 4742e0990..10c245090 100644
--- a/libs/gme/gme/Spc_Cpu.h
+++ b/libs/gme/gme/Spc_Cpu.h
@@ -76,8 +76,8 @@ Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
// TODO: remove non-wrapping versions?
#define SPC_NO_SP_WRAPAROUND 0
-#define SET_SP( v ) (sp = ram + 0x101 + (v))
-#define GET_SP() (sp - 0x101 - ram)
+#define SET_SP( v ) (sp = ram + 0x101 + ((uint8_t) v))
+#define GET_SP() (uint8_t (sp - 0x101 - ram))
#if SPC_NO_SP_WRAPAROUND
#define PUSH16( v ) (sp -= 2, SET_LE16( sp, v ))
@@ -485,7 +485,7 @@ loop:
case 0xAF: // MOV (X)+,A
WRITE_DP( 0, x, a + no_read_before_write );
- x++;
+ x = (uint8_t) (x + 1);
goto loop;
// 5. 8-BIT LOGIC OPERATION COMMANDS
@@ -808,7 +808,7 @@ loop:
unsigned temp = y * a;
a = (uint8_t) temp;
nz = ((temp >> 1) | temp) & 0x7F;
- y = temp >> 8;
+ y = (uint8_t) (temp >> 8);
nz |= y;
goto loop;
}
@@ -838,6 +838,7 @@ loop:
nz = (uint8_t) a;
a = (uint8_t) a;
+ y = (uint8_t) y;
goto loop;
}
@@ -1004,7 +1005,7 @@ loop:
case 0x7F: // RET1
temp = *sp;
SET_PC( GET_LE16( sp + 1 ) );
- sp += 3;
+ SET_SP( GET_SP() + 3 );
goto set_psw;
case 0x8E: // POP PSW
POP( temp );
diff --git a/libs/gme/gme/blargg_source.h b/libs/gme/gme/blargg_source.h
index b011777ad..b65afd30b 100644
--- a/libs/gme/gme/blargg_source.h
+++ b/libs/gme/gme/blargg_source.h
@@ -18,6 +18,19 @@ all other #include lines. */
#undef require
#define require( expr ) assert( expr )
+// Use to provide hints to compiler for optimized code layout in situations where we
+// can almost always expect a conditional to go one way or the other. Should only be
+// used in situations where an unexpected branch is truly exceptional though!
+#undef likely
+#undef unlikely
+#ifdef __GNUC__
+ #define likely( x ) __builtin_expect(x, 1)
+ #define unlikely( x ) __builtin_expect(x, 0)
+#else
+ #define likely( x ) (x)
+ #define unlikely( x ) (x)
+#endif
+
// Like printf() except output goes to debug log file. Might be defined to do
// nothing (not even evaluate its arguments).
// void debug_printf( const char* format, ... );
diff --git a/libs/gme/gme/gme.cpp b/libs/gme/gme/gme.cpp
index c05f25eb4..47709840a 100644
--- a/libs/gme/gme/gme.cpp
+++ b/libs/gme/gme/gme.cpp
@@ -337,7 +337,9 @@ BLARGG_EXPORT gme_err_t gme_play ( Music_Emu* me, int n, short* p )
BLARGG_EXPORT void gme_set_fade ( Music_Emu* me, int start_msec ) { me->set_fade( start_msec ); }
BLARGG_EXPORT int gme_track_ended ( Music_Emu const* me ) { return me->track_ended(); }
BLARGG_EXPORT int gme_tell ( Music_Emu const* me ) { return me->tell(); }
+BLARGG_EXPORT int gme_tell_samples ( Music_Emu const* me ) { return me->tell_samples(); }
BLARGG_EXPORT gme_err_t gme_seek ( Music_Emu* me, int msec ) { return me->seek( msec ); }
+BLARGG_EXPORT gme_err_t gme_seek_samples ( Music_Emu* me, int n ) { return me->seek_samples( n ); }
BLARGG_EXPORT int gme_voice_count ( Music_Emu const* me ) { return me->voice_count(); }
BLARGG_EXPORT void gme_ignore_silence ( Music_Emu* me, int disable ) { me->ignore_silence( disable != 0 ); }
BLARGG_EXPORT void gme_set_tempo ( Music_Emu* me, double t ) { me->set_tempo( t ); }
diff --git a/libs/gme/gme/gme.h b/libs/gme/gme/gme.h
index 1f2a2d150..cb07061b4 100644
--- a/libs/gme/gme/gme.h
+++ b/libs/gme/gme/gme.h
@@ -1,6 +1,6 @@
/* Game music emulator library C interface (also usable from C++) */
-/* Game_Music_Emu 0.6.0 */
+/* Game_Music_Emu 0.6.1 */
#ifndef GME_H
#define GME_H
@@ -8,7 +8,7 @@
extern "C" {
#endif
-#define GME_VERSION 0x000600 /* 1 byte major, 1 byte minor, 1 byte patch-level */
+#define GME_VERSION 0x000601 /* 1 byte major, 1 byte minor, 1 byte patch-level */
/* Error string returned by library functions, or NULL if no error (success) */
typedef const char* gme_err_t;
@@ -47,9 +47,15 @@ int gme_track_ended( Music_Emu const* );
/* Number of milliseconds (1000 = one second) played since beginning of track */
int gme_tell( Music_Emu const* );
+/* Number of samples generated since beginning of track */
+int gme_tell_samples( Music_Emu const* );
+
/* Seek to new time in track. Seeking backwards or far forward can take a while. */
gme_err_t gme_seek( Music_Emu*, int msec );
+/* Equivalent to restarting track then skipping n samples */
+gme_err_t gme_seek_samples( Music_Emu*, int n );
+
/******** Informational ********/
diff --git a/libs/gme/gme/libgme.pc.in b/libs/gme/gme/libgme.pc.in
index 4f420d9ed..49fd5b1df 100644
--- a/libs/gme/gme/libgme.pc.in
+++ b/libs/gme/gme/libgme.pc.in
@@ -3,7 +3,7 @@
# later are used by pkg-config.
prefix=@CMAKE_INSTALL_PREFIX@
exec_prefix=${prefix}
-lib_suffix=
+lib_suffix=@LIB_SUFFIX@
libdir=${exec_prefix}/lib${lib_suffix}
includedir=${prefix}/include
@@ -13,3 +13,4 @@ URL: http://code.google.com/p/game-music-emu/
Version: @GME_VERSION@
Cflags: -I${includedir}
Libs: -L${libdir} -lgme
+Libs.private: -lstdc++
diff --git a/libs/gme/include/gme/gme.h b/libs/gme/include/gme/gme.h
index 1f2a2d150..cb07061b4 100644
--- a/libs/gme/include/gme/gme.h
+++ b/libs/gme/include/gme/gme.h
@@ -1,6 +1,6 @@
/* Game music emulator library C interface (also usable from C++) */
-/* Game_Music_Emu 0.6.0 */
+/* Game_Music_Emu 0.6.1 */
#ifndef GME_H
#define GME_H
@@ -8,7 +8,7 @@
extern "C" {
#endif
-#define GME_VERSION 0x000600 /* 1 byte major, 1 byte minor, 1 byte patch-level */
+#define GME_VERSION 0x000601 /* 1 byte major, 1 byte minor, 1 byte patch-level */
/* Error string returned by library functions, or NULL if no error (success) */
typedef const char* gme_err_t;
@@ -47,9 +47,15 @@ int gme_track_ended( Music_Emu const* );
/* Number of milliseconds (1000 = one second) played since beginning of track */
int gme_tell( Music_Emu const* );
+/* Number of samples generated since beginning of track */
+int gme_tell_samples( Music_Emu const* );
+
/* Seek to new time in track. Seeking backwards or far forward can take a while. */
gme_err_t gme_seek( Music_Emu*, int msec );
+/* Equivalent to restarting track then skipping n samples */
+gme_err_t gme_seek_samples( Music_Emu*, int n );
+
/******** Informational ********/
diff --git a/libs/gme/readme.txt b/libs/gme/readme.txt
index 82a501dbd..4cfe5e7a8 100644
--- a/libs/gme/readme.txt
+++ b/libs/gme/readme.txt
@@ -1,4 +1,4 @@
-Game_Music_Emu 0.6.0: Game Music Emulators
+Game_Music_Emu 0.6.2: Game Music Emulators
------------------------------------------
Game_Music_Emu is a collection of video game music file emulators that
support the following formats and systems:
@@ -34,30 +34,45 @@ several architectures, Mac OS, MorphOS, Xbox, PlayStation Portable,
GP2X, and Nintendo DS.
Author : Shay Green
-Website: http://www.slack.net/~ant/
-Forum : http://groups.google.com/group/blargg-sound-libs
+Website: https://bitbucket.org/mpyne/game-music-emu/wiki/Home
License: GNU Lesser General Public License (LGPL)
+Current Maintainer: Michael Pyne
Getting Started
---------------
Build a program consisting of demo/basics.c, demo/Wave_Writer.cpp, and
-all source files in gme/. If you have CMake 2.6 or later, execute
+all source files in gme/.
- run cmake
- cd demo
- run make
+Or, if you have CMake 2.6 or later, execute at a command prompt (from the
+extracted source directory):
-Be sure "test.nsf" is in the same directory as the program. Running it
+ mkdir build
+ cd build
+ cmake ../ # <-- Pass any needed CMake flags here
+ make # To build the library
+ cd demo
+ make # To build the demo itself
+
+Be sure "test.nsf" is in the same directory as the demo program. Running it
should generate the recording "out.wav".
+You can use "make install" to install the library. To choose where to install
+the library to, use the CMake argument "-DCMAKE_INSTALL_PREFIX=/usr/local"
+(and replace /usr/local with the base path you wish to use). Alternately, you
+can specify the base path to install to when you run "make install" by passing
+'DESTDIR=/usr/local' on the make install command line (again, replace
+/usr/local as appropriate).
+
+To build a static library instead of shared (the default), pass
+-DBUILD_SHARED_LIBS=OFF to the cmake command when running cmake.
+
A slightly more extensive demo application is available in the player/
directory. It requires SDL to build.
Read gme.txt for more information. Post to the discussion forum for
assistance.
-
Files
-----
gme.txt General notes about the library
diff --git a/libs/gme/win32/libgme.dll.a b/libs/gme/win32/libgme.dll.a
index d56d87396..2c5e95853 100644
Binary files a/libs/gme/win32/libgme.dll.a and b/libs/gme/win32/libgme.dll.a differ
diff --git a/libs/gme/win64/libgme.dll.a b/libs/gme/win64/libgme.dll.a
index 38079dc2a..8348f12de 100644
Binary files a/libs/gme/win64/libgme.dll.a and b/libs/gme/win64/libgme.dll.a differ
diff --git a/libs/libgme.props b/libs/libgme.props
new file mode 100644
index 000000000..209f6b9a8
--- /dev/null
+++ b/libs/libgme.props
@@ -0,0 +1,16 @@
+
+
+
+
+
+ $(SolutionDir)libs\gme\include;$(IncludePath)
+ $(SolutionDir)libs\gme\win32;$(LibraryPath)
+ $(SolutionDir)libs\gme\win64;$(LibraryPath)
+
+
+
+ libgme.dll.a;%(AdditionalDependencies)
+
+
+
+
\ No newline at end of file
diff --git a/libs/libopenmpt.props b/libs/libopenmpt.props
new file mode 100644
index 000000000..8825907b6
--- /dev/null
+++ b/libs/libopenmpt.props
@@ -0,0 +1,16 @@
+
+
+
+
+
+ $(SolutionDir)libs\libopenmpt\inc;$(IncludePath)
+ $(SolutionDir)libs\libopenmpt\lib\x86;$(LibraryPath)
+ $(SolutionDir)libs\libopenmpt\lib\x86_64;$(LibraryPath)
+
+
+
+ libopenmpt.lib;%(AdditionalDependencies)
+
+
+
+
\ No newline at end of file
diff --git a/libs/libopenmpt/LICENSE.txt b/libs/libopenmpt/LICENSE.txt
new file mode 100644
index 000000000..e0f012166
--- /dev/null
+++ b/libs/libopenmpt/LICENSE.txt
@@ -0,0 +1,26 @@
+Copyright (c) 2004-2019, OpenMPT contributors
+Copyright (c) 1997-2003, Olivier Lapicque
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ * Neither the name of the OpenMPT project nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS ``AS IS'' AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
diff --git a/libs/libopenmpt/Licenses/License.Vorbis.txt b/libs/libopenmpt/Licenses/License.Vorbis.txt
new file mode 100644
index 000000000..153b926a1
--- /dev/null
+++ b/libs/libopenmpt/Licenses/License.Vorbis.txt
@@ -0,0 +1,28 @@
+Copyright (c) 2002-2018 Xiph.org Foundation
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+- Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+
+- Redistributions in binary form must reproduce the above copyright
+notice, this list of conditions and the following disclaimer in the
+documentation and/or other materials provided with the distribution.
+
+- Neither the name of the Xiph.org Foundation nor the names of its
+contributors may be used to endorse or promote products derived from
+this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION
+OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/libs/libopenmpt/Licenses/License.mpg123.Authors.txt b/libs/libopenmpt/Licenses/License.mpg123.Authors.txt
new file mode 100644
index 000000000..c1eac976d
--- /dev/null
+++ b/libs/libopenmpt/Licenses/License.mpg123.Authors.txt
@@ -0,0 +1,175 @@
+This is an attempt to give credit to the people who contributed in some way to the mpg123 project.
+There are names and email addresses listed. Please use these addresses only to contact contributors with some question about their mpg123 contribution.
+You are explicitly not allowed to send them unwanted business offers or to question the quality of their sex life.
+--------------------
+
+Being on the list of contributing authors not necessarily means that there
+is significant copyright in parts of the source code. There are obviously
+contributions of differing complexity. I try to mention people who motivated
+changes at least by suggesting some definite code changes, even if their
+code did not enter the mpg123 source verbatim. Trivial changes like pointing
+out ovbious syntax errors that make compilers cry do not land here.
+
+--------------------
+
+Current maintainers with various sorts of contributions:
+ Thomas Orgis
+ Patrick Dehne
+ Jonathan Yong <10walls@gmail.com>
+ Taihei Momma
+
+Co-initiator of the revived mpg123 project, but not that involved anymore:
+ Nicholas J Humfrey
+
+Special thanks go to Taihei, the person who keeps the assembly optimisations alive
+and takes care of portability to OSX/iOS platforms.
+
+Generic address pointing to the current maintainer (hopefully still works in future in case maintainership will change again):
+
+The creator: Michael Hipp (email: hippm@informatik.uni-tuebingen.de - please bother maintainers first)
+
+Contributions/ideas Thomas Orgis era (includes backports from mhipp trunk):
+
+Won-Kyu Park : patch to get rid of asm textrels (x86 PIC)
+Michael Weiser : update of coreaudio output to AudioComponents API
+Bent Bisballe Nyeng : patch for MPG123_NO_PEEK_END and MPG123_FORCE_SEEKABLE
+Eric S. Raymond : man page fixes
+Tobias Weber : patch for --disable-equalizer
+Hans de Goede : patch to skip APE tags
+Stephan Vedder : MSVC++ 2013 port update
+Rajeev V. Pillai : pointing out/patching issues in HTTP code and behaviour of mpg123 remote/terminal control
+Jarno Lehtinen : tinyalsa output
+Anthony Wells : initial version of ID3v2 APIC patch
+David Wohlferd : Win32 WaveOut buffer destructor fix.
+Mike Gorchak : QNX native audio output (QSA)
+Dan McGee : various patches (also for test suite)
+Jonathan Yong (jon_y) <10walls@gmail.com>: win32 hacking, win32 wasapi audio.
+Malcolm Boczek : Common language runtime wrapper
+Elbert Pol (TeLLie) : OS/2 port fixup
+Jeroen Valkonet : motivate pitch control, suggestive patch for pitch command in generic control interface
+Andy Hefner : patch for that second UTF16 issue
+Taihei Monma : A whole lot of new/improved assembler code, including Altivec!
+Christian Weisgerber , Brad Smith: sndio output
+Patrick Dehne (P4tr3ck) : more MSVC++ porting, patch to handle missing bit reservoirs
+Thorsten Glaser : icy2utf8, suggest utf8 locale stuff
+Dan Smith : ABI fixes for ensuring stack alignment (esp. for MinGW-built DLL with MSVC)
+Michael Ryzhykh : mpg123.spec.in
+Stefan Lenselink : initial aRts output
+Sergej Kvachonok : win32 audio rewrite
+Winston: SunOS-4.1.4/gcc-2.7.0 testing and suggestions for fixes (legacy Makefile, integer type headers)
+Mika Tiainen: pointing out the fix for the UTF to ASCII filtering of tags to actually work
+Nick Kurshev : extended 3dnow (from mplayer)
+Zuxy Meng : SSE (from mplayer)
+Honza : idea and prototype patch for ICY meta data support
+Petr Baudis : patches: term sigcont, id3 display unicode fallback and condensed output
+Petr Salinger : i486 enhancement
+mpdavig@users.sourceforge.net: linux-ppc-nas Makefile.legacy entry
+Adrian Bacon : patched decode_i586_dither (noise shaped float/int rounding)
+Cool Feet Audio project : realtime equalizer control
+Steve Grundell : clean stdout in control mode with stdout decoding
+Romain Dolbeau : Altivec support (taken from mplayer)
+higway : MMX Patch
+Clemens Ladisch : ALSA 0.9/1.0 support
+
+Debian Daniel Kobras era:
+
+Steve Kemp
+Dan Olson
+Syuuhei Kashiyama
+Rupert Levene
+Andreas Dilger
+Erik B. Andersen
+Chris Butler
+Martin Sjogren
+Chet Hosey
+Roland Rosenfeld
+
+
+Debian Colin Watson era:
+
+Helge Deller
+Chet Hosey
+Christopher C. Chimelis
+Roland Rosenfeld
+Marcelo E. Magallon
+
+
+Initial Debianers:
+
+Tommi Virtanen
+Paul Haggart
+
+
+Contributions/ideas Michael Hipp era:
+
+Mikko Tommila: DCT9
+Oliver Fromme
+MPEG Software Simulation Group: reference decoder package
+Tobias Bading: idea for DCT64 in subband synthesis from maplay package
+Jeff Tsay and Mikko Tommila: MDCT36 from maplay package
+Philipp Knirsch : DCT36/manual unroll idea
+Thomas Woerner: SGI Audio
+Damien Clermonte: HP-UX audio fixes
+Niclas Lindstrom : OS2 port
+Stefan Bieschewski : Pentium optimizations, decode_i586.s
+Martin Denn : NAS port
+Niklas Beisert : MPEG 2.5 tables
+ and : NetBSD Patch(es)
+Kevin Brintnall : BSD patch
+Tony Million: win32 port
+Steven Tiger Lang: advanced shuffle
+Eric B. Mitchell: esd port
+Ryan R. Prosser : esd port for Solaris
+Andreas Neuhaus: initial generic control interface
+
+(additionally fetched from changelog:)
+
+Ralf Hildebrandt : audio_alib changes
+: BSDOS 4.0 with gcc added to Makefile
+Bertrand Petit : frontend changes
+Erik Mouw : SGI audio fix for non RAD machines
+Daniel O'Connor : freebsd-esd make-entry
+D. Skarda <0rfelyus@atrey.karlin.mff.cuni.cz>: enhanced head_check
+Wilson, Jeff D : xterm-title
+Robert Bihlmeyer : esd changes
+Hannu Napari's : SGI audio patches
+: native AIX support
+: playlist patch
+Gilles Zunino : SGI audio patches
+Matthew Parslow : esdserver patch
+: equalizer patch (equalfile setting)
+Ducroquet Erwan : HPUX/ALib support
+Shane Wegner : genrepatch
+Samuel Audet : wav-File patch
+"J. Dean Brederson" : SGI-RAD support
+Chou Ye-chi : sajberplay/FreeBSD patch
+Fabrice Bellard : 486 optimizations
+A. Hermansen and J. Kysela : ALSA output
+KIMURA Takuhiro : K6-3DNow
+Petr Stehlik : MINT
+Andy : float2int speed up proposal
+Brian Foutz : TK3Play
+Thomas Niederreiter : RIFF header fix
+Stefan Gybas : m68k patch
+Grant Erickson : Linux PPC patch
+Peter Berger : BSDi patch
+Henrik P Johnson : HTTP auth
+Steven Tiger Lang : advanced shuffle
+"Brian J. Swetland" : front-end (remote) patch
+
+Tillmann Steinbrecher : shuffle patch
+M.Stekelenburg : i386-getbits
+Antti Andreimann : outburst patch
+Hur TaeSung : 'http accept' patch
+
+(from post-0.59 changes that yet have to go into new trunk:)
+
+Hans Schwengeler : audio_dec additions
+Wojciech Barañski's Mp3Play (check the tools folder): Mp3Play frontend
+Daniel Koukola: audio_oss.c patch
+Munechika SUMIKAWA : IPv6
+TEMNOTA : HTTP,FTP patch/playlist fix
+Peter Surda : VBR patch
+Ben : ARM startup time improvements
+Dave MacKenzie : init_output() patch
+pasky's : close-on-stop patch
diff --git a/libs/libopenmpt/Licenses/License.mpg123.txt b/libs/libopenmpt/Licenses/License.mpg123.txt
new file mode 100644
index 000000000..d7bb85fc3
--- /dev/null
+++ b/libs/libopenmpt/Licenses/License.mpg123.txt
@@ -0,0 +1,772 @@
+This is the file that contains the terms of use, copying, etc. for the mpg123 distribution package.
+
+Main message, to include in "About ..." boxes, etc:
+
+ Copyright (c) 1995-2013 by Michael Hipp and others,
+ free software under the terms of the LGPL v2.1
+
+There is an attempt to cover the actual list of authors in the AUTHORS file.
+Project maintainer since 2006 is Thomas Orgis and many people have contributed
+since the Michael Hipp era, but he stays the initial source and it would
+be impractical to count them all individually, so it's "and others".
+Source files contain the phrase "the mpg123 project" to the same effect
+in their license boilerplate; especially those that were added after
+maintainership changed. The person mainly responsible for the first version
+is usually named in the phrase "initially written by ...".
+
+All files in the distribution that don't carry a license note on their own are
+licensed under the terms of the LGPL 2.1; exceptions may apply, especially to
+files not in the official distribution but in the revision control repository.
+
+The formal license text follows.
+
+=======================
+1. The LGPL version 2.1
+=======================
+
+
+ GNU LESSER GENERAL PUBLIC LICENSE
+ Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL. It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+ This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it. You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+ When we speak of free software, we are referring to freedom of use,
+not price. Our General Public Licenses are designed to make sure that
+you have the freedom to distribute copies of free software (and charge
+for this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+ To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights. These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+ For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you. You must make sure that they, too, receive or can get the source
+code. If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it. And you must show them these terms so they know their rights.
+
+ We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+ To protect each distributor, we want to make it very clear that
+there is no warranty for the free library. Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+
+ Finally, software patents pose a constant threat to the existence of
+any free program. We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder. Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+ Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License. This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License. We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+ When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library. The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom. The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+ We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License. It also provides other free software developers Less
+of an advantage over competing non-free programs. These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries. However, the Lesser license provides advantages in certain
+special circumstances.
+
+ For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard. To achieve this, non-free programs must be
+allowed to use the library. A more frequent case is that a free
+library does the same job as widely used non-free libraries. In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+ In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software. For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+ Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+ The precise terms and conditions for copying, distribution and
+modification follow. Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library". The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+
+ GNU LESSER GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+ A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+ The "Library", below, refers to any such software library or work
+which has been distributed under these terms. A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language. (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+ "Source code" for a work means the preferred form of the work for
+making modifications to it. For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+ Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it). Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+ 1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+ You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+
+ 2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) The modified work must itself be a software library.
+
+ b) You must cause the files modified to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ c) You must cause the whole of the work to be licensed at no
+ charge to all third parties under the terms of this License.
+
+ d) If a facility in the modified Library refers to a function or a
+ table of data to be supplied by an application program that uses
+ the facility, other than as an argument passed when the facility
+ is invoked, then you must make a good faith effort to ensure that,
+ in the event an application does not supply such function or
+ table, the facility still operates, and performs whatever part of
+ its purpose remains meaningful.
+
+ (For example, a function in a library to compute square roots has
+ a purpose that is entirely well-defined independent of the
+ application. Therefore, Subsection 2d requires that any
+ application-supplied function or table used by this function must
+ be optional: if the application does not supply it, the square
+ root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library. To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License. (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.) Do not make any other change in
+these notices.
+
+ Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+ This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+ 4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+ If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library". Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+ However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library". The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+ When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library. The
+threshold for this to be true is not precisely defined by law.
+
+ If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work. (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+ Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+
+ 6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+ You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License. You must supply a copy of this License. If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License. Also, you must do one
+of these things:
+
+ a) Accompany the work with the complete corresponding
+ machine-readable source code for the Library including whatever
+ changes were used in the work (which must be distributed under
+ Sections 1 and 2 above); and, if the work is an executable linked
+ with the Library, with the complete machine-readable "work that
+ uses the Library", as object code and/or source code, so that the
+ user can modify the Library and then relink to produce a modified
+ executable containing the modified Library. (It is understood
+ that the user who changes the contents of definitions files in the
+ Library will not necessarily be able to recompile the application
+ to use the modified definitions.)
+
+ b) Use a suitable shared library mechanism for linking with the
+ Library. A suitable mechanism is one that (1) uses at run time a
+ copy of the library already present on the user's computer system,
+ rather than copying library functions into the executable, and (2)
+ will operate properly with a modified version of the library, if
+ the user installs one, as long as the modified version is
+ interface-compatible with the version that the work was made with.
+
+ c) Accompany the work with a written offer, valid for at
+ least three years, to give the same user the materials
+ specified in Subsection 6a, above, for a charge no more
+ than the cost of performing this distribution.
+
+ d) If distribution of the work is made by offering access to copy
+ from a designated place, offer equivalent access to copy the above
+ specified materials from the same place.
+
+ e) Verify that the user has already received a copy of these
+ materials or that you have already sent this user a copy.
+
+ For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it. However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+ It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system. Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+
+ 7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+ a) Accompany the combined library with a copy of the same work
+ based on the Library, uncombined with any other library
+ facilities. This must be distributed under the terms of the
+ Sections above.
+
+ b) Give prominent notice with the combined library of the fact
+ that part of it is a work based on the Library, and explaining
+ where to find the accompanying uncombined form of the same work.
+
+ 8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License. Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License. However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+ 9. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Library or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+ 10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+
+ 11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all. For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded. In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+ 13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation. If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+
+ 14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission. For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this. Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+ NO WARRANTY
+
+ 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+
+====================
+2. The GPL version 2
+====================
+
+
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Lesser General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
diff --git a/libs/libopenmpt/Licenses/License.ogg.txt b/libs/libopenmpt/Licenses/License.ogg.txt
new file mode 100644
index 000000000..6111c6c5a
--- /dev/null
+++ b/libs/libopenmpt/Licenses/License.ogg.txt
@@ -0,0 +1,28 @@
+Copyright (c) 2002, Xiph.org Foundation
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+- Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+
+- Redistributions in binary form must reproduce the above copyright
+notice, this list of conditions and the following disclaimer in the
+documentation and/or other materials provided with the distribution.
+
+- Neither the name of the Xiph.org Foundation nor the names of its
+contributors may be used to endorse or promote products derived from
+this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION
+OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/libs/libopenmpt/Licenses/License.zlib.txt b/libs/libopenmpt/Licenses/License.zlib.txt
new file mode 100644
index 000000000..51106de47
--- /dev/null
+++ b/libs/libopenmpt/Licenses/License.zlib.txt
@@ -0,0 +1,115 @@
+ZLIB DATA COMPRESSION LIBRARY
+
+zlib 1.2.11 is a general purpose data compression library. All the code is
+thread safe. The data format used by the zlib library is described by RFCs
+(Request for Comments) 1950 to 1952 in the files
+http://tools.ietf.org/html/rfc1950 (zlib format), rfc1951 (deflate format) and
+rfc1952 (gzip format).
+
+All functions of the compression library are documented in the file zlib.h
+(volunteer to write man pages welcome, contact zlib@gzip.org). A usage example
+of the library is given in the file test/example.c which also tests that
+the library is working correctly. Another example is given in the file
+test/minigzip.c. The compression library itself is composed of all source
+files in the root directory.
+
+To compile all files and run the test program, follow the instructions given at
+the top of Makefile.in. In short "./configure; make test", and if that goes
+well, "make install" should work for most flavors of Unix. For Windows, use
+one of the special makefiles in win32/ or contrib/vstudio/ . For VMS, use
+make_vms.com.
+
+Questions about zlib should be sent to , or to Gilles Vollant
+ for the Windows DLL version. The zlib home page is
+http://zlib.net/ . Before reporting a problem, please check this site to
+verify that you have the latest version of zlib; otherwise get the latest
+version and check whether the problem still exists or not.
+
+PLEASE read the zlib FAQ http://zlib.net/zlib_faq.html before asking for help.
+
+Mark Nelson wrote an article about zlib for the Jan. 1997
+issue of Dr. Dobb's Journal; a copy of the article is available at
+http://marknelson.us/1997/01/01/zlib-engine/ .
+
+The changes made in version 1.2.11 are documented in the file ChangeLog.
+
+Unsupported third party contributions are provided in directory contrib/ .
+
+zlib is available in Java using the java.util.zip package, documented at
+http://java.sun.com/developer/technicalArticles/Programming/compression/ .
+
+A Perl interface to zlib written by Paul Marquess is available
+at CPAN (Comprehensive Perl Archive Network) sites, including
+http://search.cpan.org/~pmqs/IO-Compress-Zlib/ .
+
+A Python interface to zlib written by A.M. Kuchling is
+available in Python 1.5 and later versions, see
+http://docs.python.org/library/zlib.html .
+
+zlib is built into tcl: http://wiki.tcl.tk/4610 .
+
+An experimental package to read and write files in .zip format, written on top
+of zlib by Gilles Vollant , is available in the
+contrib/minizip directory of zlib.
+
+
+Notes for some targets:
+
+- For Windows DLL versions, please see win32/DLL_FAQ.txt
+
+- For 64-bit Irix, deflate.c must be compiled without any optimization. With
+ -O, one libpng test fails. The test works in 32 bit mode (with the -n32
+ compiler flag). The compiler bug has been reported to SGI.
+
+- zlib doesn't work with gcc 2.6.3 on a DEC 3000/300LX under OSF/1 2.1 it works
+ when compiled with cc.
+
+- On Digital Unix 4.0D (formely OSF/1) on AlphaServer, the cc option -std1 is
+ necessary to get gzprintf working correctly. This is done by configure.
+
+- zlib doesn't work on HP-UX 9.05 with some versions of /bin/cc. It works with
+ other compilers. Use "make test" to check your compiler.
+
+- gzdopen is not supported on RISCOS or BEOS.
+
+- For PalmOs, see http://palmzlib.sourceforge.net/
+
+
+Acknowledgments:
+
+ The deflate format used by zlib was defined by Phil Katz. The deflate and
+ zlib specifications were written by L. Peter Deutsch. Thanks to all the
+ people who reported problems and suggested various improvements in zlib; they
+ are too numerous to cite here.
+
+Copyright notice:
+
+ (C) 1995-2017 Jean-loup Gailly and Mark Adler
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+
+ Jean-loup Gailly Mark Adler
+ jloup@gzip.org madler@alumni.caltech.edu
+
+If you use the zlib library in a product, we would appreciate *not* receiving
+lengthy legal documents to sign. The sources are provided for free but without
+warranty of any kind. The library has been entirely written by Jean-loup
+Gailly and Mark Adler; it does not include third-party code.
+
+If you redistribute modified sources, we would appreciate that you include in
+the file ChangeLog history information documenting your changes. Please read
+the FAQ for more information on the distribution of modified source versions.
diff --git a/libs/libopenmpt/SRB2NOTE-DEBIAN.md b/libs/libopenmpt/SRB2NOTE-DEBIAN.md
new file mode 100644
index 000000000..7e050d29a
--- /dev/null
+++ b/libs/libopenmpt/SRB2NOTE-DEBIAN.md
@@ -0,0 +1,90 @@
+# libopenmpt Debian backport info
+
+Backported libopenmpt 0.4.0 packages are available at ppa:stjr/srb2
+for Ubuntu Disco, Cosmic, Bionic, Xenial, and Trusty as of 2019/01/04.
+
+Debian Jessie users should use the Trusty package. Later Debian versions
+may use Disco or another working version.
+
+* libopenmpt 0.4.0 source package: http://archive.ubuntu.com/ubuntu/pool/universe/libo/libopenmpt/libopenmpt_0.4.0-1.dsc
+
+# Backporting from Disco to Cosmic and Bionic
+
+Cosmic and Bionic require no changes to the source package. They have
+the prerequisite `debhelper` and `dpkg-dev` versions, a matching
+`automake` version (1.15), as well as G++ > 5.
+
+Use the `backportpackage` script to automatically tag the package to
+Cosmic and Bionic, then upload to PPA:
+
+```
+sudo apt install ubuntu-dev-tools
+export UBUMAIL="John Doe " # Name and email associated with your PGP sign key
+backportpackage -d [cosmic/bionic] -u [path-to-ppa] --key=[key-fingerprint] http://archive.ubuntu.com/ubuntu/pool/universe/libo/libopenmpt/libopenmpt_0.4.0-1.dsc
+```
+
+# Backporting from Disco to Xenial
+
+Download the package:
+
+```
+dget http://archive.ubuntu.com/ubuntu/pool/universe/libo/libopenmpt/libopenmpt_0.4.0-1.dsc
+```
+
+Xenial has an earlier `debhelper` version, but the rest of the prerequisites
+are available.
+
+The required changes (see patch `debian/libopenmpt-0.4.0-xenial-backport.diff` in this directory):
+
+* `debian/control`
+ * Add `automake` to Build-Depends
+ * Change `debhelper` version to `(>= 9.0~)`
+* `debian/compat`
+ * Change to `10`
+
+Then run these commands:
+
+```
+dch -i # Edit the changelog; make sure the Name and email match the PGP sign key and that the changelog targets xenial
+debuild -s -d -k0x[key-fingerprint] # Build the updated package
+dput [path-to-ppa] [path-to-changes-file] # Upload to PPA
+```
+
+# Backporting from Disco to Trusty
+
+Download the package:
+
+```
+dget http://archive.ubuntu.com/ubuntu/pool/universe/libo/libopenmpt/libopenmpt_0.4.0-1.dsc
+```
+
+Trusty requires more changes because it uses G++ 4.8 whereas the source
+package expects G++ >= 5. Automake is an earlier version as well --
+1.14 vs 1.15 -- so `autoreconf` needs to be run at build time.
+
+The required changes (see patch `debian/libopenmpt-0.4.0-trusty-backport.diff` in this directory):
+
+* `debian/control`
+ * Add `automake` and `libtool` to Build-Depends
+ * Change `debhelper` version to `(>= 9.0~)`
+ * Change `dpkg-dev` version to `(>= 1.17.0)`
+* `debian/compat`
+ * Change to `10`
+* `debian/rules`
+ * Under `override_dh_auto_configure`, input this line as the first command:
+ `autoreconf --force --install`
+ * This re-configures the package for Automake 1.14
+* `debian/libopenmpt-modplug1.symbols` and `debian/libopenmpt0.symbols`
+ * Delete these files
+ * The C++ ABI for G++ 4.8 is incompatible with G++ >= 5, so the
+ generated symbols will be different than the expected symbols
+ in the `*.symbols` files. Deleting these files will skip the
+ symbol check.
+
+Then run these commands:
+
+```
+dch -i # Edit the changelog; make sure the Name and email match the PGP sign key and that the changelog targets trusty
+debuild -s -d -k0x[key-fingerprint] # Build the updated package
+dput [path-to-ppa] [path-to-changes-file] # Upload to PPA
+```
diff --git a/libs/libopenmpt/SRB2NOTE.md b/libs/libopenmpt/SRB2NOTE.md
new file mode 100644
index 000000000..d664ddd7e
--- /dev/null
+++ b/libs/libopenmpt/SRB2NOTE.md
@@ -0,0 +1,54 @@
+# libopenmpt mingw-w64 binary info
+
+Current built version as of 2019/05/23 is 0.4.4+r11531.pkg
+
+* mingw binaries (.dll): `bin/[x86 or x86_64]/mingw`
+* mingw import libraries (.dll.a): `lib/[x86 or x86_64]/mingw`
+
+# Building libopenmpt with mingw-w64
+
+libopenmpt must be built from the Makefile / Android dev package in the
+[Downloads page](https://lib.openmpt.org/libopenmpt/download/#all-downloads)
+
+Use the mingw-w64 distributions from
+[SourceForge](https://sourceforge.net/projects/mingw-w64/files/#readme).
+
+You can download the appropriate 7-zip archive, extract to a folder of
+your choice, remove any existing mingw directories from your PATH,
+then call `mingw32-make.exe` from its direct location.
+
+FOR LIBOPENMPT, YOU MUST USE A MINGW PACKAGE THAT SUPPORTS THE POSIX
+THREADING MODEL! DO NOT COMPILE WITH A WIN32 THREADING MODEL!
+
+I use GCC 7.3.0:
+
+* [x86_64-posix-seh](https://sourceforge.net/projects/mingw-w64/files/Toolchains%20targetting%20Win64/Personal%20Builds/mingw-builds/7.3.0/threads-posix/seh/x86_64-7.3.0-release-posix-seh-rt_v5-rev0.7z)
+* [i686-posix-dwarf](https://sourceforge.net/projects/mingw-w64/files/Toolchains%20targetting%20Win32/Personal%20Builds/mingw-builds/7.3.0/threads-posix/dwarf/i686-7.3.0-release-posix-dwarf-rt_v5-rev0.7z)
+
+## x86 build instructions
+
+```
+set CFLAGS=-march=pentium -static-libgcc
+set CXXFLAGS=-march=pentium -static-libgcc -static-libstdc++
+set LDFLAGS=-Wl,--out-implib,bin/libopenmpt.dll.a -Wl,-Bstatic,--whole-archive -lwinpthread -Wl,-Bdynamic,--no-whole-archive
+
+cd [libopenmpt-make-src]
+[x86-mingw-w64-bin]/mingw32-make.exe CONFIG=mingw64-win32
+```
+
+`libopenmpt.dll` and `libopenmpt.dll.a` will be built in the
+`bin/` folder.
+
+## x86_64 build instructions
+
+```
+set CFLAGS=-march=nocona -static-libgcc
+set CXXFLAGS=-march=nocona -static-libgcc -static-libstdc++
+set LDFLAGS=-Wl,--out-implib,bin/libopenmpt.dll.a -Wl,-Bstatic,--whole-archive -lwinpthread -Wl,-Bdynamic,--no-whole-archive
+
+cd [libopenmpt-make-src]
+[x86_64-mingw-w64-bin]/mingw32-make.exe CONFIG=mingw64-win64
+```
+
+`libopenmpt.dll` and `libopenmpt.dll.a` will be built in the
+`bin/` folder.
\ No newline at end of file
diff --git a/libs/libopenmpt/bin/x86/libopenmpt.dll b/libs/libopenmpt/bin/x86/libopenmpt.dll
new file mode 100644
index 000000000..0fc9e7656
Binary files /dev/null and b/libs/libopenmpt/bin/x86/libopenmpt.dll differ
diff --git a/libs/libopenmpt/bin/x86/mingw/libopenmpt.dll b/libs/libopenmpt/bin/x86/mingw/libopenmpt.dll
new file mode 100644
index 000000000..5fa364256
Binary files /dev/null and b/libs/libopenmpt/bin/x86/mingw/libopenmpt.dll differ
diff --git a/libs/libopenmpt/bin/x86/openmpt-mpg123.dll b/libs/libopenmpt/bin/x86/openmpt-mpg123.dll
new file mode 100644
index 000000000..79148a40e
Binary files /dev/null and b/libs/libopenmpt/bin/x86/openmpt-mpg123.dll differ
diff --git a/libs/libopenmpt/bin/x86/openmpt-ogg.dll b/libs/libopenmpt/bin/x86/openmpt-ogg.dll
new file mode 100644
index 000000000..6b5a42e8f
Binary files /dev/null and b/libs/libopenmpt/bin/x86/openmpt-ogg.dll differ
diff --git a/libs/libopenmpt/bin/x86/openmpt-vorbis.dll b/libs/libopenmpt/bin/x86/openmpt-vorbis.dll
new file mode 100644
index 000000000..486b30731
Binary files /dev/null and b/libs/libopenmpt/bin/x86/openmpt-vorbis.dll differ
diff --git a/libs/libopenmpt/bin/x86/openmpt-zlib.dll b/libs/libopenmpt/bin/x86/openmpt-zlib.dll
new file mode 100644
index 000000000..b6e028ab4
Binary files /dev/null and b/libs/libopenmpt/bin/x86/openmpt-zlib.dll differ
diff --git a/libs/libopenmpt/bin/x86_64/libopenmpt.dll b/libs/libopenmpt/bin/x86_64/libopenmpt.dll
new file mode 100644
index 000000000..536492798
Binary files /dev/null and b/libs/libopenmpt/bin/x86_64/libopenmpt.dll differ
diff --git a/libs/libopenmpt/bin/x86_64/mingw/libopenmpt.dll b/libs/libopenmpt/bin/x86_64/mingw/libopenmpt.dll
new file mode 100644
index 000000000..3f6bea95f
Binary files /dev/null and b/libs/libopenmpt/bin/x86_64/mingw/libopenmpt.dll differ
diff --git a/libs/libopenmpt/bin/x86_64/openmpt-mpg123.dll b/libs/libopenmpt/bin/x86_64/openmpt-mpg123.dll
new file mode 100644
index 000000000..f96d446f2
Binary files /dev/null and b/libs/libopenmpt/bin/x86_64/openmpt-mpg123.dll differ
diff --git a/libs/libopenmpt/bin/x86_64/openmpt-ogg.dll b/libs/libopenmpt/bin/x86_64/openmpt-ogg.dll
new file mode 100644
index 000000000..3fd951414
Binary files /dev/null and b/libs/libopenmpt/bin/x86_64/openmpt-ogg.dll differ
diff --git a/libs/libopenmpt/bin/x86_64/openmpt-vorbis.dll b/libs/libopenmpt/bin/x86_64/openmpt-vorbis.dll
new file mode 100644
index 000000000..56047c82f
Binary files /dev/null and b/libs/libopenmpt/bin/x86_64/openmpt-vorbis.dll differ
diff --git a/libs/libopenmpt/bin/x86_64/openmpt-zlib.dll b/libs/libopenmpt/bin/x86_64/openmpt-zlib.dll
new file mode 100644
index 000000000..562d8e6a9
Binary files /dev/null and b/libs/libopenmpt/bin/x86_64/openmpt-zlib.dll differ
diff --git a/libs/libopenmpt/changelog.md b/libs/libopenmpt/changelog.md
new file mode 100644
index 000000000..9847be119
--- /dev/null
+++ b/libs/libopenmpt/changelog.md
@@ -0,0 +1,791 @@
+
+Changelog {#changelog}
+=========
+
+For fully detailed change log, please see the source repository directly. This
+is just a high-level summary.
+
+### libopenmpt 0.4.4 (2019-04-07)
+
+ * [**Bug**] Channel VU meters were swapped.
+
+ * Startrekker: Clamp speed to 31 ticks per row.
+ * MTM: Ignore unused Exy commands on import. Command E5x (Set Finetune) is now
+ applied correctly.
+ * MOD: Sample swapping was always enabled since it has been separated from the
+ ProTracker 1/2 compatibility flag. Now it is always enabled for Amiga-style
+ modules and otherwise the old heuristic is used again.
+
+ * stb_vorbis: Update to v1.16 (2019-03-05).
+
+### libopenmpt 0.4.3 (2019-02-11)
+
+ * [**Sec**] Possible crash due to null-pointer access when doing a portamento
+ from an OPL instrument to an empty instrument note map slot (r11348).
+
+ * [**Bug**] libopenmpt did not compile on Apple platforms in C++17 mode.
+
+ * IT: Various fixes for note-off + instrument number in Old Effects mode.
+ * MO3: Import IT row highlights as written by MO3 2.4.1.2 or newer. Required
+ for modules using modern tempo mode.
+
+ * miniz: Update to v2.0.8 (2018-09-19).
+ * stb_vorbis: Update to v1.15 (2019-02-07).
+
+### libopenmpt 0.4.2 (2019-01-22)
+
+ * [**Sec**] DSM: Assertion failure during file parsing with debug STLs
+ (r11209).
+ * [**Sec**] J2B: Assertion failure during file parsing with debug STLs
+ (r11216).
+
+ * S3M: Allow volume change of OPL instruments after Note Cut.
+
+### libopenmpt 0.4.1 (2019-01-06)
+
+ * [**Bug**] Binaries compiled for winold (Windows XP, Vista, 7, for CPUs
+ without SSE2 support) did not actually work on CPUs without SSE2 support.
+ * [**Bug**] libmodplug: Public symbols of the C++ API had `visibility=hidden`
+ set on non-MSVC systems, which made them not publicly accessible.
+ * [**Bug**] Project files for Windows 10 desktop builds on ARM and ARM64
+ (`build/vs2017win10`) were missing from Windows source package.
+ * [**Bug**] MSVC project files in Windows source package lacked additional
+ files required to build DLLs.
+
+ * MO3: Apply playback changes based on "ModPlug-made" header flag.
+
+ * minimp3: Update to commit e9df0760e94044caded36a55d70ab4152134adc5
+ (2018-12-23).
+
+### libopenmpt 0.4.0 (2018-12-23)
+
+ * [**New**] libopenmpt now includes emulation of the OPL chip and thus plays
+ OPL instruments in S3M, C67 and MPTM files. OPL chip emulation volume can be
+ changed with the new ctl `render.opl.volume_factor`.
+ * [**New**] libopenmpt now supports CDFM / Composer 670 module files.
+ * [**New**] Autotools `configure` and plain `Makefile` now honor the variable
+ `CXXSTDLIB_PCLIBSPRIVATE` which serves the sole purpose of listing the
+ standard library (or libraries) required for static linking. The contents of
+ this variable will be put in `libopenmpt.pc` `Libs.private` and used for
+ nothing else. See \ref libopenmpt_c_staticlinking .
+ * [**New**] foo_openmpt: foo_openmpt now also works on Windows XP.
+ * [**New**] libopenmpt Emscripten builds now ship with MP3 support by
+ default, based on minimp3 by Lion (github.com/lieff).
+ * [**New**] libopenmpt: New ctl `play.at_end` can be used to change what
+ happens when the song end is reached:
+ * "fadeout": Fades the module out for a short while. Subsequent reads
+ after the fadeout will return 0 rendered frames. This is the default and
+ identical to the behaviour in previous libopenmpt versions.
+ * "continue": Returns 0 rendered frames when the song end is reached.
+ Subsequent reads will continue playing from the song start or loop
+ start. This can be used for custom loop logic, such as loop
+ auto-detection and longer fadeouts.
+ * "stop": Returns 0 rendered frames when the song end is reached.
+ Subsequent reads will return 0 rendered frames.
+ * [**New**] Add new metadata fields `"originaltype"` and `"originaltype_long"`
+ which allow more clearly reflecting what is going on with converted formats
+ like MO3 and GDM.
+ * [**New**] `Makefile` `CONFIG=emscripten` now can generate WebAssembly via
+ the additional option `EMSCRIPTEN_TARGET=wasm`.
+ * [**New**] Compiling for DOS is now experimentally supported via DJGPP GCC
+ 7.2 or later.
+
+ * [**Change**] minimp3: Instead of the LGPL-2.1-licensed minimp3 by KeyJ,
+ libopenmpt now uses the CC0-1.0-licensed minimp3 by Lion (github.com/lieff)
+ as a fallback if libmpg123 is unavailable. The `USE_MINIMP3` `Makefile`
+ option is gone and minimp3 will be used automatically in the `Makefile`
+ build system if libmpg123 is not available.
+ * [**Change**] openmpt123: openmpt123 now rejects `--output-type` in `--ui`
+ and `--batch` modes and also rejects `--output` in `--render` mode. These
+ combinations of options really made no sense and were rather confusing.
+ * [**Change**] Android NDK build system now uses libc++ (`c++_shared`) instead
+ of GNU libstdc++ (`gnustl_shared`), as recommended by Android NDK r16b.
+ * [**Change**] xmp-openmpt: `openmpt-mpg123.dll` is no longer optional and
+ must be placed into the same directory as `xmp-openmpt.dll`.
+ * [**Change**] in_openmpt: `openmpt-mpg123.dll` is no longer optional and must
+ be placed either into the directory of the player itself or into the same
+ directory as `in_openmpt.dll`. This is dependent on how the player loads its
+ plugins. For WinAMP 5, `openmpt-mpg123.dll` needs to be in the directory
+ which contains `winamp.exe`. `in_openmpt.dll` needs to be in the `Plugins`
+ directory.
+ * [**Change**] foo_openmpt: foo_openmpt is now packaged as a fb2k-component
+ package for easier installation.
+ * [**Change**] When building libopenmpt with MinGW-w64, it is now recommended
+ to use the posix thread model (as opposed to the win32 threading model),
+ because the former does support std::mutex while the latter does not. When
+ building with win32 threading model with the Autotools build system, it is
+ recommended to provide the `mingw-std-threads` package. Building libopenmpt
+ with MinGW-w64 without any `std::thread`/`std::mutex` support is deprecated
+ and support for such configurations will be removed in libopenmpt 0.5.
+ * [**Change**] `Makefile` `CONFIG=emscripten` now has 4 `EMSCRIPTEN_TARGET=`
+ settings: `wasm` generates WebAssembly, `asmjs128m` generates asm.js with a
+ fixed size 128MB heap, `asmjs` generates asm.js with a fixed default size
+ heap (as of Emscripten 1.38.11, this amounts to 16MB), `js` generates
+ JavaScript with dynamic heap growth and with compatibility for older VMs.
+ * [**Change**] libmodplug: Update public headers to libmodplug 0.8.8.5. This
+ adds support for kind-of automatic MODPLUG_EXPORT decoration on Windows.
+
+ * [**Regression**] Support for Clang 3.4, 3.5 has been removed.
+ * [**Regression**] Building with Android NDK older than NDK r16b is not
+ supported any more.
+ * [**Regression**] Support for Emscripten versions older than 1.38.5 has been
+ removed.
+ * [**Regression**] Support for libmpg123 older than 1.14.0 has been removed.
+ * [**Regression**] Using MediaFoundation to decode MP3 samples is no longer
+ supported. Use libmpg123 or minimp3 instead.
+ * [**Regression**] libmodplug: Support for emulating libmodplug 0.8.7 API/ABI
+ has been removed.
+
+ * [**Bug**] xmp-openmpt: Sample rate and number of output channels were not
+ applied correctly when using per-file settings.
+ * [**Bug**] Internal mixer state was not initialized properly when initially
+ rendering in 44100kHz stereo format.
+ * [**Bug**] openmpt123: Prevent libsdl2 and libsdl from being enabled at the
+ same time because they conflict with each other.
+ * [**Bug**] libmodplug: Setting `SNDMIX_NORESAMPLING` in the C++ API always
+ resulted in linear interpolation instead of nearest neighbour
+
+ * IT: In Compatible Gxx mode, allow sample changes next to a tone portamento
+ effect if a previous sample has already stopped playing.
+ * IT: Fix broken volume envelopes with negative values as found in breakdwn.it
+ by Elysis.
+ * MOD: Slides and delayed notes are executed on every repetition of a row with
+ row delay (fixes "ode to protracker").
+ * XM: If the sustain point of the panning envelope is reached before key-off,
+ it is never released.
+ * XM: Do not default recall volume / panning for delayed instrument-less notes
+ * XM :E60 loop bug was not considered in song length calucation.
+ * S3M: Notes without instrument number use previous note's sample offset.
+ * Tighten M15 and MOD file rejection heuristics.
+ * J2B: Ignore frequency limits from file header. Fixes Medivo.j2b, broken
+ since libopenmpt-0.2.6401-beta17.
+ * STM: More accurate tempo calculation.
+ * STM: Better support for early format revisions (no such files have been
+ found in the wild, though).
+ * STM: Last character of sample name was missing.
+ * SFX: Work around bad conversions of the "Operation Stealth" soundtrack by
+ turning pattern breaks into note stops.
+ * IMF: Filter cutoff was upside down and the cutoff range was too small.
+ * ParamEq plugin center frequency was not limited correctly.
+ * Keep track of active SFx macro during seeking.
+ * The "note cut" duplicate note action did not volume-ramp the previously
+ playing sample.
+ * A song starting with non-existing patterns could not be played.
+ * DSM: Support restart position and 16-bit samples.
+ * DTM: Import global volume.
+ * MOD: Support notes in octave 2, like in FastTracker 2 (fixes DOPE.MOD).
+ * Do not apply Amiga playback heuristics to MOD files that have clearly been
+ written with a PC tracker.
+ * MPTM: More logical release node behaviour.
+ * Subsong search is now less thorough. It could previously find many subsongs
+ that are technically correct (unplayed rows at the beginning of patterns
+ that have been jumped over due to pattern breaks), but so far no real-world
+ module that would require such a thorough subsong detection was found. The
+ old mechanism caused way more false positives than intended with real-world
+ modules, though.
+ * Restrict the unpacked size of compressed DMF, IT, MDL and MO3 samples to
+ avoid huge allocations with malformed small files.
+
+### libopenmpt 0.3 (2017-09-27)
+
+ * [**New**] New error handling functionality in the C API, which in particular
+ allows distinguishing potentially transient out-of-memory errors from parse
+ errors during module loading.
+ * [**New**] New API `openmpt::module::get_selected_subsong()` (C++) and
+ `openmpt_module_get_selected_subsong()` (C).
+ * [**New**] Faster file header probing API `openmpt::probe_file_header()` and
+ `openmpt::probe_file_header_get_recommended_size` (C++), and
+ `openmpt_probe_file_header()`,
+ `openmpt_probe_file_header_without_filesize()`,
+ `openmpt_probe_file_header_from_stream()` and
+ `openmpt_probe_file_header_get_recommended_size()` (C).
+ * [**New**] New API `openmpt::could_open_probability()` (C++) and
+ `openmpt_could_open_probability()` (C). This fixes a spelling error in the
+ old 0.2 API.
+ * [**New**] openmpt123: openmpt123 can now open M3U, M3U8, M3UEXT, M3U8EXT and
+ PLSv2 playlists via the `--playlist` option.
+ * [**New**] openmpt123: openmpt123 now supports very fast file header probing
+ via the `--probe` option.
+ * [**New**] Libopenmpt now supports building for Windows 10 Universal (Windows
+ Store 8.2) APIs with MSVC, and also for the older Windows Runtime APIs with
+ MinGW-w64.
+ * [**New**] New API header `libopenmpt_ext.h` which implements the libopenmpt
+ extension APIs also for the C interface.
+ * [**New**] The Reverb effect (S99 in S3M/IT/MPTM, and X99 in XM) is now
+ implemented in libopenmpt.
+ * [**New**] For Amiga modules, a new resampler based on the Amiga's sound
+ characteristics has been added. It can be activated by passing the
+ `render.resampler.emulate_amiga` ctl with a value of `1`. Non-Amiga modules
+ are not affected by this, and setting the ctl overrides the resampler choice
+ specified by `OPENMPT_MODULE_RENDER_INTERPOLATIONFILTER_LENGTH` or
+ `openmpt::module::RENDER_INTERPOLATIONFILTER_LENGTH`. Support for the MOD
+ command E0x (Set LED Filter) is also available when the Amiga resampler is
+ enabled.
+
+ * [**Change**] libopenmpt versioning changed and follows the more conventional
+ major.minor.patch as well as the recommendations of the
+ [SemVer](http://semver.org/) scheme now. In addition to the SemVer
+ requirements, pre-1.0.0 versions will also honor API and ABI stability in
+ libopenmpt (i.e. libopenmpt ignores SemVer Clause 4).
+ * [**Change**] The output directories of the MSVC build system were changed to
+ `bin/vs2015-shared/x86-64-win7/` (and similar) layout which allows building
+ in the same tree with different compiler versions without overwriting other
+ outputs.
+ * [**Change**] The emscripten build now exports libopenmpt as 'libopenmpt'
+ instead of the default 'Module'.
+ * [**Change**] Android: The build system changed. The various Android.mk files
+ have been merged into a single one which can be controlled using command
+ line options.
+ * [**Change**] The `Makefile` build system now passes `std=c++11` to the
+ compiler by default. Older compilers may still work if you pass
+ `STDCXX=c++0x` to the `make` invocation.
+ * [**Change**] The `Makefile` option `ANCIENT=1` is gone.
+ * [**Change**] The optional dependencies on `libltdl` or `libdl` are gone.
+ They are no longer needed for any functionality.
+
+ * [**Regression**] Compiling client code using the C++ API now requires a
+ compiler running in C++11 mode.
+ * [**Regression**] Support for GCC 4.1, 4.2, 4.3, 4.4, 4.5, 4.6, 4.7 has been
+ removed.
+ * [**Regression**] Support for Clang 3.0, 3.1, 3.2, 3.3 has been removed.
+ * [**Regression**] Support for Emscripten versions older than 1.31.0 has been
+ removed.
+ * [**Regression**] Support for Android NDK versions older than 11 has been
+ removed.
+ * [**Regression**] Visual Studio 2008, 2010, 2012, 2013 support has been
+ removed.
+ * [**Regression**] Dynamic run-time loading of libmpg123 is no longer
+ supported. Libmpg123 must be linked at link-time now.
+ * [**Regression**] xmp-openmpt: xmp-openmpt now requires XMPlay 3.8 or later
+ and compiling xmp-openmpt requires an appropriate XMPlay SDK with
+ `XMPIN_FACE` >= `4`.
+ * [**Regression**] Support for libmpg123 older than 1.13.0 has been removed.
+ * [**Regression**] Un4seen unmo3 support has been removed.
+
+ * [**Bug**] C++ API: `openmpt::exception` did not define copy and move
+ constructors or copy and move assignment operators in libopenmpt 0.2. The
+ compiler-generated ones were not adequate though. libopenmpt 0.3 adds the
+ appropriate special member functions. This adds the respective symbol names
+ to the exported ABI, which, depending on the compiler, might or might not
+ have been there in libopenmpt 0.2. The possibly resulting possible ODR
+ violation only affects cases that did crash in the libopenmpt 0.2 API anyway
+ due to memory double-free, and does not cause any further problems in
+ practice for all known platforms and compilers.
+ * [**Bug**] The C API could crash instead of failing gracefully in
+ out-of-memory situations.
+ * [**Bug**] The test suite could fail on MacOSX or FreeBSD in non-fatal ways
+ when no locale was active.
+ * [**Bug**] `libopenmpt_stream_callbacks_fd.h` and
+ `libopenmpt_stream_callbacks_file.h` were missing in Windows development
+ packages.
+ * [**Bug**] libopenmpt on Windows did not properly guard against current
+ working directory DLL injection attacks.
+ * [**Bug**] localtime() was used to determine the version of Schism Tracker
+ used to save IT and S3M files. This function is not guaranteed to be
+ thread-safe by the standard and is now no longer used.
+ * [**Bug**] Possible crashes with malformed IT, ITP, AMS, MDL, MED, MPTM, PSM
+ and Startrekker files.
+ * [**Bug**] Possible hangs with malformed DBM, MPTM and PSM files.
+ * [**Bug**] Possible hangs with malformed files containing cyclic plugin
+ routings.
+ * [**Bug**] Excessive loading times with malformed ITP / truncated AMS files.
+ * [**Bug**] Plugins did not work correctly when changing the sample rate
+ between two render calls.
+ * [**Bug**] Possible NULL-pointer dereference read during obscure
+ out-of-memory situations while handling exceptions in the C API.
+ * [**Bug**] libmodplug: `libmodplug.pc` was wrong.
+ * [**Bug**] Cross-compiling libopenmpt with autotools for Windows now properly
+ sets `-municode` and `-mconsole` as well as all required Windows system
+ libraries.
+ * [**Bug**] foo_openmpt: Interpolation filter and volume ramping settings were
+ confused in previous versions. This version resets both to the defaults.
+ * [**Bug**] libmodplug: The CSoundFile::Read function in the emulated
+ libmodplug C++ API returned the wrong value, causing qmmp (and possibly
+ other software) to crash.
+
+ * Support for SoundTracker Pro II (STP) and Digital Tracker (DTM) modules.
+ * Increased accuracy of the sample position and sample rate to drift less when
+ playing very long samples.
+ * Various playback improvements for IT and XM files.
+ * Channel frequency could wrap around after some excessive portamento / down
+ in some formats since libopenmpt 0.2-beta17.
+ * Playback improvements for S3M files made with Impulse Tracker and
+ Schism Tracker.
+ * ParamEq plugin emulation didn't do anything at full gain (+15dB).
+ * All standard DMO effects are now also emulated on non-Windows and non-MSVC
+ systems.
+ * Added `libopenmpt_stream_callbacks_buffer.h` which adds
+ `openmpt_stream_callbacks` support for in-memory buffers, possibly even only
+ using a truncated prefix view into a bigger file which is useful for
+ probing.
+ * Avoid enabling some ProTracker-specific quirks for MOD files most likely
+ created with ScreamTracker 3.
+ * Tremolo effect only had half the intended strength in MOD files.
+ * Pattern loops ending on the last row a pattern were not executed correctly
+ in S3M files.
+ * Work-around for reading MIDI macros and plugin settings in some malformed IT
+ files written by old UNMO3 versions.
+ * Improve tracker detection in IT format.
+ * Playback fixes for 8-channel MED files
+ * Do not set note volume to 0 on out-of-range offset in XM files.
+ * Better import of some slide commands in SFX files.
+ * Sample 15 in "Crew Generation" by Necros requires short loops at the
+ beginning of the sample to not be ignored. Since we need to ignore them in
+ some (non-ProTracker) modules, we heuristically disable the old loop
+ sanitization behaviour based on the module channel count.
+ * Both normal and percentage offset in PLM files were handled as percentage
+ offset.
+ * MT2 files with instruments that had both sample and plugin assignments were
+ not read correctly.
+ * Some valid FAR files were rejected erroneously.
+ * Support for VBlank timing flag and comment field in PT36 files.
+ * Improved accuracy of vibrato command in DIGI / DBM files.
+ * STM: Add support for "WUZAMOD!" magic bytes and allow some slightly
+ malformed STM files to load which were previously rejected.
+ * Detect whether "hidden" patterns in the order list of SoundTracker modules
+ should be taken into account or not.
+ * Tighten heuristics for rejecting invalid 669, M15, MOD and ICE files and
+ loosen them in other places to allow some valid MOD files to load.
+ * Improvements to seeking: Channel panning was not always updated from
+ instruments / samples when seeking, and out-of-range global volume was not
+ applied correctly in some formats.
+ * seek.sync_samples=1 did not apply PTM reverse offset effect and the volume
+ slide part of combined volume slide + vibrato commands.
+ * If the order list was longer than 256 items and there was a pattern break
+ effect without a position jump on the last pattern of the sequence, it did
+ not jump to the correct restart order.
+ * `Makefile` has now explicit support for FreeBSD with no special option or
+ configuration required.
+ * openmpt123: Improved section layout in man page.
+ * libmodplug: Added all missing C++ API symbols that are accessible via the
+ public libmodplug header file.
+ * Autotools build system now has options `--disable-openmpt123`,
+ `--disable-tests` and `--disable-examples` which may be desireable when
+ cross-compiling.
+ * Windows binary packages now ship with libmpg123 included.
+
+### libopenmpt 0.2-beta20 (2016-08-07)
+
+ * [**Bug**] PSM loader was broken on big-endian platforms since forever.
+ * [**Bug**] `load.skip_samples` ctl did not work for PSM16 modules.
+
+ * There is a new `subsong` ctl, which can return the currently selected
+ subsong.
+ * More accurate ProTracker arpeggio wrap-around emulation.
+ * More accurate sample tuning in PSM16 files.
+ * Samples in DSM files were sometimes detuned and some pattern commands were
+ not imported correctly.
+ * More accurate import of MDL 7-bit panning command.
+ * Only import pattern commands supported by the UltraTracker version that was
+ used to save ULT files. Add support for command 5-C (end loop).
+ * DMF sample loop lengths were off by one.
+ * Unis 669 pan slide effect was too deep.
+ * Several valid (but slightly corrupted possibly due to disk failures or data
+ transfer errors) SoundTracker files were no longer loading since libopenmpt
+ 0.2-beta18.
+
+### libopenmpt 0.2-beta19 (2016-07-23)
+
+ * [**Change**] libopenmpt now uses C++14 `[[deprecated]]` attribute instead
+ of compiler-specific solutions when appropriate.
+ * [**Change**] libopenmpt C++ header now uses C++11 `noexcept` instead of
+ C++98 `throw()` exception specification when supported. `throw()` is
+ deprecated since C++11. This does not change API or ABI as they are
+ equivalent. Use `LIBOPENMPT_ASSUME_CPLUSPLUS_NOEXCEPT` to override the
+ default.
+ * [**Change**] The preprocessor macro `LIBOPENMPT_ANCIENT_COMPILER_STDINT` is
+ gone. Please use `LIBOPENMPT_ASSUME_CPLUSPLUS_CSTDINT instead`.
+ Additionally, the typedefs moved from illegal namespace ::std into somewhat
+ less dangerous namespace ::openmpt::std. You can test
+ `#ifdef LIBOPENMPT_QUIRK_NO_CSTDINT` client-side to check whether
+ `libopenmpt.hpp` used the non-standard types. (Note: Of all supported
+ compilers, this change only affects the 3 compilers with only limited
+ support: MSVC 2008, GCC 4.1, GCC 4.2.)
+
+ * [**Bug**] xmp-openmpt: Crash when viewing sample texts.
+
+ * The public libopenmpt C++ header has auto-detection logic for the used C++
+ standard now. In case your client code compiler misreports the standard
+ version or you want to override it for other reasons,
+ `#define LIBOPENMPT_ASSUME_CPLUSPLUS` to the value of the standard version
+ you desire to be used. There is also a macro for each individual aspect,
+ like `LIBOPENMPT_ASSUME_CPLUSPLUS_CSTDINT`,
+ `LIBOPENMPT_ASSUME_CPLUSPLUS_DEPRECATED`,
+ `LIBOPENMPT_ASSUME_CPLUSPLUS_NOEXCEPT` which take precedence over the
+ general macro.
+ * Portamento with sample swap behaviour was wrong for ProTracker MODs.
+ * Rewritten loader and various playback fixes for MDL files.
+ * libopenmpt 0.2-beta18 broke import of many pattern commands in DBM, DMF and
+ ULT files.
+ * ADPCM samples in MOD files were broken since libopenmpt 0.2-beta17.
+
+### libopenmpt 0.2-beta18 (2016-07-11)
+
+ * [**Change**] openmpt123: Add PulseAudio output support. Autotools and
+ `Makefile` build systems now depend on `libpulse` and `libpulse-simple` by
+ default. Disable with `--without-pulseaudio` or `NO_PULSEAUDIO=1`
+ respectively. When enabled, PulseAudio will be the default output driver,
+ * [**Change**] xmp-openmpt: Settings are now stored in xmplay.ini like with
+ every other plugin.
+
+ * [**Regression**] openmpt123: Support for FLAC < 1.3.0 has been removed. FLAC
+ before 1.3.0 is broken beyond repair as it provides `assert.h` in the
+ include path.
+
+ * [**Bug**] Generated pkg-config file libopenmpt.pc by both `Makefile` and
+ Autotools build systems was totally broken.
+ * [**Bug**] libopenmpt no longer uses the non-thread-safe global std::rand()
+ function.
+ * [**Bug**] Sample loops in GDM modules did not work when using Emscripten.
+ * [**Bug**] XM and MO3 loaders could crash due to unaligned memory accesses.
+ * [**Bug**] Fixed incorrect handling of custom MPTM tunings on big endian
+ platforms.
+ * [**Bug**] Fixed various problems found with clang 3.8 static analyzer,
+ address sanitizer and undefined behaviour sanitizer.
+ * [**Bug**] File header probing functionality was broken for most formats.
+ * [**Bug**] With non-seekable streams, the entire file was almost always
+ cached even if it was not of any supported module type.
+
+ * Seeking in allsubsongs-mode now works correctly.
+ * openmpt123: Added subsong support.
+ * Various playback fixes for 669, IT, MT2 and MTM files.
+ * Some MOD files with more than 128 patterns (e.g. NIETNU.MOD) were not loaded
+ correctly.
+ * A new example `libopenmpt_example_c_probe` has been added which demonstrates
+ the usage and flexibility of openmpt_could_open_propability() in the C API
+ under various constraints.
+
+### libopenmpt 0.2-beta17 (2016-05-21)
+
+ * [**Change**] The Makefile and Autotools build systems now require to
+ explicitly specify `NO_LTDL=1` or `--without-ltdl` respectively if no
+ support for dynamic loading of third party libraries via libtool libltdl is
+ desired.
+ * [**Change**] In the Makefile build system option `USE_MO3` and the Autotools
+ build system option `--enable-mo3` are gone. Dynamic loading of un4seen
+ unmo3 is now always enabled when dynamic loading is possible and built-in
+ MO3 support is not possible because either a MP3 or a Vorbis decoder is
+ missing.
+ * [**Change**] The MSVC build system changed. The `libopenmptDLL` project is
+ gone. Use the new `ReleaseShared` configuration of the `libopenmpt` project
+ instead. libopenmpt now links against zlib by default. A separate project
+ with smaller footprint linking against miniz is still available as
+ `libopenmpt-small`.
+ * [**Change**] The constants used to query library information from
+ `openmpt_get_string()` and `openmpt::string::get()` (i.e. OPENMPT_STRING_FOO
+ and openmpt::string::FOO) have been deprecated because having syntactic
+ constants for theses keys makes extending the API in a backwards and
+ forwards compatible way harder than it should be. Please just use the string
+ literals directly.
+ * [**Change**] Deprecated API identifiers will now cause deprecation warnings
+ with MSVC, GCC and clang. `#define LIBOPENMPT_NO_DEPRECATE` to disable the
+ warnings.
+ * [**Change**] openmpt123: `--[no-]shuffle` option has been renamed to
+ `--[no-]randomize`. A new `--[no-]shuffle` option has been added which
+ shuffles randomly through the playlist as opposed to randomizing the
+ playlist upfront.
+ * [**Change**] Support for Un4seen unmo3 has generally been deprecated in
+ favour of the new internal mo3 decoder. Un4seen unmo3 support will be
+ removed on 2018-01-01.
+
+ * [**Bug**] Memory consumption during loading has been reduced by about 1/3 in
+ case a seekable input stream is provided (either via C API callback open
+ functions or via C++ API iostream constructors).
+ * [**Bug**] Some samples in AMS modules were detuned when using Emscripten.
+ * [**Bug**] Possible crash with excessive portamento down in some formats.
+ * [**Bug**] Possible crashes with malformed AMF, AMS, DBM, IT, MDL, MED, MPTM,
+ MT2, PSM and MMCMP-, XPK- and PP20-compressed files.
+ * [**Bug**] `openmpt::module::format_pattern_row_channel` with `width == 0`
+ was returning an empty string instead of an string with unconstrained
+ length.
+
+ * Support for ProTracker 3.6 IFF-style modules and SoundFX / MultiMedia Sound
+ (SFX / MMS) modules.
+ * libopenmpt now has support for DMO plugins on Windows when built with MSVC.
+ Additionally, the DMO Compression, Distortion, Echo, Gargle, ParamEQ and
+ WavesReverb DSPs are emulated on on all other platforms.
+ * libopenmpt now supports the DigiBooster Echo DSP.
+ * To avoid any of the aforementioned plugins to be used, the load.skip_plugins
+ ctl can be passed when loading a module.
+ * libopenmpt got native MO3 support with MP3 decoding either via libmpg123 or
+ MediaFoundation (on Windows 7 and up) and Vorbis decoding via libogg,
+ libvorbis, libvorbisfile or stb_vorbis.
+ * libopenmpt MSVC builds with Visual Studio 2010 or later on Windows 7 or
+ later now use an internal MO3 decoder with libogg, libvorbis, libvorbisfile,
+ and libmpg123 or minimp3 or MediaFoundation suppport by default. Visual
+ Studio 2008 builds still use unmo3.dll by default but also support the
+ built-in decoder in which case libmpg123 is required.
+ * libopenmpt with Makefile or Autotools build system can now also use
+ glibc/libdl instead of libtool/libltdl for dynamic loading of third-party
+ libraries. Options `NO_DL=1` and `--without-dl` have been added
+ respectively.
+ * The `Makefile` build system got 4 new options NO_MPG123, NO_OGG, NO_VORBIS,
+ NO_VORBISFILE. The default is to use the new dependencies automatically.
+ * The `Autotools` build system got 4 new options --without-mpg123,
+ --without-ogg, --without-vorbis, --without-vorbisfile. The default is to use
+ the new dependencies automatically.
+ * Makefile and Android builds got support for using minimp3 instead of
+ libmpg123. For Android, use `Android-minimp3-stbvorbis.mk`, for Makefile use
+ `USE_MINIMP3=1`. You have to download
+ [minimp3](http://keyj.emphy.de/minimp3/) yourself and put its contents into
+ `include/minimp3/`.
+ * `"source_url"`, `"source_date"` and `"build_compiler"` keys have been added
+ to `openmpt_string_get()` and `openmpt::string::get()`.
+ * openmpt123: Add new `--[no-]restart]` option which restarts the playlist
+ when finished.
+ * Improved Ultimate SoundTracker version detection heuristics.
+ * Playing a sample at a sample rate close to the mix rate could lead to small
+ clicks when using vibrato.
+ * More fine-grained internal legacy module compatibility settings to correctly
+ play back modules made with older versions of OpenMPT and a few other
+ trackers.
+ * The tail of compressed MDL samples was slightly off.
+ * Some probably hex-edited XM files (e.g. cybernostra weekend.xm) were not
+ loaded correctly.
+ * Countless other playback fixes for MOD, XM, S3M, IT and MT2 files.
+
+### libopenmpt 0.2-beta16 (2015-11-22)
+
+ * [**Change**] The Autotools build system does strict checking of all
+ dependencies now. Instead of best effort auto-magic detection of all
+ potentially optional dependencies, the default set of dependencies is now
+ enforced unless each individual dependency gets explicitely disabled via
+ `--without-foo` or `--disable-foo` `./configure` switches. Run
+ `./configure --help` for the full list of options.
+
+ * [**Bug**] Some MOD files were erroneously detected as 669 files.
+ * [**Bug**] Some malformed AMF files could result in very long loading times.
+ * [**Bug**] Fixed crashes in IMF and MT2 loaders.
+ * [**Bug**] MTM files generated by UNMO3 were not loaded properly.
+
+ * Improved MTM playback.
+ * `make CONFIG=haiku` for Haiku has been added.
+ * Language bindings for FreeBASIC have been added (see
+ `libopenmpt/bindings/`).
+
+### libopenmpt 0.2-beta15 (2015-10-31)
+
+ * [**Change**] openmpt123: SDL2 is now supported and preferred to SDL1 if
+ available with the `Makefile` build system.
+
+ * [**Bug**] Emscripten support for older emscripten versions broke in -beta14.
+ These are now supported again when using `make CONFIG=emscripten-old`.
+ * [**Bug**] Fixed crashes in MED loader.
+
+ * Playback improvements and loader fixes for MOD, MT2 and MED.
+
+### libopenmpt 0.2-beta14 (2015-09-13)
+
+ * [**Change**] The C++ API example now uses the PortAudio C++ bindings
+ instead of the C API.
+ * [**Change**] Default compiler options for Emscripten have been changed to
+ more closely match the Emscripten recommendations.
+
+ * [**Bug**] Client code compilation with C89 compilers was broken in beta13.
+ * [**Bug**] Test suite failed on certain Emscripten/node.js combinations.
+ * [**Bug**] Fixed various crashes or hangs in DMF, OKT, PLM, IT and MPTM
+ loaders.
+
+ * Implemented error handling in the libopenmpt API examples.
+ * Various playback improvements and fixes for OKT, IT and MOD.
+
+### libopenmpt 0.2-beta13 (2015-08-16)
+
+ * [**Change**] The MSVC build system has been redone. Solutions are now
+ located in `build/vsVERSION/`.
+
+ * [**Bug**] get_current_channel_vu_left and get_current_channel_vu_right only
+ return the volume of the front left and right channels now.
+ get_current_channel_vu_rear_left and get_current_channel_vu_rear_right
+ do now actually work and return non-zero values.
+ * [**Bug**] Fix crashes and hangs in MED and MDL loaders and with some
+ truncated compressed IT samples.
+ * [**Bug**] Fix crash when playing extremely high-pitched samples.
+
+ * Completed C and C++ documentation
+ * Added new key for openmpt::module::get_metadata, "message_raw", which
+ returns an empty string if there is no song message rather than a list of
+ instrument names.
+ * in_openmpt: Support for compiling with VS2008.
+ * xmp-openmpt: Support for compiling with VS2008.
+ * in_openmpt: Add a more readable file information window.
+
+### libopenmpt 0.2-beta12 (2015-04-19)
+
+ * Playback fix when row delay effect is used together with offset command.
+ * A couple of fixes for the seek.sync_samples=1 case.
+ * IT compatibility fix for IT note delay.
+ * ProTracker MOD playback compatibility improvement.
+
+### libopenmpt 0.2-beta11 (2015-04-18)
+
+ * [**Change**] openmpt_stream_seek_func() now gets called with
+ OPENMPT_STREAM_SEEK_SET, OPENMPT_STREAM_SEEK_CUR and
+ OPENMPT_STREAM_SEEK_END whence parameter instead of SEEK_SET, SEEK_CUR and
+ SEEK_END. These are defined to 0, 1 and 2 respectively which corresponds to
+ the definition in all common C libraries. If your C library uses different
+ constants, this theoretically breaks binary compatibility. The old
+ libopenmpt code, however, never actually called the seek function, thus,
+ there will be no problem in practice.
+ * [**Change**] openmpt123: When both SDL1.2 and PortAudio are available,
+ SDL is now the preferred backend because SDL is more widespread and better
+ tested on all kinds of different platforms, and in general, SDL is just
+ more reliable.
+
+ * [**Bug**] libopenmpt now also compiles with GCC 4.3.
+
+ * libopenmpt now supports PLM (Disorder Tracker 2) files.
+ * Various playback improvements and fixes for IT, S3M, XM, MOD, PTM and 669
+ files.
+
+### libopenmpt 0.2-beta10 (2015-02-17)
+
+ * [**Change**] Makefile configuration filenames changed from
+ `build/make/Makefile.config.*` to `build/make/config-*.mk`.
+ * [**Change**] libopenmpt for Android now supports unmo3 from un4seen. See
+ `build/android_ndk/README.AndroidNDK.txt` for details.
+
+ * [**Bug**] Fix out-of-bounds read in mixer code for ProTracker-compatible
+ MOD files which was introduced back in r4223 / beta6.
+
+ * Vibrato effect was too weak in beta8 and beta9 in IT linear slide mode.
+ * Very small fine portamento was wrong in beta8 and beta9 in IT linear slide
+ mode.
+ * Tiny IT playback compatibility improvements.
+ * STM playback improvements.
+
+### libopenmpt 0.2-beta9 (2014-12-21)
+
+ * [**Bug**] libopenmpt_ext.hpp was missing from the Windows binary zip files.
+
+### libopenmpt 0.2-beta8 (2014-12-21)
+
+ * [**Change**] foo_openmpt: Settings are now accessible via foobar2000
+ advanced settings.
+ * [**Change**] Autotools based build now supports libunmo3. Specify
+ --enable-unmo3.
+ * [**Change**] Support for dynamic loading of libunmo3 on MacOS X.
+ * [**Change**] libopenmpt now uses libltld (from libtool) for dynamic loading
+ of libunmo3 on all non-Windows platforms.
+ * [**Change**] Support for older compilers:
+ * GCC 4.1.x to 4.3.x (use `make ANCIENT=1`)
+ * Microsoft Visual Studio 2008 (with latest Service Pack)
+ (see `build/vs2008`)
+ * [**Change**] libopenmpt_ext.hpp is now distributed by default. The API is
+ still considered experimental and not guaranteed to stay API or ABI
+ compatible.
+ * [**Change**] xmp-openmpt / in_openmpt: No more libopenmpt_settings.dll.
+ The settings dialog now uses a statically linked copy of MFC.
+
+ * [**Bug**] The -autotools tarballs were not working at all.
+
+ * Vastly improved MT2 loader.
+ * Improved S3M playback compatibility.
+ * Added openmpt::ext::interactive, an extension which adds a whole bunch of
+ new functionality to change playback in some way or another.
+ * Added possibility to sync sample playback when using
+ openmpt::module::set_position_* by setting the ctl value
+ seek.sync_samples=1
+ * Support for "hidden" subsongs has been added.
+ They are accessible through the same interface as ordinary subsongs, i.e.
+ use openmpt::module::select_subsong to switch between any kind of subsongs.
+ * All subsongs can now be played consecutively by passing -1 as the subsong
+ index in openmpt::module::select_subsong.
+ * Added documentation for a couple of more functions.
+
+### libopenmpt 0.2-beta7 (2014-09-07)
+
+ * [**Change**] libopenmpt now has an GNU Autotools based build system (in
+ addition to all previously supported ways of building libopenmpt).
+ Autotools support is packaged separately as tarballs ending in
+ `-autotools.tar.gz`.
+
+ * [**Bug**] The distributed windows .zip file did not include pugixml.
+
+ * [**Regression**] openmpt123: Support for writing WavPack (.wv) files has
+ been removed.
+
+ Reasoning:
+ 1. WavPack support was incomplete and did not include support for writing
+ WavPack metadata at all.
+ 2. openmpt123 already supports libSndFile which can be used to write
+ uncompressed lossless WAV files which can then be encoded to whatever
+ format the user desires with other tools.
+
+### libopenmpt 0.2-beta6 (2014-09-06)
+
+ * [**Change**] openmpt123: SDL is now also used by default if availble, in
+ addition to PortAudio.
+ * [**Change**] Support for emscripten is no longer experimental.
+ * [**Change**] libopenmpt itself can now also be compiled with VS2008.
+
+ * [**Bug**] Fix all known crashes on platforms that do not support unaligned
+ memory access.
+ * [**Bug**] openmpt123: Effect column was always missing in pattern display.
+
+### libopenmpt 0.2-beta5 (2014-06-15)
+
+ * [**Change**] Add unmo3 support for non-Windows builds.
+ * [**Change**] Namespace all internal functions in order to allow statically
+ linking against libopenmpt without risking duplicate symbols.
+ * [**Change**] Iconv is now completely optional and only used on Linux
+ systems by default.
+ * [**Change**] Added libopenmpt_example_c_stdout.c, an example without
+ requiring PortAudio.
+ * [**Change**] Add experimental support for building libopenmpt with
+ emscripten.
+
+ * [**Bug**] Fix ping-pong loop behaviour which broke in 0.2-beta3.
+ * [**Bug**] Fix crashes when accessing invalid patterns through libopenmpt
+ API.
+ * [**Bug**] Makefile: Support building with missing optional dependencies
+ without them being stated explicitely.
+ * [**Bug**] openmpt123: Crash when quitting while playback is stopped.
+ * [**Bug**] openmpt123: Crash when writing output to a file in interactive UI
+ mode.
+ * [**Bug**] openmpt123: Wrong FLAC output filename in --render mode.
+
+ * Various smaller playback accuracy improvements.
+
+### libopenmpt 0.2-beta4 (2014-02-25)
+
+ * [**Bug**] Makefile: Dependency tracking for the test suite did not work.
+
+### libopenmpt 0.2-beta3 (2014-02-21)
+
+ * [**Change**] The test suite is now built by default with Makefile based
+ builds. Use `TEST=0` to skip building the tests. `make check` runs the test
+ suite.
+
+ * [**Bug**] Crash in MOD and XM loaders on architectures not supporting
+ unaligned memory access.
+ * [**Bug**] MMCMP, PP20 and XPK unpackers should now work on non-x86 hardware
+ and implement proper bounds checking.
+ * [**Bug**] openmpt_module_get_num_samples() returned the wrong value.
+ * [**Bug**] in_openmpt: DSP plugins did not work properly.
+ * [**Bug**] in_openmpt/xmp-openmpt: Setting name for stereo separation was
+ misspelled. This version will revert your stereo separation settings to
+ default.
+ * [**Bug**] Crash when loading some corrupted modules with stereo samples.
+
+ * Support building on Android NDK.
+ * Avoid clicks in sample loops when using interpolation.
+ * IT filters are now done in integer instead of floating point. This improves
+ performance, especially on architectures with no or a slow FPU.
+ * MOD pattern break handling fixes.
+ * Various XM playback improvements.
+ * Improved and switchable dithering when using 16bit integer API.
+
+### libopenmpt 0.2-beta2 (2014-01-12)
+
+ * [**Bug**] MT2 loader crash.
+ * [**Bug**] Saving settings in in_openmpt and xmp-openmpt did not work.
+ * [**Bug**] Load libopenmpt_settings.dll also from below Plugins directory in
+ Winamp.
+
+ * DBM playback improvements.
+
+### libopenmpt 0.2-beta1 (2013-12-31)
+
+ * First release.
+
diff --git a/libs/libopenmpt/debian/libopenmpt-0.4.0-trusty-backport.diff b/libs/libopenmpt/debian/libopenmpt-0.4.0-trusty-backport.diff
new file mode 100644
index 000000000..1c9b56ba5
--- /dev/null
+++ b/libs/libopenmpt/debian/libopenmpt-0.4.0-trusty-backport.diff
@@ -0,0 +1,550 @@
+diff -uraN ../../orig/libopenmpt-0.4.0/debian/changelog ./debian/changelog
+--- ../../orig/libopenmpt-0.4.0/debian/changelog 2018-12-24 16:43:58.000000000 -0500
++++ ./debian/changelog 2019-01-04 17:56:35.024725537 -0500
+@@ -1,3 +1,38 @@
++libopenmpt (0.4.0-ubuntu14.04.1~ppa14) trusty; urgency=medium
++
++ * Remove debian symbols files due to gcc 4.8 - 5 C++ abi incompatibility
++
++ -- Sonic Team Junior Fri, 04 Jan 2019 17:56:01 -0500
++
++libopenmpt (0.4.0-ubuntu14.04.1~ppa13) trusty; urgency=medium
++
++ * autoreconf libtool
++
++ -- Sonic Team Junior Fri, 04 Jan 2019 17:10:45 -0500
++
++libopenmpt (0.4.0-ubuntu14.04.1~ppa12) trusty; urgency=medium
++
++ * debian/rules autoreconf
++
++ -- Sonic Team Junior Fri, 04 Jan 2019 17:03:19 -0500
++
++libopenmpt (0.4.0-ubuntu14.04.1~ppa11) trusty; urgency=medium
++
++ * debian/rules autoreconf
++
++ -- Sonic Team Junior Fri, 04 Jan 2019 16:59:08 -0500
++
++libopenmpt (0.4.0-ubuntu14.04.1~ppa10) trusty; urgency=medium
++
++ * Backport to trusty
++ * Added automake build depend
++ * Adjusted debhelper depend to >= 9.0~
++ * Adjusted dpkg-dev depend to >= 1.17.0
++ * Adjusted debian/compat to 10
++ * autoreconf --force --install
++
++ -- Sonic Team Junior Fri, 04 Jan 2019 16:54:04 -0500
++
+ libopenmpt (0.4.0-1) unstable; urgency=medium
+
+ * New upstream release.
+diff -uraN ../../orig/libopenmpt-0.4.0/debian/compat ./debian/compat
+--- ../../orig/libopenmpt-0.4.0/debian/compat 2018-12-24 16:43:58.000000000 -0500
++++ ./debian/compat 2019-01-04 16:39:17.613976357 -0500
+@@ -1 +1 @@
+-11
++10
+diff -uraN ../../orig/libopenmpt-0.4.0/debian/control ./debian/control
+--- ../../orig/libopenmpt-0.4.0/debian/control 2018-12-24 16:43:58.000000000 -0500
++++ ./debian/control 2019-01-04 17:10:42.008523333 -0500
+@@ -4,10 +4,12 @@
+ Maintainer: Debian Multimedia Maintainers
+ Uploaders: James Cowgill
+ Build-Depends:
+- debhelper (>= 11.1~),
++ automake,
++ libtool,
++ debhelper (>= 9.0~),
+ dh-exec,
+ doxygen,
+- dpkg-dev (>= 1.18.0),
++ dpkg-dev (>= 1.17.0),
+ libflac-dev,
+ libmpg123-dev,
+ libogg-dev,
+diff -uraN ../../orig/libopenmpt-0.4.0/debian/files ./debian/files
+--- ../../orig/libopenmpt-0.4.0/debian/files 1969-12-31 19:00:00.000000000 -0500
++++ ./debian/files 2019-01-04 17:56:47.813250880 -0500
+@@ -0,0 +1 @@
++libopenmpt_0.4.0-ubuntu14.04.1~ppa14_source.buildinfo libs optional
+diff -uraN ../../orig/libopenmpt-0.4.0/debian/libopenmpt0.symbols ./debian/libopenmpt0.symbols
+--- ../../orig/libopenmpt-0.4.0/debian/libopenmpt0.symbols 2018-12-24 16:43:58.000000000 -0500
++++ ./debian/libopenmpt0.symbols 1969-12-31 19:00:00.000000000 -0500
+@@ -1,256 +0,0 @@
+-libopenmpt.so.0 libopenmpt0 #MINVER#
+-* Build-Depends-Package: libopenmpt-dev
+-# Ignore std:: template instantiations
+- (regex|optional)"^_ZN?K?S" 0.2.7025~beta20.1
+- _ZN7openmpt10module_ext13get_interfaceERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE@Base 0.2.7025~beta20.1
+- (arch-bits=32)_ZN7openmpt10module_extC1EPKcjRSoRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESA_St4lessISA_ESaISt4pairIKSA_SA_EEE@Base 0.2.7025~beta20.1
+- (arch-bits=64)_ZN7openmpt10module_extC1EPKcmRSoRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESA_St4lessISA_ESaISt4pairIKSA_SA_EEE@Base 0.2.7025~beta20.1
+- (arch-bits=32)_ZN7openmpt10module_extC1EPKvjRSoRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESA_St4lessISA_ESaISt4pairIKSA_SA_EEE@Base 0.2.7025~beta20.1
+- (arch-bits=64)_ZN7openmpt10module_extC1EPKvmRSoRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESA_St4lessISA_ESaISt4pairIKSA_SA_EEE@Base 0.2.7025~beta20.1
+- _ZN7openmpt10module_extC1ERKS0_@Base 0.2.7025~beta20.1
+- _ZN7openmpt10module_extC1ERKSt6vectorIcSaIcEERSoRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcES2_EESC_St4lessISC_ESaISt4pairIKSC_SC_EEE@Base 0.2.7025~beta20.1
+- _ZN7openmpt10module_extC1ERSiRSoRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_St4lessIS9_ESaISt4pairIKS9_S9_EEE@Base 0.2.7025~beta20.1
+- (arch-bits=32)_ZN7openmpt10module_extC2EPKcjRSoRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESA_St4lessISA_ESaISt4pairIKSA_SA_EEE@Base 0.2.7025~beta20.1
+- (arch-bits=64)_ZN7openmpt10module_extC2EPKcmRSoRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESA_St4lessISA_ESaISt4pairIKSA_SA_EEE@Base 0.2.7025~beta20.1
+- (arch-bits=32)_ZN7openmpt10module_extC2EPKvjRSoRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESA_St4lessISA_ESaISt4pairIKSA_SA_EEE@Base 0.2.7025~beta20.1
+- (arch-bits=64)_ZN7openmpt10module_extC2EPKvmRSoRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESA_St4lessISA_ESaISt4pairIKSA_SA_EEE@Base 0.2.7025~beta20.1
+- _ZN7openmpt10module_extC2ERKS0_@Base 0.2.7025~beta20.1
+- _ZN7openmpt10module_extC2ERKSt6vectorIcSaIcEERSoRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcES2_EESC_St4lessISC_ESaISt4pairIKSC_SC_EEE@Base 0.2.7025~beta20.1
+- _ZN7openmpt10module_extC2ERSiRSoRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_St4lessIS9_ESaISt4pairIKS9_S9_EEE@Base 0.2.7025~beta20.1
+- _ZN7openmpt10module_extD0Ev@Base 0.2.7025~beta20.1
+- _ZN7openmpt10module_extD1Ev@Base 0.2.7025~beta20.1
+- _ZN7openmpt10module_extD2Ev@Base 0.2.7025~beta20.1
+- _ZN7openmpt10module_extaSERKS0_@Base 0.2.7025~beta20.1
+- _ZN7openmpt16get_core_versionEv@Base 0.2.7025~beta20.1
+- (arch-bits=32)_ZN7openmpt17probe_file_headerEyPKhj@Base 0.3.0
+- (arch-bits=64)_ZN7openmpt17probe_file_headerEmPKhm@Base 0.3.0
+- (arch-bits=32)_ZN7openmpt17probe_file_headerEyPKhjy@Base 0.3.0
+- (arch-bits=64)_ZN7openmpt17probe_file_headerEmPKhmm@Base 0.3.0
+- (arch-bits=32)_ZN7openmpt17probe_file_headerEyRSi@Base 0.3.0
+- (arch-bits=64)_ZN7openmpt17probe_file_headerEmRSi@Base 0.3.0
+- _ZN7openmpt19get_library_versionEv@Base 0.2.7025~beta20.1
+- _ZN7openmpt22could_open_probabilityERSidRSo@Base 0.3.0
+- _ZN7openmpt22could_open_propabilityERSidRSo@Base 0.2.7025~beta20.1
+- _ZN7openmpt22is_extension_supportedERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE@Base 0.2.7025~beta20.1
+- _ZN7openmpt24get_supported_extensionsB5cxx11Ev@Base 0.2.7025~beta20.1
+- _ZN7openmpt38probe_file_header_get_recommended_sizeEv@Base 0.3.0
+- _ZN7openmpt6module14select_subsongEi@Base 0.2.7025~beta20.1
+- _ZN7openmpt6module16set_render_paramEii@Base 0.2.7025~beta20.1
+- _ZN7openmpt6module16set_repeat_countEi@Base 0.2.7025~beta20.1
+- _ZN7openmpt6module20set_position_secondsEd@Base 0.2.7025~beta20.1
+- (arch-bits=32)_ZN7openmpt6module21read_interleaved_quadEijPf@Base 0.2.7025~beta20.1
+- (arch-bits=64)_ZN7openmpt6module21read_interleaved_quadEimPf@Base 0.2.7025~beta20.1
+- (arch-bits=32)_ZN7openmpt6module21read_interleaved_quadEijPs@Base 0.2.7025~beta20.1
+- (arch-bits=64)_ZN7openmpt6module21read_interleaved_quadEimPs@Base 0.2.7025~beta20.1
+- _ZN7openmpt6module22set_position_order_rowEii@Base 0.2.7025~beta20.1
+- (arch-bits=32)_ZN7openmpt6module23read_interleaved_stereoEijPf@Base 0.2.7025~beta20.1
+- (arch-bits=64)_ZN7openmpt6module23read_interleaved_stereoEimPf@Base 0.2.7025~beta20.1
+- (arch-bits=32)_ZN7openmpt6module23read_interleaved_stereoEijPs@Base 0.2.7025~beta20.1
+- (arch-bits=64)_ZN7openmpt6module23read_interleaved_stereoEimPs@Base 0.2.7025~beta20.1
+- (arch-bits=32)_ZN7openmpt6module4readEijPf@Base 0.2.7025~beta20.1
+- (arch-bits=64)_ZN7openmpt6module4readEimPf@Base 0.2.7025~beta20.1
+- (arch-bits=32)_ZN7openmpt6module4readEijPfS1_@Base 0.2.7025~beta20.1
+- (arch-bits=64)_ZN7openmpt6module4readEimPfS1_@Base 0.2.7025~beta20.1
+- (arch-bits=32)_ZN7openmpt6module4readEijPfS1_S1_S1_@Base 0.2.7025~beta20.1
+- (arch-bits=64)_ZN7openmpt6module4readEimPfS1_S1_S1_@Base 0.2.7025~beta20.1
+- (arch-bits=32)_ZN7openmpt6module4readEijPs@Base 0.2.7025~beta20.1
+- (arch-bits=64)_ZN7openmpt6module4readEimPs@Base 0.2.7025~beta20.1
+- (arch-bits=32)_ZN7openmpt6module4readEijPsS1_@Base 0.2.7025~beta20.1
+- (arch-bits=64)_ZN7openmpt6module4readEimPsS1_@Base 0.2.7025~beta20.1
+- (arch-bits=32)_ZN7openmpt6module4readEijPsS1_S1_S1_@Base 0.2.7025~beta20.1
+- (arch-bits=64)_ZN7openmpt6module4readEimPsS1_S1_S1_@Base 0.2.7025~beta20.1
+- _ZN7openmpt6module7ctl_setERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_@Base 0.2.7025~beta20.1
+- _ZN7openmpt6module8set_implEPNS_11module_implE@Base 0.2.7025~beta20.1
+- _ZN7openmpt6moduleC1EPKcS2_RSoRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESA_St4lessISA_ESaISt4pairIKSA_SA_EEE@Base 0.2.7025~beta20.1
+- (arch-bits=32)_ZN7openmpt6moduleC1EPKcjRSoRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESA_St4lessISA_ESaISt4pairIKSA_SA_EEE@Base 0.2.7025~beta20.1
+- (arch-bits=64)_ZN7openmpt6moduleC1EPKcmRSoRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESA_St4lessISA_ESaISt4pairIKSA_SA_EEE@Base 0.2.7025~beta20.1
+- _ZN7openmpt6moduleC1EPKhS2_RSoRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESA_St4lessISA_ESaISt4pairIKSA_SA_EEE@Base 0.2.7025~beta20.1
+- (arch-bits=32)_ZN7openmpt6moduleC1EPKhjRSoRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESA_St4lessISA_ESaISt4pairIKSA_SA_EEE@Base 0.2.7025~beta20.1
+- (arch-bits=64)_ZN7openmpt6moduleC1EPKhmRSoRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESA_St4lessISA_ESaISt4pairIKSA_SA_EEE@Base 0.2.7025~beta20.1
+- (arch-bits=32)_ZN7openmpt6moduleC1EPKvjRSoRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESA_St4lessISA_ESaISt4pairIKSA_SA_EEE@Base 0.2.7025~beta20.1
+- (arch-bits=64)_ZN7openmpt6moduleC1EPKvmRSoRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESA_St4lessISA_ESaISt4pairIKSA_SA_EEE@Base 0.2.7025~beta20.1
+- _ZN7openmpt6moduleC1ERKS0_@Base 0.2.7025~beta20.1
+- _ZN7openmpt6moduleC1ERKSt6vectorIcSaIcEERSoRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcES2_EESC_St4lessISC_ESaISt4pairIKSC_SC_EEE@Base 0.2.7025~beta20.1
+- _ZN7openmpt6moduleC1ERKSt6vectorIhSaIhEERSoRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESD_St4lessISD_ESaISt4pairIKSD_SD_EEE@Base 0.2.7025~beta20.1
+- _ZN7openmpt6moduleC1ERSiRSoRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_St4lessIS9_ESaISt4pairIKS9_S9_EEE@Base 0.2.7025~beta20.1
+- _ZN7openmpt6moduleC1Ev@Base 0.2.7025~beta20.1
+- _ZN7openmpt6moduleC2EPKcS2_RSoRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESA_St4lessISA_ESaISt4pairIKSA_SA_EEE@Base 0.2.7025~beta20.1
+- (arch-bits=32)_ZN7openmpt6moduleC2EPKcjRSoRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESA_St4lessISA_ESaISt4pairIKSA_SA_EEE@Base 0.2.7025~beta20.1
+- (arch-bits=64)_ZN7openmpt6moduleC2EPKcmRSoRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESA_St4lessISA_ESaISt4pairIKSA_SA_EEE@Base 0.2.7025~beta20.1
+- _ZN7openmpt6moduleC2EPKhS2_RSoRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESA_St4lessISA_ESaISt4pairIKSA_SA_EEE@Base 0.2.7025~beta20.1
+- (arch-bits=32)_ZN7openmpt6moduleC2EPKhjRSoRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESA_St4lessISA_ESaISt4pairIKSA_SA_EEE@Base 0.2.7025~beta20.1
+- (arch-bits=64)_ZN7openmpt6moduleC2EPKhmRSoRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESA_St4lessISA_ESaISt4pairIKSA_SA_EEE@Base 0.2.7025~beta20.1
+- (arch-bits=32)_ZN7openmpt6moduleC2EPKvjRSoRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESA_St4lessISA_ESaISt4pairIKSA_SA_EEE@Base 0.2.7025~beta20.1
+- (arch-bits=64)_ZN7openmpt6moduleC2EPKvmRSoRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESA_St4lessISA_ESaISt4pairIKSA_SA_EEE@Base 0.2.7025~beta20.1
+- _ZN7openmpt6moduleC2ERKS0_@Base 0.2.7025~beta20.1
+- _ZN7openmpt6moduleC2ERKSt6vectorIcSaIcEERSoRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcES2_EESC_St4lessISC_ESaISt4pairIKSC_SC_EEE@Base 0.2.7025~beta20.1
+- _ZN7openmpt6moduleC2ERKSt6vectorIhSaIhEERSoRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESD_St4lessISD_ESaISt4pairIKSD_SD_EEE@Base 0.2.7025~beta20.1
+- _ZN7openmpt6moduleC2ERSiRSoRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_St4lessIS9_ESaISt4pairIKS9_S9_EEE@Base 0.2.7025~beta20.1
+- _ZN7openmpt6moduleC2Ev@Base 0.2.7025~beta20.1
+- _ZN7openmpt6moduleD0Ev@Base 0.2.7025~beta20.1
+- _ZN7openmpt6moduleD1Ev@Base 0.2.7025~beta20.1
+- _ZN7openmpt6moduleD2Ev@Base 0.2.7025~beta20.1
+- _ZN7openmpt6moduleaSERKS0_@Base 0.2.7025~beta20.1
+- _ZN7openmpt6string3getERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE@Base 0.2.7025~beta20.1
+- _ZN7openmpt9exceptionC1EOS0_@Base 0.3.0
+- _ZN7openmpt9exceptionC1ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE@Base 0.2.7025~beta20.1
+- _ZN7openmpt9exceptionC1ERKS0_@Base 0.3.0
+- _ZN7openmpt9exceptionC2EOS0_@Base 0.3.0
+- _ZN7openmpt9exceptionC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE@Base 0.2.7025~beta20.1
+- _ZN7openmpt9exceptionC2ERKS0_@Base 0.3.0
+- _ZN7openmpt9exceptionD0Ev@Base 0.2.7025~beta20.1
+- _ZN7openmpt9exceptionD1Ev@Base 0.2.7025~beta20.1
+- _ZN7openmpt9exceptionD2Ev@Base 0.2.7025~beta20.1
+- _ZN7openmpt9exceptionaSEOS0_@Base 0.3.0
+- _ZN7openmpt9exceptionaSERKS0_@Base 0.3.0
+- _ZNK7openmpt6module12get_metadataERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE@Base 0.2.7025~beta20.1
+- _ZNK7openmpt6module14get_num_ordersEv@Base 0.2.7025~beta20.1
+- _ZNK7openmpt6module15get_current_rowEv@Base 0.2.7025~beta20.1
+- _ZNK7openmpt6module15get_num_samplesEv@Base 0.2.7025~beta20.1
+- _ZNK7openmpt6module15get_order_namesB5cxx11Ev@Base 0.2.7025~beta20.1
+- _ZNK7openmpt6module16get_num_channelsEv@Base 0.2.7025~beta20.1
+- _ZNK7openmpt6module16get_num_patternsEv@Base 0.2.7025~beta20.1
+- _ZNK7openmpt6module16get_num_subsongsEv@Base 0.2.7025~beta20.1
+- _ZNK7openmpt6module16get_render_paramEi@Base 0.2.7025~beta20.1
+- _ZNK7openmpt6module16get_repeat_countEv@Base 0.2.7025~beta20.1
+- _ZNK7openmpt6module16get_sample_namesB5cxx11Ev@Base 0.2.7025~beta20.1
+- _ZNK7openmpt6module17get_channel_namesB5cxx11Ev@Base 0.2.7025~beta20.1
+- _ZNK7openmpt6module17get_current_orderEv@Base 0.2.7025~beta20.1
+- _ZNK7openmpt6module17get_current_speedEv@Base 0.2.7025~beta20.1
+- _ZNK7openmpt6module17get_current_tempoEv@Base 0.2.7025~beta20.1
+- _ZNK7openmpt6module17get_metadata_keysB5cxx11Ev@Base 0.2.7025~beta20.1
+- _ZNK7openmpt6module17get_order_patternEi@Base 0.2.7025~beta20.1
+- _ZNK7openmpt6module17get_pattern_namesB5cxx11Ev@Base 0.2.7025~beta20.1
+- _ZNK7openmpt6module17get_subsong_namesB5cxx11Ev@Base 0.2.7025~beta20.1
+- _ZNK7openmpt6module19get_current_patternEv@Base 0.2.7025~beta20.1
+- _ZNK7openmpt6module19get_num_instrumentsEv@Base 0.2.7025~beta20.1
+- _ZNK7openmpt6module20get_duration_secondsEv@Base 0.2.7025~beta20.1
+- _ZNK7openmpt6module20get_instrument_namesB5cxx11Ev@Base 0.2.7025~beta20.1
+- _ZNK7openmpt6module20get_pattern_num_rowsEi@Base 0.2.7025~beta20.1
+- _ZNK7openmpt6module20get_position_secondsEv@Base 0.2.7025~beta20.1
+- _ZNK7openmpt6module20get_selected_subsongEv@Base 0.3.0
+- (arch-bits=32)_ZNK7openmpt6module26format_pattern_row_channelB5cxx11Eiiijb@Base 0.2.7025~beta20.1
+- (arch-bits=64)_ZNK7openmpt6module26format_pattern_row_channelB5cxx11Eiiimb@Base 0.2.7025~beta20.1
+- _ZNK7openmpt6module27get_current_channel_vu_leftEi@Base 0.2.7025~beta20.1
+- _ZNK7openmpt6module27get_current_channel_vu_monoEi@Base 0.2.7025~beta20.1
+- _ZNK7openmpt6module28get_current_channel_vu_rightEi@Base 0.2.7025~beta20.1
+- _ZNK7openmpt6module28get_current_playing_channelsEv@Base 0.2.7025~beta20.1
+- (arch-bits=32)_ZNK7openmpt6module29highlight_pattern_row_channelB5cxx11Eiiijb@Base 0.2.7025~beta20.1
+- (arch-bits=64)_ZNK7openmpt6module29highlight_pattern_row_channelB5cxx11Eiiimb@Base 0.2.7025~beta20.1
+- _ZNK7openmpt6module31get_pattern_row_channel_commandEiiii@Base 0.2.7025~beta20.1
+- _ZNK7openmpt6module32get_current_channel_vu_rear_leftEi@Base 0.2.7025~beta20.1
+- _ZNK7openmpt6module33get_current_channel_vu_rear_rightEi@Base 0.2.7025~beta20.1
+- _ZNK7openmpt6module34format_pattern_row_channel_commandB5cxx11Eiiii@Base 0.2.7025~beta20.1
+- _ZNK7openmpt6module37highlight_pattern_row_channel_commandB5cxx11Eiiii@Base 0.2.7025~beta20.1
+- _ZNK7openmpt6module7ctl_getERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE@Base 0.2.7025~beta20.1
+- _ZNK7openmpt6module8get_ctlsB5cxx11Ev@Base 0.2.7025~beta20.1
+- _ZNK7openmpt9exception4whatEv@Base 0.2.7025~beta20.1
+- _ZTIN7openmpt10module_extE@Base 0.2.7025~beta20.1
+- _ZTIN7openmpt6moduleE@Base 0.2.7025~beta20.1
+- _ZTIN7openmpt9exceptionE@Base 0.2.7025~beta20.1
+- (optional=weak)_ZTISt11_Mutex_baseILN9__gnu_cxx12_Lock_policyE2EE@Base 0.2.7025~beta20.1
+- (optional=weak)_ZTISt16_Sp_counted_baseILN9__gnu_cxx12_Lock_policyE2EE@Base 0.2.7025~beta20.1
+- _ZTSN7openmpt10module_extE@Base 0.2.7025~beta20.1
+- _ZTSN7openmpt6moduleE@Base 0.2.7025~beta20.1
+- _ZTSN7openmpt9exceptionE@Base 0.2.7025~beta20.1
+- (optional=weak)_ZTSSt11_Mutex_baseILN9__gnu_cxx12_Lock_policyE2EE@Base 0.2.7025~beta20.1
+- (optional=weak)_ZTSSt16_Sp_counted_baseILN9__gnu_cxx12_Lock_policyE2EE@Base 0.2.7025~beta20.1
+- (optional=weak)_ZTSSt19_Sp_make_shared_tag@Base 0.2.7025~beta20.1
+- _ZTVN7openmpt10module_extE@Base 0.2.7025~beta20.1
+- _ZTVN7openmpt6moduleE@Base 0.2.7025~beta20.1
+- _ZTVN7openmpt9exceptionE@Base 0.2.7025~beta20.1
+- (optional=weak)_ZZNSt19_Sp_make_shared_tag5_S_tiEvE5__tag@Base 0.4.0
+- openmpt_could_open_probability2@Base 0.3.0
+- openmpt_could_open_probability@Base 0.3.0
+- openmpt_could_open_propability@Base 0.2.7025~beta20.1
+- openmpt_error_func_default@Base 0.3.0
+- openmpt_error_func_errno@Base 0.3.0
+- openmpt_error_func_errno_userdata@Base 0.3.0
+- openmpt_error_func_ignore@Base 0.3.0
+- openmpt_error_func_log@Base 0.3.0
+- openmpt_error_func_store@Base 0.3.0
+- openmpt_error_is_transient@Base 0.3.0
+- openmpt_error_string@Base 0.3.0
+- openmpt_free_string@Base 0.2.7025~beta20.1
+- openmpt_get_core_version@Base 0.2.7025~beta20.1
+- openmpt_get_library_version@Base 0.2.7025~beta20.1
+- openmpt_get_string@Base 0.2.7025~beta20.1
+- openmpt_get_supported_extensions@Base 0.2.7025~beta20.1
+- openmpt_is_extension_supported@Base 0.2.7025~beta20.1
+- openmpt_log_func_default@Base 0.2.7025~beta20.1
+- openmpt_log_func_silent@Base 0.2.7025~beta20.1
+- openmpt_module_create2@Base 0.3.0
+- openmpt_module_create@Base 0.2.7025~beta20.1
+- openmpt_module_create_from_memory2@Base 0.3.0
+- openmpt_module_create_from_memory@Base 0.2.7025~beta20.1
+- openmpt_module_ctl_get@Base 0.2.7025~beta20.1
+- openmpt_module_ctl_set@Base 0.2.7025~beta20.1
+- openmpt_module_destroy@Base 0.2.7025~beta20.1
+- openmpt_module_error_clear@Base 0.3.0
+- openmpt_module_error_get_last@Base 0.3.0
+- openmpt_module_error_get_last_message@Base 0.3.0
+- openmpt_module_error_set_last@Base 0.3.0
+- openmpt_module_ext_create@Base 0.3.0
+- openmpt_module_ext_create_from_memory@Base 0.3.0
+- openmpt_module_ext_destroy@Base 0.3.0
+- openmpt_module_ext_get_interface@Base 0.3.0
+- openmpt_module_ext_get_module@Base 0.3.0
+- openmpt_module_format_pattern_row_channel@Base 0.2.7025~beta20.1
+- openmpt_module_format_pattern_row_channel_command@Base 0.2.7025~beta20.1
+- openmpt_module_get_channel_name@Base 0.2.7025~beta20.1
+- openmpt_module_get_ctls@Base 0.2.7025~beta20.1
+- openmpt_module_get_current_channel_vu_left@Base 0.2.7025~beta20.1
+- openmpt_module_get_current_channel_vu_mono@Base 0.2.7025~beta20.1
+- openmpt_module_get_current_channel_vu_rear_left@Base 0.2.7025~beta20.1
+- openmpt_module_get_current_channel_vu_rear_right@Base 0.2.7025~beta20.1
+- openmpt_module_get_current_channel_vu_right@Base 0.2.7025~beta20.1
+- openmpt_module_get_current_order@Base 0.2.7025~beta20.1
+- openmpt_module_get_current_pattern@Base 0.2.7025~beta20.1
+- openmpt_module_get_current_playing_channels@Base 0.2.7025~beta20.1
+- openmpt_module_get_current_row@Base 0.2.7025~beta20.1
+- openmpt_module_get_current_speed@Base 0.2.7025~beta20.1
+- openmpt_module_get_current_tempo@Base 0.2.7025~beta20.1
+- openmpt_module_get_duration_seconds@Base 0.2.7025~beta20.1
+- openmpt_module_get_instrument_name@Base 0.2.7025~beta20.1
+- openmpt_module_get_metadata@Base 0.2.7025~beta20.1
+- openmpt_module_get_metadata_keys@Base 0.2.7025~beta20.1
+- openmpt_module_get_num_channels@Base 0.2.7025~beta20.1
+- openmpt_module_get_num_instruments@Base 0.2.7025~beta20.1
+- openmpt_module_get_num_orders@Base 0.2.7025~beta20.1
+- openmpt_module_get_num_patterns@Base 0.2.7025~beta20.1
+- openmpt_module_get_num_samples@Base 0.2.7025~beta20.1
+- openmpt_module_get_num_subsongs@Base 0.2.7025~beta20.1
+- openmpt_module_get_order_name@Base 0.2.7025~beta20.1
+- openmpt_module_get_order_pattern@Base 0.2.7025~beta20.1
+- openmpt_module_get_pattern_name@Base 0.2.7025~beta20.1
+- openmpt_module_get_pattern_num_rows@Base 0.2.7025~beta20.1
+- openmpt_module_get_pattern_row_channel_command@Base 0.2.7025~beta20.1
+- openmpt_module_get_position_seconds@Base 0.2.7025~beta20.1
+- openmpt_module_get_render_param@Base 0.2.7025~beta20.1
+- openmpt_module_get_repeat_count@Base 0.2.7025~beta20.1
+- openmpt_module_get_sample_name@Base 0.2.7025~beta20.1
+- openmpt_module_get_selected_subsong@Base 0.3.0
+- openmpt_module_get_subsong_name@Base 0.2.7025~beta20.1
+- openmpt_module_highlight_pattern_row_channel@Base 0.2.7025~beta20.1
+- openmpt_module_highlight_pattern_row_channel_command@Base 0.2.7025~beta20.1
+- openmpt_module_read_float_mono@Base 0.2.7025~beta20.1
+- openmpt_module_read_float_quad@Base 0.2.7025~beta20.1
+- openmpt_module_read_float_stereo@Base 0.2.7025~beta20.1
+- openmpt_module_read_interleaved_float_quad@Base 0.2.7025~beta20.1
+- openmpt_module_read_interleaved_float_stereo@Base 0.2.7025~beta20.1
+- openmpt_module_read_interleaved_quad@Base 0.2.7025~beta20.1
+- openmpt_module_read_interleaved_stereo@Base 0.2.7025~beta20.1
+- openmpt_module_read_mono@Base 0.2.7025~beta20.1
+- openmpt_module_read_quad@Base 0.2.7025~beta20.1
+- openmpt_module_read_stereo@Base 0.2.7025~beta20.1
+- openmpt_module_select_subsong@Base 0.2.7025~beta20.1
+- openmpt_module_set_error_func@Base 0.3.0
+- openmpt_module_set_log_func@Base 0.3.0
+- openmpt_module_set_position_order_row@Base 0.2.7025~beta20.1
+- openmpt_module_set_position_seconds@Base 0.2.7025~beta20.1
+- openmpt_module_set_render_param@Base 0.2.7025~beta20.1
+- openmpt_module_set_repeat_count@Base 0.2.7025~beta20.1
+- openmpt_probe_file_header@Base 0.3.0
+- openmpt_probe_file_header_from_stream@Base 0.3.0
+- openmpt_probe_file_header_get_recommended_size@Base 0.3.0
+- openmpt_probe_file_header_without_filesize@Base 0.3.0
+diff -uraN ../../orig/libopenmpt-0.4.0/debian/libopenmpt-modplug1.symbols ./debian/libopenmpt-modplug1.symbols
+--- ../../orig/libopenmpt-0.4.0/debian/libopenmpt-modplug1.symbols 2018-12-24 16:43:58.000000000 -0500
++++ ./debian/libopenmpt-modplug1.symbols 1969-12-31 19:00:00.000000000 -0500
+@@ -1,200 +0,0 @@
+-libopenmpt_modplug.so.1 libopenmpt-modplug1 #MINVER#
+-* Build-Depends-Package: libopenmpt-modplug-dev
+- LIBOPENMPT_MODPLUG1@LIBOPENMPT_MODPLUG1 0.2.7386~beta20.3
+- ModPlug_ExportIT@LIBOPENMPT_MODPLUG1 0.2.7386~beta20.3
+- ModPlug_ExportMOD@LIBOPENMPT_MODPLUG1 0.2.7386~beta20.3
+- ModPlug_ExportS3M@LIBOPENMPT_MODPLUG1 0.2.7386~beta20.3
+- ModPlug_ExportXM@LIBOPENMPT_MODPLUG1 0.2.7386~beta20.3
+- ModPlug_GetCurrentOrder@LIBOPENMPT_MODPLUG1 0.2.7386~beta20.3
+- ModPlug_GetCurrentPattern@LIBOPENMPT_MODPLUG1 0.2.7386~beta20.3
+- ModPlug_GetCurrentRow@LIBOPENMPT_MODPLUG1 0.2.7386~beta20.3
+- ModPlug_GetCurrentSpeed@LIBOPENMPT_MODPLUG1 0.2.7386~beta20.3
+- ModPlug_GetCurrentTempo@LIBOPENMPT_MODPLUG1 0.2.7386~beta20.3
+- ModPlug_GetLength@LIBOPENMPT_MODPLUG1 0.2.7386~beta20.3
+- ModPlug_GetMasterVolume@LIBOPENMPT_MODPLUG1 0.2.7386~beta20.3
+- ModPlug_GetMessage@LIBOPENMPT_MODPLUG1 0.2.7386~beta20.3
+- ModPlug_GetModuleType@LIBOPENMPT_MODPLUG1 0.2.7386~beta20.3
+- ModPlug_GetName@LIBOPENMPT_MODPLUG1 0.2.7386~beta20.3
+- ModPlug_GetPattern@LIBOPENMPT_MODPLUG1 0.2.7386~beta20.3
+- ModPlug_GetPlayingChannels@LIBOPENMPT_MODPLUG1 0.2.7386~beta20.3
+- ModPlug_GetSettings@LIBOPENMPT_MODPLUG1 0.2.7386~beta20.3
+- ModPlug_InitMixerCallback@LIBOPENMPT_MODPLUG1 0.2.7386~beta20.3
+- ModPlug_InstrumentName@LIBOPENMPT_MODPLUG1 0.2.7386~beta20.3
+- ModPlug_Load@LIBOPENMPT_MODPLUG1 0.2.7386~beta20.3
+- ModPlug_NumChannels@LIBOPENMPT_MODPLUG1 0.2.7386~beta20.3
+- ModPlug_NumInstruments@LIBOPENMPT_MODPLUG1 0.2.7386~beta20.3
+- ModPlug_NumPatterns@LIBOPENMPT_MODPLUG1 0.2.7386~beta20.3
+- ModPlug_NumSamples@LIBOPENMPT_MODPLUG1 0.2.7386~beta20.3
+- ModPlug_Read@LIBOPENMPT_MODPLUG1 0.2.7386~beta20.3
+- ModPlug_SampleName@LIBOPENMPT_MODPLUG1 0.2.7386~beta20.3
+- ModPlug_Seek@LIBOPENMPT_MODPLUG1 0.2.7386~beta20.3
+- ModPlug_SeekOrder@LIBOPENMPT_MODPLUG1 0.2.7386~beta20.3
+- ModPlug_SetMasterVolume@LIBOPENMPT_MODPLUG1 0.2.7386~beta20.3
+- ModPlug_SetSettings@LIBOPENMPT_MODPLUG1 0.2.7386~beta20.3
+- ModPlug_Unload@LIBOPENMPT_MODPLUG1 0.2.7386~beta20.3
+- ModPlug_UnloadMixerCallback@LIBOPENMPT_MODPLUG1 0.2.7386~beta20.3
+- _ZN10CSoundFile10FreeSampleEPv@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5
+- _ZN10CSoundFile10InitPlayerEb@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5
+- _ZN10CSoundFile10NoteChangeEjibb@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5
+- _ZN10CSoundFile10PackSampleERii@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5
+- _ZN10CSoundFile10ProcessAGCEi@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5
+- _ZN10CSoundFile10ProcessRowEv@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5
+- _ZN10CSoundFile10ReadSampleEP14_MODINSTRUMENTjPKcj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5
+- _ZN10CSoundFile10RetrigNoteEjj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5
+- _ZN10CSoundFile10gdwSysInfoE@LIBOPENMPT_MODPLUG1 0.2.7386~beta20.3
+- _ZN10CSoundFile10gnCPUUsageE@LIBOPENMPT_MODPLUG1 0.2.7386~beta20.3
+- _ZN10CSoundFile10gnChannelsE@LIBOPENMPT_MODPLUG1 0.2.7386~beta20.3
+- _ZN10CSoundFile11DoFreqSlideEP11_MODCHANNELi@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5
+- _ZN10CSoundFile11FineVibratoEP11_MODCHANNELj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5
+- _ZN10CSoundFile11FreePatternEPv@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5
+- _ZN10CSoundFile11InitSysInfoEv@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5
+- _ZN10CSoundFile11LoopPatternEii@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5
+- _ZN10CSoundFile11PatternLoopEP11_MODCHANNELj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5
+- _ZN10CSoundFile11VolumeSlideEP11_MODCHANNELj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5
+- _ZN10CSoundFile12FineVolumeUpEP11_MODCHANNELj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5
+- _ZN10CSoundFile12ITInstrToMPTEPKvP17_INSTRUMENTHEADERj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5
+- _ZN10CSoundFile12IsSampleUsedEj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5
+- _ZN10CSoundFile12PanningSlideEP11_MODCHANNELj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5
+- _ZN10CSoundFile12PortamentoUpEP11_MODCHANNELj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5
+- _ZN10CSoundFile12ResetMidiCfgEv@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5
+- _ZN10CSoundFile12SetMixConfigEjj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5
+- _ZN10CSoundFile12gnReverbTypeE@LIBOPENMPT_MODPLUG1 0.2.7386~beta20.3
+- _ZN10CSoundFile12gpSndMixHookE@LIBOPENMPT_MODPLUG1 0.2.7386~beta20.3
+- _ZN10CSoundFile13CanPackSampleEPcjjPh@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5
+- _ZN10CSoundFile13CheckCPUUsageEj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5
+- _ZN10CSoundFile13DestroySampleEj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5
+- _ZN10CSoundFile13ResetChannelsEv@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5
+- _ZN10CSoundFile13SetCurrentPosEj@LIBOPENMPT_MODPLUG1 0.2.7386~beta20.3
+- _ZN10CSoundFile13SetWaveConfigEjjjb@LIBOPENMPT_MODPLUG1 0.2.7386~beta20.3
+- _ZN10CSoundFile13gdwMixingFreqE@LIBOPENMPT_MODPLUG1 0.2.7386~beta20.3
+- _ZN10CSoundFile13gdwSoundSetupE@LIBOPENMPT_MODPLUG1 0.2.7386~beta20.3
+- _ZN10CSoundFile13m_nXBassDepthE@LIBOPENMPT_MODPLUG1 0.2.7386~beta20.3
+- _ZN10CSoundFile13m_nXBassRangeE@LIBOPENMPT_MODPLUG1 0.2.7386~beta20.3
+- _ZN10CSoundFile14AllocateSampleEj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5
+- _ZN10CSoundFile14FineVolumeDownEP11_MODCHANNELj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5
+- _ZN10CSoundFile14GlobalFadeSongEj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5
+- _ZN10CSoundFile14GlobalVolSlideEj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5
+- _ZN10CSoundFile14LoadMixPluginsEPKvj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5
+- _ZN10CSoundFile14PortamentoDownEP11_MODCHANNELj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5
+- _ZN10CSoundFile14ProcessEffectsEv@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5
+- _ZN10CSoundFile14SaveMixPluginsEP8_IO_FILEb@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5
+- _ZN10CSoundFile14SetPatternNameEjPKc@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5
+- _ZN10CSoundFile14TonePortamentoEP11_MODCHANNELj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5
+- _ZN10CSoundFile14m_nReverbDelayE@LIBOPENMPT_MODPLUG1 0.2.7386~beta20.3
+- _ZN10CSoundFile14m_nReverbDepthE@LIBOPENMPT_MODPLUG1 0.2.7386~beta20.3
+- _ZN10CSoundFile15AllocatePatternEjj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5
+- _ZN10CSoundFile15ChannelVolSlideEP11_MODCHANNELj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5
+- _ZN10CSoundFile15CreateStereoMixEi@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5
+- _ZN10CSoundFile15GetSongCommentsEPcjj@LIBOPENMPT_MODPLUG1 0.2.7386~beta20.3
+- _ZN10CSoundFile15SetCurrentOrderEj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5
+- _ZN10CSoundFile15SetMasterVolumeEjb@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5
+- _ZN10CSoundFile15SetWaveConfigExEbbbbbbb@LIBOPENMPT_MODPLUG1 0.2.7386~beta20.3
+- _ZN10CSoundFile15gnBitsPerSampleE@LIBOPENMPT_MODPLUG1 0.2.7386~beta20.3
+- _ZN10CSoundFile15m_nStreamVolumeE@LIBOPENMPT_MODPLUG1 0.2.7386~beta20.3
+- _ZN10CSoundFile16AdjustSampleLoopEP14_MODINSTRUMENT@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5
+- _ZN10CSoundFile16FinePortamentoUpEP11_MODCHANNELj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5
+- _ZN10CSoundFile16InstrumentChangeEP11_MODCHANNELjbbb@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5
+- _ZN10CSoundFile16IsInstrumentUsedEj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5
+- _ZN10CSoundFile16ProcessMidiMacroEjPKcj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5
+- _ZN10CSoundFile16m_nProLogicDelayE@LIBOPENMPT_MODPLUG1 0.2.7386~beta20.3
+- _ZN10CSoundFile16m_nProLogicDepthE@LIBOPENMPT_MODPLUG1 0.2.7386~beta20.3
+- _ZN10CSoundFile17DestroyInstrumentEj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5
+- _ZN10CSoundFile17MapMidiInstrumentEjjj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5
+- _ZN10CSoundFile17SetResamplingModeEj@LIBOPENMPT_MODPLUG1 0.2.7386~beta20.3
+- _ZN10CSoundFile17m_nMaxMixChannelsE@LIBOPENMPT_MODPLUG1 0.2.7386~beta20.3
+- _ZN10CSoundFile18FinePortamentoDownEP11_MODCHANNELj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5
+- _ZN10CSoundFile18GetRawSongCommentsEPcjj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5
+- _ZN10CSoundFile18ReadSampleFromSongEjPS_j@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5
+- _ZN10CSoundFile18SetXBassParametersEjj@LIBOPENMPT_MODPLUG1 0.2.7386~beta20.3
+- _ZN10CSoundFile19DetectUnusedSamplesEPb@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5
+- _ZN10CSoundFile19ExtendedMODCommandsEjj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5
+- _ZN10CSoundFile19ExtendedS3MCommandsEjj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5
+- _ZN10CSoundFile19SetReverbParametersEjj@LIBOPENMPT_MODPLUG1 0.2.7386~beta20.3
+- _ZN10CSoundFile19gnVolumeRampSamplesE@LIBOPENMPT_MODPLUG1 0.2.7386~beta20.3
+- _ZN10CSoundFile19m_nStereoSeparationE@LIBOPENMPT_MODPLUG1 0.2.7386~beta20.3
+- _ZN10CSoundFile20FrequencyToTransposeEP14_MODINSTRUMENT@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5
+- _ZN10CSoundFile20FrequencyToTransposeEj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5
+- _ZN10CSoundFile20Normalize24BitBufferEPhjjj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5
+- _ZN10CSoundFile20TransposeToFrequencyEii@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5
+- _ZN10CSoundFile21ExtendedChannelEffectEP11_MODCHANNELj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5
+- _ZN10CSoundFile21ExtraFinePortamentoUpEP11_MODCHANNELj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5
+- _ZN10CSoundFile21RemoveSelectedSamplesEPb@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5
+- _ZN10CSoundFile21SetSurroundParametersEjj@LIBOPENMPT_MODPLUG1 0.2.7386~beta20.3
+- _ZN10CSoundFile21gpMixPluginCreateProcE@LIBOPENMPT_MODPLUG1 0.2.7386~beta20.3
+- _ZN10CSoundFile22ReadInstrumentFromSongEjPS_j@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5
+- _ZN10CSoundFile23ExtraFinePortamentoDownEP11_MODCHANNELj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5
+- _ZN10CSoundFile23RemoveInstrumentSamplesEj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5
+- _ZN10CSoundFile4ReadEPvj@LIBOPENMPT_MODPLUG1 0.2.7386~beta20.3
+- _ZN10CSoundFile5gnAGCE@LIBOPENMPT_MODPLUG1 0.2.7386~beta20.3
+- _ZN10CSoundFile6CreateEPKhj@LIBOPENMPT_MODPLUG1 0.2.7386~beta20.3
+- _ZN10CSoundFile6KeyOffEj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5
+- _ZN10CSoundFile6ReadITEPKhj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5
+- _ZN10CSoundFile6ReadXMEPKhj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5
+- _ZN10CSoundFile6SetAGCEb@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5
+- _ZN10CSoundFile7DestroyEv@LIBOPENMPT_MODPLUG1 0.2.7386~beta20.3
+- _ZN10CSoundFile7NoteCutEjj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5
+- _ZN10CSoundFile7Read669EPKhj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5
+- _ZN10CSoundFile7ReadABCEPKhj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5
+- _ZN10CSoundFile7ReadAMFEPKhj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5
+- _ZN10CSoundFile7ReadAMSEPKhj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5
+- _ZN10CSoundFile7ReadDBMEPKhj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5
+- _ZN10CSoundFile7ReadDMFEPKhj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5
+- _ZN10CSoundFile7ReadDSMEPKhj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5
+- _ZN10CSoundFile7ReadFAREPKhj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5
+- _ZN10CSoundFile7ReadJ2BEPKhj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5
+- _ZN10CSoundFile7ReadMDLEPKhj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5
+- _ZN10CSoundFile7ReadMIDEPKhj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5
+- _ZN10CSoundFile7ReadMT2EPKhj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5
+- _ZN10CSoundFile7ReadMTMEPKhj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5
+- _ZN10CSoundFile7ReadMedEPKhj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5
+- _ZN10CSoundFile7ReadModEPKhj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5
+- _ZN10CSoundFile7ReadOKTEPKhj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5
+- _ZN10CSoundFile7ReadPATEPKhj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5
+- _ZN10CSoundFile7ReadPSMEPKhj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5
+- _ZN10CSoundFile7ReadPTMEPKhj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5
+- _ZN10CSoundFile7ReadS3MEPKhj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5
+- _ZN10CSoundFile7ReadSTMEPKhj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5
+- _ZN10CSoundFile7ReadUMXEPKhj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5
+- _ZN10CSoundFile7ReadUltEPKhj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5
+- _ZN10CSoundFile7ReadWavEPKhj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5
+- _ZN10CSoundFile7TestABCEPKhj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5
+- _ZN10CSoundFile7TestMIDEPKhj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5
+- _ZN10CSoundFile7TestPATEPKhj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5
+- _ZN10CSoundFile7TremoloEP11_MODCHANNELj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5
+- _ZN10CSoundFile7VibratoEP11_MODCHANNELj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5
+- _ZN10CSoundFile8CheckNNAEjjib@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5
+- _ZN10CSoundFile8FadeSongEj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5
+- _ZN10CSoundFile8ReadAMS2EPKhj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5
+- _ZN10CSoundFile8ReadNoteEv@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5
+- _ZN10CSoundFile8ResetAGCEv@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5
+- _ZN10CSoundFile8SetSpeedEj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5
+- _ZN10CSoundFile8SetTempoEj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5
+- _ZN10CSoundFile9GetLengthEbb@LIBOPENMPT_MODPLUG1 0.2.7386~beta20.3
+- _ZN10CSoundFile9PanbrelloEP11_MODCHANNELj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5
+- _ZN10CSoundFile9gnVUMeterE@LIBOPENMPT_MODPLUG1 0.2.7386~beta20.3
+- _ZN10CSoundFileC1Ev@LIBOPENMPT_MODPLUG1 0.2.7386~beta20.3
+- _ZN10CSoundFileC2Ev@LIBOPENMPT_MODPLUG1 0.2.7386~beta20.3
+- _ZN10CSoundFileD1Ev@LIBOPENMPT_MODPLUG1 0.2.7386~beta20.3
+- _ZN10CSoundFileD2Ev@LIBOPENMPT_MODPLUG1 0.2.7386~beta20.3
+- _ZNK10CSoundFile10S3MConvertEP11_MODCOMMANDb@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5
+- _ZNK10CSoundFile13GetCurrentPosEv@LIBOPENMPT_MODPLUG1 0.2.7386~beta20.3
+- _ZNK10CSoundFile13GetNNAChannelEj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5
+- _ZNK10CSoundFile13GetSampleNameEjPc@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5
+- _ZNK10CSoundFile14GetMaxPositionEv@LIBOPENMPT_MODPLUG1 0.2.7386~beta20.3
+- _ZNK10CSoundFile14GetNumChannelsEv@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5
+- _ZNK10CSoundFile14GetNumPatternsEv@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5
+- _ZNK10CSoundFile14GetPatternNameEjPcj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5
+- _ZNK10CSoundFile14GetSaveFormatsEv@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5
+- _ZNK10CSoundFile14IsSongFinishedEjj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5
+- _ZNK10CSoundFile14ModSaveCommandEPK11_MODCOMMANDb@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5
+- _ZNK10CSoundFile14S3MSaveConvertEPjS0_b@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5
+- _ZNK10CSoundFile17ConvertModCommandEP11_MODCOMMAND@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5
+- _ZNK10CSoundFile17CutOffToFrequencyEji@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5
+- _ZNK10CSoundFile17GetBestSaveFormatEv@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5
+- _ZNK10CSoundFile17GetFreqFromPeriodEjji@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5
+- _ZNK10CSoundFile17GetInstrumentNameEjPc@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5
+- _ZNK10CSoundFile17GetNoteFromPeriodEj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5
+- _ZNK10CSoundFile17GetNumInstrumentsEv@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5
+- _ZNK10CSoundFile17GetPeriodFromNoteEjij@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5
+- _ZNK10CSoundFile18SetupChannelFilterEP11_MODCHANNELbi@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5
+- _ZNK10CSoundFile19IsValidBackwardJumpEjjjj@LIBOPENMPT_MODPLUG1 0.2.7561~beta20.5
+diff -uraN ../../orig/libopenmpt-0.4.0/debian/rules ./debian/rules
+--- ../../orig/libopenmpt-0.4.0/debian/rules 2018-12-24 16:43:58.000000000 -0500
++++ ./debian/rules 2019-01-04 17:03:16.206691071 -0500
+@@ -11,9 +11,10 @@
+ dh $@
+
+ override_dh_autoreconf:
+- dh_autoreconf --as-needed
++ autoreconf --force --install
+
+ override_dh_auto_configure:
++ debian/rules override_dh_autoreconf
+ dh_auto_configure -- --disable-static --enable-libopenmpt_modplug
+
+ override_dh_auto_build:
diff --git a/libs/libopenmpt/debian/libopenmpt-0.4.0-xenial-backport.diff b/libs/libopenmpt/debian/libopenmpt-0.4.0-xenial-backport.diff
new file mode 100644
index 000000000..9cb88b748
--- /dev/null
+++ b/libs/libopenmpt/debian/libopenmpt-0.4.0-xenial-backport.diff
@@ -0,0 +1,40 @@
+diff -uraN ../../orig/libopenmpt-0.4.0/debian/changelog ./debian/changelog
+--- ../../orig/libopenmpt-0.4.0/debian/changelog 2018-12-24 16:43:58.000000000 -0500
++++ ./debian/changelog 2019-01-04 16:37:08.788775423 -0500
+@@ -1,3 +1,12 @@
++libopenmpt (0.4.0-ubuntu16.04.1~ppa10) xenial; urgency=medium
++
++ * Backport to Xenial
++ * automake build depend added
++ * debhelper depend adjusted to >= 9.0~
++ * deb compat level adjusted to 10
++
++ -- Sonic Team Junior Fri, 04 Jan 2019 16:35:08 -0500
++
+ libopenmpt (0.4.0-1) unstable; urgency=medium
+
+ * New upstream release.
+diff -uraN ../../orig/libopenmpt-0.4.0/debian/compat ./debian/compat
+--- ../../orig/libopenmpt-0.4.0/debian/compat 2018-12-24 16:43:58.000000000 -0500
++++ ./debian/compat 2019-01-04 16:34:31.830370437 -0500
+@@ -1 +1 @@
+-11
++10
+diff -uraN ../../orig/libopenmpt-0.4.0/debian/control ./debian/control
+--- ../../orig/libopenmpt-0.4.0/debian/control 2018-12-24 16:43:58.000000000 -0500
++++ ./debian/control 2019-01-04 16:34:59.339499384 -0500
+@@ -4,7 +4,8 @@
+ Maintainer: Debian Multimedia Maintainers
+ Uploaders: James Cowgill
+ Build-Depends:
+- debhelper (>= 11.1~),
++ automake,
++ debhelper (>= 9.0~),
+ dh-exec,
+ doxygen,
+ dpkg-dev (>= 1.18.0),
+diff -uraN ../../orig/libopenmpt-0.4.0/debian/files ./debian/files
+--- ../../orig/libopenmpt-0.4.0/debian/files 1969-12-31 19:00:00.000000000 -0500
++++ ./debian/files 2019-01-04 16:37:20.001229883 -0500
+@@ -0,0 +1 @@
++libopenmpt_0.4.0-ubuntu16.04.1~ppa10_source.buildinfo libs optional
diff --git a/libs/libopenmpt/inc/libopenmpt/libopenmpt.h b/libs/libopenmpt/inc/libopenmpt/libopenmpt.h
new file mode 100644
index 000000000..d41324885
--- /dev/null
+++ b/libs/libopenmpt/inc/libopenmpt/libopenmpt.h
@@ -0,0 +1,1449 @@
+/*
+ * libopenmpt.h
+ * ------------
+ * Purpose: libopenmpt public c interface
+ * Notes : (currently none)
+ * Authors: OpenMPT Devs
+ * The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
+ */
+
+#ifndef LIBOPENMPT_H
+#define LIBOPENMPT_H
+
+#include "libopenmpt_config.h"
+#include
+#include
+
+/*!
+ * \page libopenmpt_c_overview C API
+ *
+ * \section libopenmpt_c_error Error Handling
+ *
+ * - Functions with no return value in the corresponding C++ API return 0 on
+ * failure and 1 on success.
+ * - Functions that return a string in the corresponding C++ API return a
+ * dynamically allocated const char *. In case of failure or memory allocation
+ * failure, a NULL pointer is returned.
+ * - Functions that return integer values signal error condition by returning
+ * an invalid value (-1 in most cases, 0 in some cases).
+ * - All functions that work on an \ref openmpt_module object will call an
+ * \ref openmpt_error_func and depending on the value returned by this function
+ * log the error code and/xor/or store it inside the openmpt_module object.
+ * Stored error codes can be accessed with the openmpt_module_error_get_last()
+ * and openmpt_module_error_get_last_message(). Stored errors will not get
+ * cleared automatically and should be reset with openmpt_module_error_clear().
+ * - Some functions not directly related to an \ref openmpt_module object take
+ * an explicit \ref openmpt_error_func error function callback and a pointer to
+ * an int and behave analog to the functions working on an \ref openmpt_module
+ * object.
+ *
+ * \section libopenmpt_c_strings Strings
+ *
+ * - All strings returned from libopenmpt are encoded in UTF-8.
+ * - All strings passed to libopenmpt should also be encoded in UTF-8.
+ * Behaviour in case of invalid UTF-8 is unspecified.
+ * - libopenmpt does not enforce or expect any particular Unicode
+ * normalization form.
+ * - All strings returned from libopenmpt are dynamically allocated and must
+ * be freed with openmpt_free_string(). Do NOT use the C standard library
+ * free() for libopenmpt strings as that would make your code invalid on
+ * windows when dynamically linking against libopenmpt which itself statically
+ * links to the C runtime.
+ * - All strings passed to libopenmpt are copied. No ownership is assumed or
+ * transferred.
+ *
+ * \section libopenmpt_c_fileio File I/O
+ *
+ * libopenmpt can use 3 different strategies for file I/O.
+ *
+ * - openmpt_module_create_from_memory2() will load the module from the provided
+ * memory buffer, which will require loading all data upfront by the library
+ * caller.
+ * - openmpt_module_create2() with a seekable stream will load the module via
+ * callbacks to the stream interface. libopenmpt will not implement an
+ * additional buffering layer in this case which means the callbacks are assumed
+ * to be performant even with small i/o sizes.
+ * - openmpt_module_create2() with an unseekable stream will load the module via
+ * callbacks to the stream interface. libopempt will make an internal copy as
+ * it goes along, and sometimes have to pre-cache the whole file in case it
+ * needs to know the complete file size. This strategy is intended to be used
+ * if the file is located on a high latency network.
+ *
+ * | create function | speed | memory consumption |
+ * | ----------------------------------------------: | :----: | :----------------: |
+ * | openmpt_module_create_from_memory2() |
fast
|
medium
|
+ * | openmpt_module_create2() with seekable stream |
slow
|
low
|
+ * | openmpt_module_create2() with unseekable stream |
medium
|
high
|
+ *
+ * In all cases, the data or stream passed to the create function is no longer
+ * needed after the openmpt_module has been created and can be freed by the
+ * caller.
+ *
+ * \section libopenmpt_c_outputformat Output Format
+ *
+ * libopenmpt supports a wide range of PCM output formats:
+ * [8000..192000]/[mono|stereo|quad]/[f32|i16].
+ *
+ * Unless you have some very specific requirements demanding a particular aspect
+ * of the output format, you should always prefer 48000/stereo/f32 as the
+ * libopenmpt PCM format.
+ *
+ * - Please prefer 48000Hz unless the user explicitly demands something else.
+ * Practically all audio equipment and file formats use 48000Hz nowadays.
+ * - Practically all module formats are made for stereo output. Mono will not
+ * give you any measurable speed improvements and can trivially be obtained from
+ * the stereo output anyway. Quad is not expected by almost all modules and even
+ * if they do use surround effects, they expect the effects to be mixed to
+ * stereo.
+ * - Floating point output provides headroom instead of hard clipping if the
+ * module is louder than 0dBFs, will give you a better signal-to-noise ratio
+ * than int16 output, and avoid the need to apply an additional dithering to the
+ * output by libopenmpt. Unless your platform has no floating point unit at all,
+ * floating point will thus also be slightly faster.
+ *
+ * \section libopenmpt_c_threads libopenmpt in multi-threaded environments
+ *
+ * - libopenmpt is thread-aware.
+ * - Individual libopenmpt objects are not thread-safe.
+ * - libopenmpt itself does not spawn any user-visible threads but may spawn
+ * threads for internal use.
+ * - You must ensure to only ever access a particular libopenmpt object from a
+ * single thread at a time.
+ * - Consecutive accesses can happen from different threads.
+ * - Different objects can be accessed concurrently from different threads.
+ *
+ * \section libopenmpt_c_staticlinking Statically linking to libopenmpt
+ *
+ * libopenmpt is implemented in C++. This implies that linking to libopenmpt
+ * statically requires linking to the C++ runtime and standard library. The
+ * **highly preferred and recommended** way to do this is by using the C++
+ * compiler instead of the platform linker to do the linking. This will do all
+ * necessary things that are C++ specific (in particular, it will pull in the
+ * appropriate runtime and/or library). If for whatever reason it is not
+ * possible to use the C++ compiler for statically linking against libopenmpt,
+ * the libopenmpt build system can list the required libraries in the pkg-config
+ * file `libopenmpt.pc`. However, there is no reliable way to determine the name
+ * of the required library or libraries from within the build system. The
+ * libopenmpt autotools `configure` and plain `Makefile` honor the custom
+ * variable `CXXSTDLIB_PCLIBSPRIVATE` which serves the sole purpose of listing
+ * the standard library (or libraries) required for static linking. The contents
+ * of this variable will be put in `libopenmpt.pc` `Libs.private` and used for
+ * nothing else.
+ *
+ * This problem is inherent to libraries implemented in C++ that can also be used
+ * without a C++ compiler. Other libraries try to solve that by listing
+ * `-lstdc++` unconditionally in `Libs.private`. However, that will break
+ * platforms that use a different C++ standard library (in particular FreeBSD).
+ *
+ * See https://lists.freedesktop.org/archives/pkg-config/2016-August/001055.html .
+ *
+ * Dymically linking to libopenmpt does not require anything special and will
+ * work as usual (and exactly as done for libraries implemented in C).
+ *
+ * Note: This section does not apply when using Microsoft Visual Studio or
+ * Andriod NDK ndk-build build systems.
+ *
+ * \section libopenmpt_c_detailed Detailed documentation
+ *
+ * \ref libopenmpt_c
+ *
+ * In case a function is not documented here, you might want to look at the
+ * \ref libopenmpt_cpp documentation. The C and C++ APIs are kept semantically
+ * as close as possible.
+ *
+ * \section libopenmpt_c_examples Examples
+ *
+ * \subsection libopenmpt_c_example_unsafe Unsafe, simplified example without any error checking to get a first idea of the API
+ * \include libopenmpt_example_c_unsafe.c
+ * \subsection libopenmpt_c_example_file FILE*
+ * \include libopenmpt_example_c.c
+ * \subsection libopenmpt_c_example_inmemory in memory
+ * \include libopenmpt_example_c_mem.c
+ * \subsection libopenmpt_c_example_stdout reading FILE* and writing PCM data to STDOUT (usable without PortAudio)
+ * \include libopenmpt_example_c_stdout.c
+ *
+ */
+
+/*! \defgroup libopenmpt_c libopenmpt C */
+
+/*! \addtogroup libopenmpt_c
+ * @{
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*! \brief Get the libopenmpt version number
+ *
+ * Returns the libopenmpt version number.
+ * \return The value represents (major << 24 + minor << 16 + patch << 0).
+ * \remarks libopenmpt < 0.3.0-pre used the following scheme: (major << 24 + minor << 16 + revision).
+ */
+LIBOPENMPT_API uint32_t openmpt_get_library_version(void);
+
+/*! \brief Get the core version number
+ *
+ * Return the OpenMPT core version number.
+ * \return The value represents (majormajor << 24 + major << 16 + minor << 8 + minorminor).
+ */
+LIBOPENMPT_API uint32_t openmpt_get_core_version(void);
+
+/*! Return a verbose library version string from openmpt_get_string(). \deprecated Please use `"library_version"` directly. */
+#define OPENMPT_STRING_LIBRARY_VERSION LIBOPENMPT_DEPRECATED_STRING( "library_version" )
+/*! Return a verbose library features string from openmpt_get_string(). \deprecated Please use `"library_features"` directly. */
+#define OPENMPT_STRING_LIBRARY_FEATURES LIBOPENMPT_DEPRECATED_STRING( "library_features" )
+/*! Return a verbose OpenMPT core version string from openmpt_get_string(). \deprecated Please use `"core_version"` directly. */
+#define OPENMPT_STRING_CORE_VERSION LIBOPENMPT_DEPRECATED_STRING( "core_version" )
+/*! Return information about the current build (e.g. the build date or compiler used) from openmpt_get_string(). \deprecated Please use `"build"` directly. */
+#define OPENMPT_STRING_BUILD LIBOPENMPT_DEPRECATED_STRING( "build" )
+/*! Return all contributors from openmpt_get_string(). \deprecated Please use `"credits"` directly. */
+#define OPENMPT_STRING_CREDITS LIBOPENMPT_DEPRECATED_STRING( "credits" )
+/*! Return contact information about libopenmpt from openmpt_get_string(). \deprecated Please use `"contact"` directly. */
+#define OPENMPT_STRING_CONTACT LIBOPENMPT_DEPRECATED_STRING( "contact" )
+/*! Return the libopenmpt license from openmpt_get_string(). \deprecated Please use `"license"` directly. */
+#define OPENMPT_STRING_LICENSE LIBOPENMPT_DEPRECATED_STRING( "license" )
+
+/*! \brief Free a string returned by libopenmpt
+ *
+ * Frees any string that got returned by libopenmpt.
+ */
+LIBOPENMPT_API void openmpt_free_string( const char * str );
+
+/*! \brief Get library related metadata.
+ *
+ * \param key Key to query.
+ * Possible keys are:
+ * - "library_version": verbose library version string
+ * - "library_version_is_release": "1" if the version is an officially released version
+ * - "library_features": verbose library features string
+ * - "core_version": verbose OpenMPT core version string
+ * - "source_url": original source code URL
+ * - "source_date": original source code date
+ * - "source_revision": original source code revision
+ * - "source_is_modified": "1" if the original source has been modified
+ * - "source_has_mixed_revisions": "1" if the original source has been compiled from different various revision
+ * - "source_is_package": "1" if the original source has been obtained from a source pacakge instead of source code version control
+ * - "build": information about the current build (e.g. the build date or compiler used)
+ * - "build_compiler": information about the compiler used to build libopenmpt
+ * - "credits": all contributors
+ * - "contact": contact information about libopenmpt
+ * - "license": the libopenmpt license
+ * - "url": libopenmpt website URL
+ * - "support_forum_url": libopenmpt support and discussions forum URL
+ * - "bugtracker_url": libopenmpt bug and issue tracker URL
+ * \return A (possibly multi-line) string containing the queried information. If no information is available, the string is empty.
+ */
+LIBOPENMPT_API const char * openmpt_get_string( const char * key );
+
+/*! \brief Get a list of supported file extensions
+ *
+ * \return The semicolon-separated list of extensions supported by this libopenmpt build. The extensions are returned lower-case without a leading dot.
+ */
+LIBOPENMPT_API const char * openmpt_get_supported_extensions(void);
+
+/*! \brief Query whether a file extension is supported
+ *
+ * \param extension file extension to query without a leading dot. The case is ignored.
+ * \return 1 if the extension is supported by libopenmpt, 0 otherwise.
+ */
+LIBOPENMPT_API int openmpt_is_extension_supported( const char * extension );
+
+/*! Seek to the given offset relative to the beginning of the file. */
+#define OPENMPT_STREAM_SEEK_SET 0
+/*! Seek to the given offset relative to the current position in the file. */
+#define OPENMPT_STREAM_SEEK_CUR 1
+/*! Seek to the given offset relative to the end of the file. */
+#define OPENMPT_STREAM_SEEK_END 2
+
+/*! \brief Read bytes from stream
+ *
+ * Read bytes data from stream to dst.
+ * \param stream Stream to read data from
+ * \param dst Target where to copy data.
+ * \param bytes Number of bytes to read.
+ * \return Number of bytes actually read and written to dst.
+ * \retval 0 End of stream or error.
+ * \remarks Short reads are allowed as long as they return at least 1 byte if EOF is not reached.
+ */
+typedef size_t (*openmpt_stream_read_func)( void * stream, void * dst, size_t bytes );
+
+/*! \brief Seek stream position
+ *
+ * Seek to stream position offset at whence.
+ * \param stream Stream to operate on.
+ * \param offset Offset to seek to.
+ * \param whence OPENMPT_STREAM_SEEK_SET, OPENMPT_STREAM_SEEK_CUR, OPENMPT_STREAM_SEEK_END. See C89 documentation.
+ * \return Returns 0 on success.
+ * \retval 0 Success.
+ * \retval -1 Failure. Position does not get updated.
+ * \remarks libopenmpt will not try to seek beyond the file size, thus it is not important whether you allow for virtual positioning after the file end, or return an error in that case. The position equal to the file size needs to be seekable to.
+ */
+typedef int (*openmpt_stream_seek_func)( void * stream, int64_t offset, int whence );
+
+/*! \brief Tell stream position
+ *
+ * Tell position of stream.
+ * \param stream Stream to operate on.
+ * \return Current position in stream.
+ * \retval -1 Failure.
+ */
+typedef int64_t (*openmpt_stream_tell_func)( void * stream );
+
+/*! \brief Stream callbacks
+ *
+ * Stream callbacks used by libopenmpt for stream operations.
+ * \sa openmpt_stream_get_file_callbacks
+ * \sa openmpt_stream_get_fd_callbacks
+ * \sa openmpt_stream_get_buffer_callbacks
+ */
+typedef struct openmpt_stream_callbacks {
+
+ /*! \brief Read callback.
+ *
+ * \sa openmpt_stream_read_func
+ */
+ openmpt_stream_read_func read;
+
+ /*! \brief Seek callback.
+ *
+ * Seek callback can be NULL if seeking is not supported.
+ * \sa openmpt_stream_seek_func
+ */
+ openmpt_stream_seek_func seek;
+
+ /*! \brief Tell callback.
+ *
+ * Tell callback can be NULL if seeking is not supported.
+ * \sa openmpt_stream_tell_func
+ */
+ openmpt_stream_tell_func tell;
+
+} openmpt_stream_callbacks;
+
+/*! \brief Logging function
+ *
+ * \param message UTF-8 encoded log message.
+ * \param user User context that was passed to openmpt_module_create2(), openmpt_module_create_from_memory2() or openmpt_could_open_probability2().
+ */
+typedef void (*openmpt_log_func)( const char * message, void * user );
+
+/*! \brief Default logging function
+ *
+ * Default logging function that logs anything to stderr.
+ */
+LIBOPENMPT_API void openmpt_log_func_default( const char * message, void * user );
+
+/*! \brief Silent logging function
+ *
+ * Silent logging function that throws any log message away.
+ */
+LIBOPENMPT_API void openmpt_log_func_silent( const char * message, void * user );
+
+/*! No error. \since 0.3.0 */
+#define OPENMPT_ERROR_OK 0
+
+/*! Lowest value libopenmpt will use for any of its own error codes. \since 0.3.0 */
+#define OPENMPT_ERROR_BASE 256
+
+/*! Unknown internal error. \since 0.3.0 */
+#define OPENMPT_ERROR_UNKNOWN ( OPENMPT_ERROR_BASE + 1 )
+
+/*! Unknown internal C++ exception. \since 0.3.0 */
+#define OPENMPT_ERROR_EXCEPTION ( OPENMPT_ERROR_BASE + 11 )
+
+/*! Out of memory. \since 0.3.0 */
+#define OPENMPT_ERROR_OUT_OF_MEMORY ( OPENMPT_ERROR_BASE + 21 )
+
+/*! Runtime error. \since 0.3.0 */
+#define OPENMPT_ERROR_RUNTIME ( OPENMPT_ERROR_BASE + 30 )
+/*! Range error. \since 0.3.0 */
+#define OPENMPT_ERROR_RANGE ( OPENMPT_ERROR_BASE + 31 )
+/*! Arithmetic overflow. \since 0.3.0 */
+#define OPENMPT_ERROR_OVERFLOW ( OPENMPT_ERROR_BASE + 32 )
+/*! Arithmetic underflow. \since 0.3.0 */
+#define OPENMPT_ERROR_UNDERFLOW ( OPENMPT_ERROR_BASE + 33 )
+
+/*! Logic error. \since 0.3.0 */
+#define OPENMPT_ERROR_LOGIC ( OPENMPT_ERROR_BASE + 40 )
+/*! Value domain error. \since 0.3.0 */
+#define OPENMPT_ERROR_DOMAIN ( OPENMPT_ERROR_BASE + 41 )
+/*! Maximum supported size exceeded. \since 0.3.0 */
+#define OPENMPT_ERROR_LENGTH ( OPENMPT_ERROR_BASE + 42 )
+/*! Argument out of range. \since 0.3.0 */
+#define OPENMPT_ERROR_OUT_OF_RANGE ( OPENMPT_ERROR_BASE + 43 )
+/*! Invalid argument. \since 0.3.0 */
+#define OPENMPT_ERROR_INVALID_ARGUMENT ( OPENMPT_ERROR_BASE + 44 )
+
+/*! General libopenmpt error. \since 0.3.0 */
+#define OPENMPT_ERROR_GENERAL ( OPENMPT_ERROR_BASE + 101 )
+/*! openmpt_module * is invalid. \since 0.3.0 */
+#define OPENMPT_ERROR_INVALID_MODULE_POINTER ( OPENMPT_ERROR_BASE + 102 )
+/*! NULL pointer argument. \since 0.3.0 */
+#define OPENMPT_ERROR_ARGUMENT_NULL_POINTER ( OPENMPT_ERROR_BASE + 103 )
+
+/*! \brief Check whether the error is transient
+ *
+ * Checks whether an error code represents a transient error which may not occur again in a later try if for example memory has been freed up after an out-of-memory error.
+ * \param error Error code.
+ * \retval 0 Error is not transient.
+ * \retval 1 Error is transient.
+ * \sa OPENMPT_ERROR_OUT_OF_MEMORY
+ * \since 0.3.0
+ */
+LIBOPENMPT_API int openmpt_error_is_transient( int error );
+
+/*! \brief Convert error code to text
+ *
+ * Converts an error code into a text string describing the error.
+ * \param error Error code.
+ * \return Allocated string describing the error.
+ * \retval NULL Not enough memory to allocate the string.
+ * \since 0.3.0
+ */
+LIBOPENMPT_API const char * openmpt_error_string( int error );
+
+/*! Do not log or store the error. \since 0.3.0 */
+#define OPENMPT_ERROR_FUNC_RESULT_NONE 0
+/*! Log the error. \since 0.3.0 */
+#define OPENMPT_ERROR_FUNC_RESULT_LOG ( 1 << 0 )
+/*! Store the error. \since 0.3.0 */
+#define OPENMPT_ERROR_FUNC_RESULT_STORE ( 1 << 1 )
+/*! Log and store the error. \since 0.3.0 */
+#define OPENMPT_ERROR_FUNC_RESULT_DEFAULT ( OPENMPT_ERROR_FUNC_RESULT_LOG | OPENMPT_ERROR_FUNC_RESULT_STORE )
+
+/*! \brief Error function
+ *
+ * \param error Error code.
+ * \param user User context that was passed to openmpt_module_create2(), openmpt_module_create_from_memory2() or openmpt_could_open_probability2().
+ * \return Mask of OPENMPT_ERROR_FUNC_RESULT_LOG and OPENMPT_ERROR_FUNC_RESULT_STORE.
+ * \retval OPENMPT_ERROR_FUNC_RESULT_NONE Do not log or store the error.
+ * \retval OPENMPT_ERROR_FUNC_RESULT_LOG Log the error.
+ * \retval OPENMPT_ERROR_FUNC_RESULT_STORE Store the error.
+ * \retval OPENMPT_ERROR_FUNC_RESULT_DEFAULT Log and store the error.
+ * \sa OPENMPT_ERROR_FUNC_RESULT_NONE
+ * \sa OPENMPT_ERROR_FUNC_RESULT_LOG
+ * \sa OPENMPT_ERROR_FUNC_RESULT_STORE
+ * \sa OPENMPT_ERROR_FUNC_RESULT_DEFAULT
+ * \sa openmpt_error_func_default
+ * \sa openmpt_error_func_log
+ * \sa openmpt_error_func_store
+ * \sa openmpt_error_func_ignore
+ * \sa openmpt_error_func_errno
+ * \since 0.3.0
+ */
+typedef int (*openmpt_error_func)( int error, void * user );
+
+/*! \brief Default error function
+ *
+ * Causes all errors to be logged and stored.
+ * \param error Error code.
+ * \param user Ignored.
+ * \retval OPENMPT_ERROR_FUNC_RESULT_DEFAULT Always.
+ * \since 0.3.0
+ */
+LIBOPENMPT_API int openmpt_error_func_default( int error, void * user );
+
+/*! \brief Log error function
+ *
+ * Causes all errors to be logged.
+ * \param error Error code.
+ * \param user Ignored.
+ * \retval OPENMPT_ERROR_FUNC_RESULT_LOG Always.
+ * \since 0.3.0
+ */
+LIBOPENMPT_API int openmpt_error_func_log( int error, void * user );
+
+/*! \brief Store error function
+ *
+ * Causes all errors to be stored.
+ * \param error Error code.
+ * \param user Ignored.
+ * \retval OPENMPT_ERROR_FUNC_RESULT_STORE Always.
+ * \since 0.3.0
+ */
+LIBOPENMPT_API int openmpt_error_func_store( int error, void * user );
+
+/*! \brief Ignore error function
+ *
+ * Causes all errors to be neither logged nor stored.
+ * \param error Error code.
+ * \param user Ignored.
+ * \retval OPENMPT_ERROR_FUNC_RESULT_NONE Always.
+ * \since 0.3.0
+ */
+LIBOPENMPT_API int openmpt_error_func_ignore( int error, void * user );
+
+/*! \brief Errno error function
+ *
+ * Causes all errors to be stored in the pointer passed in as user.
+ * \param error Error code.
+ * \param user Pointer to an int as generated by openmpt_error_func_errno_userdata.
+ * \retval OPENMPT_ERROR_FUNC_RESULT_NONE user is not NULL.
+ * \retval OPENMPT_ERROR_FUNC_RESULT_DEFAULT user is NULL.
+ * \since 0.3.0
+ */
+LIBOPENMPT_API int openmpt_error_func_errno( int error, void * user );
+
+/*! \brief User pointer for openmpt_error_func_errno
+ *
+ * Provides a suitable user pointer argument for openmpt_error_func_errno.
+ * \param error Pointer to an integer value to be used as output by openmpt_error_func_errno.
+ * \retval (void*)error.
+ * \since 0.3.0
+ */
+LIBOPENMPT_API void * openmpt_error_func_errno_userdata( int * error );
+
+/*! \brief Roughly scan the input stream to find out whether libopenmpt might be able to open it
+ *
+ * \param stream_callbacks Input stream callback operations.
+ * \param stream Input stream to scan.
+ * \param effort Effort to make when validating stream. Effort 0.0 does not even look at stream at all and effort 1.0 completely loads the file from stream. A lower effort requires less data to be loaded but only gives a rough estimate answer. Use an effort of 0.25 to only verify the header data of the module file.
+ * \param logfunc Logging function where warning and errors are written. May be NULL.
+ * \param user Logging function user context. Used to pass any user-defined data associated with this module to the logging function.
+ * \return Probability between 0.0 and 1.0.
+ * \remarks openmpt_could_open_probability() can return any value between 0.0 and 1.0. Only 0.0 and 1.0 are definitive answers, all values in between are just estimates. In general, any return value >0.0 means that you should try loading the file, and any value below 1.0 means that loading may fail. If you want a threshold above which you can be reasonably sure that libopenmpt will be able to load the file, use >=0.5. If you see the need for a threshold below which you could reasonably outright reject a file, use <0.25 (Note: Such a threshold for rejecting on the lower end is not recommended, but may be required for better integration into some other framework's probe scoring.).
+ * \remarks openmpt_could_open_probability() expects the complete file data to be eventually available to it, even if it is asked to just parse the header. Verification will be unreliable (both false positives and false negatives), if you pretend that the file is just some few bytes of initial data threshold in size. In order to really just access the first bytes of a file, check in your callback functions whether data or seeking is requested beyond your initial data threshold, and in that case, return an error. openmpt_could_open_probability() will treat this as any other I/O error and return 0.0. You must not expect the correct result in this case. You instead must remember that it asked for more data than you currently want to provide to it and treat this situation as if openmpt_could_open_probability() returned 0.5.
+ * \sa \ref libopenmpt_c_fileio
+ * \sa openmpt_stream_callbacks
+ * \deprecated Please use openmpt_could_open_probability2().
+ * \since 0.3.0
+ */
+LIBOPENMPT_API LIBOPENMPT_DEPRECATED double openmpt_could_open_probability( openmpt_stream_callbacks stream_callbacks, void * stream, double effort, openmpt_log_func logfunc, void * user );
+
+/*! \brief Roughly scan the input stream to find out whether libopenmpt might be able to open it
+ *
+ * \param stream_callbacks Input stream callback operations.
+ * \param stream Input stream to scan.
+ * \param effort Effort to make when validating stream. Effort 0.0 does not even look at stream at all and effort 1.0 completely loads the file from stream. A lower effort requires less data to be loaded but only gives a rough estimate answer. Use an effort of 0.25 to only verify the header data of the module file.
+ * \param logfunc Logging function where warning and errors are written. May be NULL.
+ * \param user Logging function user context. Used to pass any user-defined data associated with this module to the logging function.
+ * \return Probability between 0.0 and 1.0.
+ * \remarks openmpt_could_open_probability() can return any value between 0.0 and 1.0. Only 0.0 and 1.0 are definitive answers, all values in between are just estimates. In general, any return value >0.0 means that you should try loading the file, and any value below 1.0 means that loading may fail. If you want a threshold above which you can be reasonably sure that libopenmpt will be able to load the file, use >=0.5. If you see the need for a threshold below which you could reasonably outright reject a file, use <0.25 (Note: Such a threshold for rejecting on the lower end is not recommended, but may be required for better integration into some other framework's probe scoring.).
+ * \remarks openmpt_could_open_probability() expects the complete file data to be eventually available to it, even if it is asked to just parse the header. Verification will be unreliable (both false positives and false negatives), if you pretend that the file is just some few bytes of initial data threshold in size. In order to really just access the first bytes of a file, check in your callback functions whether data or seeking is requested beyond your initial data threshold, and in that case, return an error. openmpt_could_open_probability() will treat this as any other I/O error and return 0.0. You must not expect the correct result in this case. You instead must remember that it asked for more data than you currently want to provide to it and treat this situation as if openmpt_could_open_probability() returned 0.5.
+ * \sa \ref libopenmpt_c_fileio
+ * \sa openmpt_stream_callbacks
+ * \deprecated Please use openmpt_could_open_probability2().
+ */
+LIBOPENMPT_API LIBOPENMPT_DEPRECATED double openmpt_could_open_propability( openmpt_stream_callbacks stream_callbacks, void * stream, double effort, openmpt_log_func logfunc, void * user );
+
+/*! \brief Roughly scan the input stream to find out whether libopenmpt might be able to open it
+ *
+ * \param stream_callbacks Input stream callback operations.
+ * \param stream Input stream to scan.
+ * \param effort Effort to make when validating stream. Effort 0.0 does not even look at stream at all and effort 1.0 completely loads the file from stream. A lower effort requires less data to be loaded but only gives a rough estimate answer. Use an effort of 0.25 to only verify the header data of the module file.
+ * \param logfunc Logging function where warning and errors are written. May be NULL.
+ * \param loguser Logging function user context. Used to pass any user-defined data associated with this module to the logging function.
+ * \param errfunc Error function to define error behaviour. May be NULL.
+ * \param erruser Error function user context. Used to pass any user-defined data associated with this module to the logging function.
+ * \param error Pointer to an integer where an error may get stored. May be NULL.
+ * \param error_message Pointer to a string pointer where an error message may get stored. May be NULL.
+ * \return Probability between 0.0 and 1.0.
+ * \remarks openmpt_probe_file_header() or openmpt_probe_file_header_without_filesize() provide a simpler and faster interface that fits almost all use cases better. It is recommended to use openmpt_probe_file_header() or openmpt_probe_file_header_without_filesize() instead of openmpt_could_open_probability().
+ * \remarks openmpt_could_open_probability2() can return any value between 0.0 and 1.0. Only 0.0 and 1.0 are definitive answers, all values in between are just estimates. In general, any return value >0.0 means that you should try loading the file, and any value below 1.0 means that loading may fail. If you want a threshold above which you can be reasonably sure that libopenmpt will be able to load the file, use >=0.5. If you see the need for a threshold below which you could reasonably outright reject a file, use <0.25 (Note: Such a threshold for rejecting on the lower end is not recommended, but may be required for better integration into some other framework's probe scoring.).
+ * \remarks openmpt_could_open_probability2() expects the complete file data to be eventually available to it, even if it is asked to just parse the header. Verification will be unreliable (both false positives and false negatives), if you pretend that the file is just some few bytes of initial data threshold in size. In order to really just access the first bytes of a file, check in your callback functions whether data or seeking is requested beyond your initial data threshold, and in that case, return an error. openmpt_could_open_probability2() will treat this as any other I/O error and return 0.0. You must not expect the correct result in this case. You instead must remember that it asked for more data than you currently want to provide to it and treat this situation as if openmpt_could_open_probability2() returned 0.5. \include libopenmpt_example_c_probe.c
+ * \sa \ref libopenmpt_c_fileio
+ * \sa openmpt_stream_callbacks
+ * \sa openmpt_probe_file_header
+ * \sa openmpt_probe_file_header_without_filesize
+ * \since 0.3.0
+ */
+LIBOPENMPT_API double openmpt_could_open_probability2( openmpt_stream_callbacks stream_callbacks, void * stream, double effort, openmpt_log_func logfunc, void * loguser, openmpt_error_func errfunc, void * erruser, int * error, const char * * error_message );
+
+/*! \brief Get recommended header size for successfull format probing
+ *
+ * \sa openmpt_probe_file_header()
+ * \sa openmpt_probe_file_header_without_filesize()
+ * \since 0.3.0
+ */
+LIBOPENMPT_API size_t openmpt_probe_file_header_get_recommended_size(void);
+
+/*! Probe for module formats in openmpt_probe_file_header() or openmpt_probe_file_header_without_filesize(). \since 0.3.0 */
+#define OPENMPT_PROBE_FILE_HEADER_FLAGS_MODULES 0x1ul
+/*! Probe for module-specific container formats in openmpt_probe_file_header() or openmpt_probe_file_header_without_filesize(). \since 0.3.0 */
+#define OPENMPT_PROBE_FILE_HEADER_FLAGS_CONTAINERS 0x2ul
+
+/*! Probe for the default set of formats in openmpt_probe_file_header() or openmpt_probe_file_header_without_filesize(). \since 0.3.0 */
+#define OPENMPT_PROBE_FILE_HEADER_FLAGS_DEFAULT ( OPENMPT_PROBE_FILE_HEADER_FLAGS_MODULES | OPENMPT_PROBE_FILE_HEADER_FLAGS_CONTAINERS )
+/*! Probe for no formats in openmpt_probe_file_header() or openmpt_probe_file_header_without_filesize(). \since 0.3.0 */
+#define OPENMPT_PROBE_FILE_HEADER_FLAGS_NONE 0x0ul
+
+/*! Possible return values fo openmpt_probe_file_header() and openmpt_probe_file_header_without_filesize(). \since 0.3.0 */
+#define OPENMPT_PROBE_FILE_HEADER_RESULT_SUCCESS 1
+/*! Possible return values fo openmpt_probe_file_header() and openmpt_probe_file_header_without_filesize(). \since 0.3.0 */
+#define OPENMPT_PROBE_FILE_HEADER_RESULT_FAILURE 0
+/*! Possible return values fo openmpt_probe_file_header() and openmpt_probe_file_header_without_filesize(). \since 0.3.0 */
+#define OPENMPT_PROBE_FILE_HEADER_RESULT_WANTMOREDATA (-1)
+/*! Possible return values fo openmpt_probe_file_header() and openmpt_probe_file_header_without_filesize(). \since 0.3.0 */
+#define OPENMPT_PROBE_FILE_HEADER_RESULT_ERROR (-255)
+
+/*! \brief Probe the provided bytes from the beginning of a file for supported file format headers to find out whether libopenmpt might be able to open it
+ *
+ * \param flags Ored mask of OPENMPT_PROBE_FILE_HEADER_FLAGS_MODULES and OPENMPT_PROBE_FILE_HEADER_FLAGS_CONTAINERS, or OPENMPT_PROBE_FILE_HEADER_FLAGS_DEFAULT.
+ * \param data Beginning of the file data.
+ * \param size Size of the beginning of the file data.
+ * \param filesize Full size of the file data on disk.
+ * \param logfunc Logging function where warning and errors are written. May be NULL.
+ * \param loguser Logging function user context. Used to pass any user-defined data associated with this module to the logging function.
+ * \param errfunc Error function to define error behaviour. May be NULL.
+ * \param erruser Error function user context. Used to pass any user-defined data associated with this module to the logging function.
+ * \param error Pointer to an integer where an error may get stored. May be NULL.
+ * \param error_message Pointer to a string pointer where an error message may get stored. May be NULL.
+ * \remarks It is recommended to provide openmpt_probe_file_header_get_recommended_size() bytes of data for data and size. If the file is smaller, only provide the filesize amount and set size and filesize to the file's size.
+ * \remarks openmpt_could_open_probability2() provides a more elaborate interface that might be required for special use cases. It is recommended to use openmpt_probe_file_header() though, if possible.
+ * \retval OPENMPT_PROBE_FILE_HEADER_RESULT_SUCCESS The file will most likely be supported by libopenmpt.
+ * \retval OPENMPT_PROBE_FILE_HEADER_RESULT_FAILURE The file is not supported by libopenmpt.
+ * \retval OPENMPT_PROBE_FILE_HEADER_RESULT_WANTMOREDATA An answer could not be determined with the amount of data provided.
+ * \retval OPENMPT_PROBE_FILE_HEADER_RESULT_ERROR An internal error occurred.
+ * \sa openmpt_probe_file_header_get_recommended_size()
+ * \sa openmpt_probe_file_header_without_filesize()
+ * \sa openmpt_probe_file_header_from_stream()
+ * \sa openmpt_could_open_probability2()
+ * \since 0.3.0
+ */
+LIBOPENMPT_API int openmpt_probe_file_header( uint64_t flags, const void * data, size_t size, uint64_t filesize, openmpt_log_func logfunc, void * loguser, openmpt_error_func errfunc, void * erruser, int * error, const char * * error_message );
+/*! \brief Probe the provided bytes from the beginning of a file for supported file format headers to find out whether libopenmpt might be able to open it
+ *
+ * \param flags Ored mask of OPENMPT_PROBE_FILE_HEADER_FLAGS_MODULES and OPENMPT_PROBE_FILE_HEADER_FLAGS_CONTAINERS, or OPENMPT_PROBE_FILE_HEADER_FLAGS_DEFAULT.
+ * \param data Beginning of the file data.
+ * \param size Size of the beginning of the file data.
+ * \param logfunc Logging function where warning and errors are written. May be NULL.
+ * \param loguser Logging function user context. Used to pass any user-defined data associated with this module to the logging function.
+ * \param errfunc Error function to define error behaviour. May be NULL.
+ * \param erruser Error function user context. Used to pass any user-defined data associated with this module to the logging function.
+ * \param error Pointer to an integer where an error may get stored. May be NULL.
+ * \param error_message Pointer to a string pointer where an error message may get stored. May be NULL.
+ * \remarks It is recommended to use openmpt_probe_file_header() and provide the acutal file's size as a parameter if at all possible. libopenmpt can provide more accurate answers if the filesize is known.
+ * \remarks It is recommended to provide openmpt_probe_file_header_get_recommended_size() bytes of data for data and size. If the file is smaller, only provide the filesize amount and set size to the file's size.
+ * \remarks openmpt_could_open_probability2() provides a more elaborate interface that might be required for special use cases. It is recommended to use openmpt_probe_file_header() though, if possible.
+ * \retval OPENMPT_PROBE_FILE_HEADER_RESULT_SUCCESS The file will most likely be supported by libopenmpt.
+ * \retval OPENMPT_PROBE_FILE_HEADER_RESULT_FAILURE The file is not supported by libopenmpt.
+ * \retval OPENMPT_PROBE_FILE_HEADER_RESULT_WANTMOREDATA An answer could not be determined with the amount of data provided.
+ * \retval OPENMPT_PROBE_FILE_HEADER_RESULT_ERROR An internal error occurred.
+ * \sa openmpt_probe_file_header_get_recommended_size()
+ * \sa openmpt_probe_file_header()
+ * \sa openmpt_probe_file_header_from_stream()
+ * \sa openmpt_could_open_probability2()
+ * \since 0.3.0
+ */
+LIBOPENMPT_API int openmpt_probe_file_header_without_filesize( uint64_t flags, const void * data, size_t size, openmpt_log_func logfunc, void * loguser, openmpt_error_func errfunc, void * erruser, int * error, const char * * error_message );
+
+/*! \brief Probe the provided bytes from the beginning of a file for supported file format headers to find out whether libopenmpt might be able to open it
+ *
+ * \param flags Ored mask of OPENMPT_PROBE_FILE_HEADER_FLAGS_MODULES and OPENMPT_PROBE_FILE_HEADER_FLAGS_CONTAINERS, or OPENMPT_PROBE_FILE_HEADER_FLAGS_DEFAULT.
+ * \param stream_callbacks Input stream callback operations.
+ * \param stream Input stream to scan.
+ * \param logfunc Logging function where warning and errors are written. May be NULL.
+ * \param loguser Logging function user context. Used to pass any user-defined data associated with this module to the logging function.
+ * \param errfunc Error function to define error behaviour. May be NULL.
+ * \param erruser Error function user context. Used to pass any user-defined data associated with this module to the logging function.
+ * \param error Pointer to an integer where an error may get stored. May be NULL.
+ * \param error_message Pointer to a string pointer where an error message may get stored. May be NULL.
+ * \remarks The stream is left in an unspecified state when this function returns.
+ * \remarks It is recommended to provide openmpt_probe_file_header_get_recommended_size() bytes of data for data and size. If the file is smaller, only provide the filesize amount and set size and filesize to the file's size.
+ * \remarks openmpt_could_open_probability2() provides a more elaborate interface that might be required for special use cases. It is recommended to use openmpt_probe_file_header() though, if possible.
+ * \retval OPENMPT_PROBE_FILE_HEADER_RESULT_SUCCESS The file will most likely be supported by libopenmpt.
+ * \retval OPENMPT_PROBE_FILE_HEADER_RESULT_FAILURE The file is not supported by libopenmpt.
+ * \retval OPENMPT_PROBE_FILE_HEADER_RESULT_WANTMOREDATA An answer could not be determined with the amount of data provided.
+ * \retval OPENMPT_PROBE_FILE_HEADER_RESULT_ERROR An internal error occurred.
+ * \sa openmpt_probe_file_header_get_recommended_size()
+ * \sa openmpt_probe_file_header()
+ * \sa openmpt_probe_file_header_without_filesize()
+ * \sa openmpt_could_open_probability2()
+ * \since 0.3.0
+ */
+LIBOPENMPT_API int openmpt_probe_file_header_from_stream( uint64_t flags, openmpt_stream_callbacks stream_callbacks, void * stream, openmpt_log_func logfunc, void * loguser, openmpt_error_func errfunc, void * erruser, int * error, const char * * error_message );
+
+
+/*! \brief Opaque type representing a libopenmpt module
+ */
+typedef struct openmpt_module openmpt_module;
+
+typedef struct openmpt_module_initial_ctl {
+ const char * ctl;
+ const char * value;
+} openmpt_module_initial_ctl;
+
+/*! \brief Construct an openmpt_module
+ *
+ * \param stream_callbacks Input stream callback operations.
+ * \param stream Input stream to load the module from.
+ * \param logfunc Logging function where warning and errors are written. The logging function may be called throughout the lifetime of openmpt_module. May be NULL.
+ * \param loguser User-defined data associated with this module. This value will be passed to the logging callback function (logfunc)
+ * \param ctls A map of initial ctl values. See openmpt_module_get_ctls()
+ * \return A pointer to the constructed openmpt_module, or NULL on failure.
+ * \remarks The input data can be discarded after an openmpt_module has been constructed successfully.
+ * \sa openmpt_stream_callbacks
+ * \sa \ref libopenmpt_c_fileio
+ * \deprecated Please use openmpt_module_create2().
+ */
+LIBOPENMPT_API LIBOPENMPT_DEPRECATED openmpt_module * openmpt_module_create( openmpt_stream_callbacks stream_callbacks, void * stream, openmpt_log_func logfunc, void * loguser, const openmpt_module_initial_ctl * ctls );
+
+/*! \brief Construct an openmpt_module
+ *
+ * \param stream_callbacks Input stream callback operations.
+ * \param stream Input stream to load the module from.
+ * \param logfunc Logging function where warning and errors are written. The logging function may be called throughout the lifetime of openmpt_module. May be NULL.
+ * \param loguser User-defined data associated with this module. This value will be passed to the logging callback function (logfunc)
+ * \param errfunc Error function to define error behaviour. May be NULL.
+ * \param erruser Error function user context. Used to pass any user-defined data associated with this module to the logging function.
+ * \param error Pointer to an integer where an error may get stored. May be NULL.
+ * \param error_message Pointer to a string pointer where an error message may get stored. May be NULL.
+ * \param ctls A map of initial ctl values. See openmpt_module_get_ctls()
+ * \return A pointer to the constructed openmpt_module, or NULL on failure.
+ * \remarks The input data can be discarded after an openmpt_module has been constructed successfully.
+ * \sa openmpt_stream_callbacks
+ * \sa \ref libopenmpt_c_fileio
+ * \since 0.3.0
+ */
+LIBOPENMPT_API openmpt_module * openmpt_module_create2( openmpt_stream_callbacks stream_callbacks, void * stream, openmpt_log_func logfunc, void * loguser, openmpt_error_func errfunc, void * erruser, int * error, const char * * error_message, const openmpt_module_initial_ctl * ctls );
+
+/*! \brief Construct an openmpt_module
+ *
+ * \param filedata Data to load the module from.
+ * \param filesize Amount of data available.
+ * \param logfunc Logging function where warning and errors are written. The logging function may be called throughout the lifetime of openmpt_module.
+ * \param loguser User-defined data associated with this module. This value will be passed to the logging callback function (logfunc)
+ * \param ctls A map of initial ctl values. See openmpt_module_get_ctls()
+ * \return A pointer to the constructed openmpt_module, or NULL on failure.
+ * \remarks The input data can be discarded after an openmpt_module has been constructed successfully.
+ * \sa \ref libopenmpt_c_fileio
+ * \deprecated Please use openmpt_module_create_from_memory2().
+ */
+LIBOPENMPT_API LIBOPENMPT_DEPRECATED openmpt_module * openmpt_module_create_from_memory( const void * filedata, size_t filesize, openmpt_log_func logfunc, void * loguser, const openmpt_module_initial_ctl * ctls );
+
+/*! \brief Construct an openmpt_module
+ *
+ * \param filedata Data to load the module from.
+ * \param filesize Amount of data available.
+ * \param logfunc Logging function where warning and errors are written. The logging function may be called throughout the lifetime of openmpt_module.
+ * \param loguser User-defined data associated with this module. This value will be passed to the logging callback function (logfunc)
+ * \param errfunc Error function to define error behaviour. May be NULL.
+ * \param erruser Error function user context. Used to pass any user-defined data associated with this module to the logging function.
+ * \param error Pointer to an integer where an error may get stored. May be NULL.
+ * \param error_message Pointer to a string pointer where an error message may get stored. May be NULL.
+ * \param ctls A map of initial ctl values. See openmpt_module_get_ctls()
+ * \return A pointer to the constructed openmpt_module, or NULL on failure.
+ * \remarks The input data can be discarded after an openmpt_module has been constructed successfully.
+ * \sa \ref libopenmpt_c_fileio
+ * \since 0.3.0
+ */
+LIBOPENMPT_API openmpt_module * openmpt_module_create_from_memory2( const void * filedata, size_t filesize, openmpt_log_func logfunc, void * loguser, openmpt_error_func errfunc, void * erruser, int * error, const char * * error_message, const openmpt_module_initial_ctl * ctls );
+
+/*! \brief Unload a previously created openmpt_module from memory.
+ *
+ * \param mod The module to unload.
+ */
+LIBOPENMPT_API void openmpt_module_destroy( openmpt_module * mod );
+
+/*! \brief Set logging function.
+ *
+ * Set the logging function of an already constructed openmpt_module.
+ * \param mod The module handle to work on.
+ * \param logfunc Logging function where warning and errors are written. The logging function may be called throughout the lifetime of openmpt_module.
+ * \param loguser User-defined data associated with this module. This value will be passed to the logging callback function (logfunc)
+ * \since 0.3.0
+ */
+LIBOPENMPT_API void openmpt_module_set_log_func( openmpt_module * mod, openmpt_log_func logfunc, void * loguser );
+
+/*! \brief Set error function.
+ *
+ * Set the error function of an already constructed openmpt_module.
+ * \param mod The module handle to work on.
+ * \param errfunc Error function to define error behaviour. May be NULL.
+ * \param erruser Error function user context.
+ * \since 0.3.0
+ */
+LIBOPENMPT_API void openmpt_module_set_error_func( openmpt_module * mod, openmpt_error_func errfunc, void * erruser );
+
+/*! \brief Get last error.
+ *
+ * Return the error currently stored in an openmpt_module. The stored error is not cleared.
+ * \param mod The module handle to work on.
+ * \return The error currently stored.
+ * \sa openmpt_module_error_get_last_message
+ * \sa openmpt_module_error_set_last
+ * \sa openmpt_module_error_clear
+ * \since 0.3.0
+ */
+LIBOPENMPT_API int openmpt_module_error_get_last( openmpt_module * mod );
+
+/*! \brief Get last error message.
+ *
+ * Return the error message currently stored in an openmpt_module. The stored error is not cleared.
+ * \param mod The module handle to work on.
+ * \return The error message currently stored.
+ * \sa openmpt_module_error_set_last
+ * \sa openmpt_module_error_clear
+ * \since 0.3.0
+ */
+LIBOPENMPT_API const char * openmpt_module_error_get_last_message( openmpt_module * mod );
+
+/*! \brief Set last error.
+ *
+ * Set the error currently stored in an openmpt_module.
+ * \param mod The module handle to work on.
+ * \param error Error to be stored.
+ * \sa openmpt_module_error_get_last
+ * \sa openmpt_module_error_clear
+ * \since 0.3.0
+ */
+LIBOPENMPT_API void openmpt_module_error_set_last( openmpt_module * mod, int error );
+
+/*! \brief Clear last error.
+ *
+ * Set the error currently stored in an openmpt_module to OPPENMPT_ERROR_OK.
+ * \param mod The module handle to work on.
+ * \sa openmpt_module_error_get_last
+ * \sa openmpt_module_error_set_last
+ * \since 0.3.0
+ */
+LIBOPENMPT_API void openmpt_module_error_clear( openmpt_module * mod );
+
+/**
+ * \defgroup openmpt_module_render_param Render param indices
+ *
+ * \brief Parameter index to use with openmpt_module_get_render_param() and openmpt_module_set_render_param()
+ * @{
+ */
+/*! \brief Master Gain
+ *
+ * The related value represents a relative gain in milliBel.\n
+ * The default value is 0.\n
+ * The supported value range is unlimited.\n
+ */
+#define OPENMPT_MODULE_RENDER_MASTERGAIN_MILLIBEL 1
+/*! \brief Stereo Separation
+ *
+ * The related value represents the stereo separation generated by the libopenmpt mixer in percent.\n
+ * The default value is 100.\n
+ * The supported value range is [0,200].\n
+ */
+#define OPENMPT_MODULE_RENDER_STEREOSEPARATION_PERCENT 2
+/*! \brief Interpolation Filter
+ *
+ * The related value represents the interpolation filter length used by the libopenmpt mixer.\n
+ * The default value is 0, which indicates a recommended default value.\n
+ * The supported value range is [0,inf). Values greater than the implementation limit are clamped to the maximum supported value.\n
+ * Currently supported values:
+ * - 0: internal default
+ * - 1: no interpolation (zero order hold)
+ * - 2: linear interpolation
+ * - 4: cubic interpolation
+ * - 8: windowed sinc with 8 taps
+ */
+#define OPENMPT_MODULE_RENDER_INTERPOLATIONFILTER_LENGTH 3
+/*! \brief Volume Ramping Strength
+ *
+ * The related value represents the amount of volume ramping done by the libopenmpt mixer.\n
+ * The default value is -1, which indicates a recommended default value.\n
+ * The meaningful value range is [-1..10].\n
+ * A value of 0 completely disables volume ramping. This might cause clicks in sound output.\n
+ * Higher values imply slower/softer volume ramps.
+ */
+#define OPENMPT_MODULE_RENDER_VOLUMERAMPING_STRENGTH 4
+/** @}*/
+
+/**
+ * \defgroup openmpt_module_command_index Pattern cell indices
+ *
+ * \brief Parameter index to use with openmpt_module_get_pattern_row_channel_command(), openmpt_module_format_pattern_row_channel_command() and openmpt_module_highlight_pattern_row_channel_command()
+ * @{
+ */
+#define OPENMPT_MODULE_COMMAND_NOTE 0
+#define OPENMPT_MODULE_COMMAND_INSTRUMENT 1
+#define OPENMPT_MODULE_COMMAND_VOLUMEEFFECT 2
+#define OPENMPT_MODULE_COMMAND_EFFECT 3
+#define OPENMPT_MODULE_COMMAND_VOLUME 4
+#define OPENMPT_MODULE_COMMAND_PARAMETER 5
+/** @}*/
+
+/*! \brief Select a sub-song from a multi-song module
+ *
+ * \param mod The module handle to work on.
+ * \param subsong Index of the sub-song. -1 plays all sub-songs consecutively.
+ * \return 1 on success, 0 on failure.
+ * \sa openmpt_module_get_num_subsongs, openmpt_module_get_selected_subsong, openmpt_module_get_subsong_name
+ * \remarks Whether subsong -1 (all subsongs consecutively), subsong 0 or some other subsong is selected by default, is an implementation detail and subject to change. If you do not want to care about subsongs, it is recommended to just not call openmpt_module_select_subsong() at all.
+ */
+LIBOPENMPT_API int openmpt_module_select_subsong( openmpt_module * mod, int32_t subsong );
+/*! \brief Get currently selected sub-song from a multi-song module
+ *
+ * \param mod The module handle to work on.
+ * \return Currently selected sub-song. -1 for all subsongs consecutively, 0 or greater for the current sub-song index.
+ * \sa openmpt_module_get_num_subsongs, openmpt_module_select_subsong, openmpt_module_get_subsong_name
+ * \since 0.3.0
+ */
+LIBOPENMPT_API int32_t openmpt_module_get_selected_subsong( openmpt_module * mod );
+/*! \brief Set Repeat Count
+ *
+ * \param mod The module handle to work on.
+ * \param repeat_count Repeat Count
+ * - -1: repeat forever
+ * - 0: play once, repeat zero times (the default)
+ * - n>0: play once and repeat n times after that
+ * \return 1 on success, 0 on failure.
+ * \sa openmpt_module_get_repeat_count
+ */
+LIBOPENMPT_API int openmpt_module_set_repeat_count( openmpt_module * mod, int32_t repeat_count );
+/*! \brief Get Repeat Count
+ *
+ * \param mod The module handle to work on.
+ * \return Repeat Count
+ * - -1: repeat forever
+ * - 0: play once, repeat zero times (the default)
+ * - n>0: play once and repeat n times after that
+ * \sa openmpt_module_set_repeat_count
+ */
+LIBOPENMPT_API int32_t openmpt_module_get_repeat_count( openmpt_module * mod );
+
+/*! \brief approximate song duration
+ *
+ * \param mod The module handle to work on.
+ * \return Approximate duration of current sub-song in seconds.
+ */
+LIBOPENMPT_API double openmpt_module_get_duration_seconds( openmpt_module * mod );
+
+/*! \brief Set approximate current song position
+ *
+ * \param mod The module handle to work on.
+ * \param seconds Seconds to seek to. If seconds is out of range, the position gets set to song start or end respectively.
+ * \return Approximate new song position in seconds.
+ * \sa openmpt_module_get_position_seconds
+ */
+LIBOPENMPT_API double openmpt_module_set_position_seconds( openmpt_module * mod, double seconds );
+/*! \brief Get current song position
+ *
+ * \param mod The module handle to work on.
+ * \return Current song position in seconds.
+ * \sa openmpt_module_set_position_seconds
+ */
+LIBOPENMPT_API double openmpt_module_get_position_seconds( openmpt_module * mod );
+
+/*! \brief Set approximate current song position
+ *
+ * If order or row are out of range, to position is not modified and the current position is returned.
+ * \param mod The module handle to work on.
+ * \param order Pattern order number to seek to.
+ * \param row Pattern row number to seek to.
+ * \return Approximate new song position in seconds.
+ * \sa openmpt_module_set_position_seconds
+ * \sa openmpt_module_get_position_seconds
+ */
+LIBOPENMPT_API double openmpt_module_set_position_order_row( openmpt_module * mod, int32_t order, int32_t row );
+
+/*! \brief Get render parameter
+ *
+ * \param mod The module handle to work on.
+ * \param param Parameter to query. See \ref openmpt_module_render_param
+ * \param value Pointer to the variable that receives the current value of the parameter.
+ * \return 1 on success, 0 on failure (invalid param or value is NULL).
+ * \sa OPENMPT_MODULE_RENDER_MASTERGAIN_MILLIBEL
+ * \sa OPENMPT_MODULE_RENDER_STEREOSEPARATION_PERCENT
+ * \sa OPENMPT_MODULE_RENDER_INTERPOLATIONFILTER_LENGTH
+ * \sa OPENMPT_MODULE_RENDER_VOLUMERAMPING_STRENGTH
+ * \sa openmpt_module_set_render_param
+ */
+LIBOPENMPT_API int openmpt_module_get_render_param( openmpt_module * mod, int param, int32_t * value );
+/*! \brief Set render parameter
+ *
+ * \param mod The module handle to work on.
+ * \param param Parameter to set. See \ref openmpt_module_render_param
+ * \param value The value to set param to.
+ * \return 1 on success, 0 on failure (invalid param).
+ * \sa OPENMPT_MODULE_RENDER_MASTERGAIN_MILLIBEL
+ * \sa OPENMPT_MODULE_RENDER_STEREOSEPARATION_PERCENT
+ * \sa OPENMPT_MODULE_RENDER_INTERPOLATIONFILTER_LENGTH
+ * \sa OPENMPT_MODULE_RENDER_VOLUMERAMPING_STRENGTH
+ * \sa openmpt_module_get_render_param
+ */
+LIBOPENMPT_API int openmpt_module_set_render_param( openmpt_module * mod, int param, int32_t value );
+
+/*@{*/
+/*! \brief Render audio data
+ *
+ * \param mod The module handle to work on.
+ * \param samplerate Sample rate to render output. Should be in [8000,192000], but this is not enforced.
+ * \param count Number of audio frames to render per channel.
+ * \param mono Pointer to a buffer of at least count elements that receives the mono/center output.
+ * \return The number of frames actually rendered.
+ * \retval 0 The end of song has been reached.
+ * \remarks The output buffers are only written to up to the returned number of elements.
+ * \remarks You can freely switch between any of the "openmpt_module_read*" variants if you see a need to do so. libopenmpt tries to introduce as little switching annoyances as possible. Normally, you would only use a single one of these functions for rendering a particular module.
+ * \remarks It is recommended to use the floating point API because of the greater dynamic range and no implied clipping.
+ * \sa \ref libopenmpt_c_outputformat
+ */
+LIBOPENMPT_API size_t openmpt_module_read_mono( openmpt_module * mod, int32_t samplerate, size_t count, int16_t * mono );
+/*! \brief Render audio data
+ *
+ * \param mod The module handle to work on.
+ * \param samplerate Sample rate to render output. Should be in [8000,192000], but this is not enforced.
+ * \param count Number of audio frames to render per channel.
+ * \param left Pointer to a buffer of at least count elements that receives the left output.
+ * \param right Pointer to a buffer of at least count elements that receives the right output.
+ * \return The number of frames actually rendered.
+ * \retval 0 The end of song has been reached.
+ * \remarks The output buffers are only written to up to the returned number of elements.
+ * \remarks You can freely switch between any of the "openmpt_module_read*" variants if you see a need to do so. libopenmpt tries to introduce as little switching annoyances as possible. Normally, you would only use a single one of these functions for rendering a particular module.
+ * \remarks It is recommended to use the floating point API because of the greater dynamic range and no implied clipping.
+ * \sa \ref libopenmpt_c_outputformat
+ */
+LIBOPENMPT_API size_t openmpt_module_read_stereo( openmpt_module * mod, int32_t samplerate, size_t count, int16_t * left, int16_t * right );
+/*! \brief Render audio data
+ *
+ * \param mod The module handle to work on.
+ * \param samplerate Sample rate to render output. Should be in [8000,192000], but this is not enforced.
+ * \param count Number of audio frames to render per channel.
+ * \param left Pointer to a buffer of at least count elements that receives the left output.
+ * \param right Pointer to a buffer of at least count elements that receives the right output.
+ * \param rear_left Pointer to a buffer of at least count elements that receives the rear left output.
+ * \param rear_right Pointer to a buffer of at least count elements that receives the rear right output.
+ * \return The number of frames actually rendered.
+ * \retval 0 The end of song has been reached.
+ * \remarks The output buffers are only written to up to the returned number of elements.
+ * \remarks You can freely switch between any of the "openmpt_module_read*" variants if you see a need to do so. libopenmpt tries to introduce as little switching annoyances as possible. Normally, you would only use a single one of these functions for rendering a particular module.
+ * \remarks It is recommended to use the floating point API because of the greater dynamic range and no implied clipping.
+ * \sa \ref libopenmpt_c_outputformat
+ */
+LIBOPENMPT_API size_t openmpt_module_read_quad( openmpt_module * mod, int32_t samplerate, size_t count, int16_t * left, int16_t * right, int16_t * rear_left, int16_t * rear_right );
+/*! \brief Render audio data
+ *
+ * \param mod The module handle to work on.
+ * \param samplerate Sample rate to render output. Should be in [8000,192000], but this is not enforced.
+ * \param count Number of audio frames to render per channel.
+ * \param mono Pointer to a buffer of at least count elements that receives the mono/center output.
+ * \return The number of frames actually rendered.
+ * \retval 0 The end of song has been reached.
+ * \remarks The output buffers are only written to up to the returned number of elements.
+ * \remarks You can freely switch between any of the "openmpt_module_read*" variants if you see a need to do so. libopenmpt tries to introduce as little switching annoyances as possible. Normally, you would only use a single one of these functions for rendering a particular module.
+ * \remarks Floating point samples are in the [-1.0..1.0] nominal range. They are not clipped to that range though and thus might overshoot.
+ * \sa \ref libopenmpt_c_outputformat
+ */
+LIBOPENMPT_API size_t openmpt_module_read_float_mono( openmpt_module * mod, int32_t samplerate, size_t count, float * mono );
+/*! \brief Render audio data
+ *
+ * \param mod The module handle to work on.
+ * \param samplerate Sample rate to render output. Should be in [8000,192000], but this is not enforced.
+ * \param count Number of audio frames to render per channel.
+ * \param left Pointer to a buffer of at least count elements that receives the left output.
+ * \param right Pointer to a buffer of at least count elements that receives the right output.
+ * \return The number of frames actually rendered.
+ * \retval 0 The end of song has been reached.
+ * \remarks The output buffers are only written to up to the returned number of elements.
+ * \remarks You can freely switch between any of the "openmpt_module_read*" variants if you see a need to do so. libopenmpt tries to introduce as little switching annoyances as possible. Normally, you would only use a single one of these functions for rendering a particular module.
+ * \remarks Floating point samples are in the [-1.0..1.0] nominal range. They are not clipped to that range though and thus might overshoot.
+ * \sa \ref libopenmpt_c_outputformat
+ */
+LIBOPENMPT_API size_t openmpt_module_read_float_stereo( openmpt_module * mod, int32_t samplerate, size_t count, float * left, float * right );
+/*! \brief Render audio data
+ *
+ * \param mod The module handle to work on.
+ * \param samplerate Sample rate to render output. Should be in [8000,192000], but this is not enforced.
+ * \param count Number of audio frames to render per channel.
+ * \param left Pointer to a buffer of at least count elements that receives the left output.
+ * \param right Pointer to a buffer of at least count elements that receives the right output.
+ * \param rear_left Pointer to a buffer of at least count elements that receives the rear left output.
+ * \param rear_right Pointer to a buffer of at least count elements that receives the rear right output.
+ * \return The number of frames actually rendered.
+ * \retval 0 The end of song has been reached.
+ * \remarks The output buffers are only written to up to the returned number of elements.
+ * \remarks You can freely switch between any of the "openmpt_module_read*" variants if you see a need to do so. libopenmpt tries to introduce as little switching annoyances as possible. Normally, you would only use a single one of these functions for rendering a particular module.
+ * \remarks Floating point samples are in the [-1.0..1.0] nominal range. They are not clipped to that range though and thus might overshoot.
+ * \sa \ref libopenmpt_c_outputformat
+ */
+LIBOPENMPT_API size_t openmpt_module_read_float_quad( openmpt_module * mod, int32_t samplerate, size_t count, float * left, float * right, float * rear_left, float * rear_right );
+/*! \brief Render audio data
+ *
+ * \param mod The module handle to work on.
+ * \param samplerate Sample rate to render output. Should be in [8000,192000], but this is not enforced.
+ * \param count Number of audio frames to render per channel.
+ * \param interleaved_stereo Pointer to a buffer of at least count*2 elements that receives the interleaved stereo output in the order (L,R).
+ * \return The number of frames actually rendered.
+ * \retval 0 The end of song has been reached.
+ * \remarks The output buffers are only written to up to the returned number of elements.
+ * \remarks You can freely switch between any of the "openmpt_module_read*" variants if you see a need to do so. libopenmpt tries to introduce as little switching annoyances as possible. Normally, you would only use a single one of these functions for rendering a particular module.
+ * \remarks It is recommended to use the floating point API because of the greater dynamic range and no implied clipping.
+ * \sa \ref libopenmpt_c_outputformat
+ */
+LIBOPENMPT_API size_t openmpt_module_read_interleaved_stereo( openmpt_module * mod, int32_t samplerate, size_t count, int16_t * interleaved_stereo );
+/*! \brief Render audio data
+ *
+ * \param mod The module handle to work on.
+ * \param samplerate Sample rate to render output. Should be in [8000,192000], but this is not enforced.
+ * \param count Number of audio frames to render per channel.
+ * \param interleaved_quad Pointer to a buffer of at least count*4 elements that receives the interleaved suad surround output in the order (L,R,RL,RR).
+ * \return The number of frames actually rendered.
+ * \retval 0 The end of song has been reached.
+ * \remarks The output buffers are only written to up to the returned number of elements.
+ * \remarks You can freely switch between any of the "openmpt_module_read*" variants if you see a need to do so. libopenmpt tries to introduce as little switching annoyances as possible. Normally, you would only use a single one of these functions for rendering a particular module.
+ * \remarks It is recommended to use the floating point API because of the greater dynamic range and no implied clipping.
+ * \sa \ref libopenmpt_c_outputformat
+ */
+LIBOPENMPT_API size_t openmpt_module_read_interleaved_quad( openmpt_module * mod, int32_t samplerate, size_t count, int16_t * interleaved_quad );
+/*! \brief Render audio data
+ *
+ * \param mod The module handle to work on.
+ * \param samplerate Sample rate to render output. Should be in [8000,192000], but this is not enforced.
+ * \param count Number of audio frames to render per channel.
+ * \param interleaved_stereo Pointer to a buffer of at least count*2 elements that receives the interleaved stereo output in the order (L,R).
+ * \return The number of frames actually rendered.
+ * \retval 0 The end of song has been reached.
+ * \remarks The output buffers are only written to up to the returned number of elements.
+ * \remarks You can freely switch between any of the "openmpt_module_read*" variants if you see a need to do so. libopenmpt tries to introduce as little switching annoyances as possible. Normally, you would only use a single one of these functions for rendering a particular module.
+ * \remarks Floating point samples are in the [-1.0..1.0] nominal range. They are not clipped to that range though and thus might overshoot.
+ * \sa \ref libopenmpt_c_outputformat
+ */
+LIBOPENMPT_API size_t openmpt_module_read_interleaved_float_stereo( openmpt_module * mod, int32_t samplerate, size_t count, float * interleaved_stereo );
+/*! \brief Render audio data
+ *
+ * \param mod The module handle to work on.
+ * \param samplerate Sample rate to render output. Should be in [8000,192000], but this is not enforced.
+ * \param count Number of audio frames to render per channel.
+ * \param interleaved_quad Pointer to a buffer of at least count*4 elements that receives the interleaved suad surround output in the order (L,R,RL,RR).
+ * \return The number of frames actually rendered.
+ * \retval 0 The end of song has been reached.
+ * \remarks The output buffers are only written to up to the returned number of elements.
+ * \remarks You can freely switch between any of the "openmpt_module_read*" variants if you see a need to do so. libopenmpt tries to introduce as little switching annoyances as possible. Normally, you would only use a single one of these functions for rendering a particular module.
+ * \remarks Floating point samples are in the [-1.0..1.0] nominal range. They are not clipped to that range though and thus might overshoot.
+ * \sa \ref libopenmpt_c_outputformat
+*/
+LIBOPENMPT_API size_t openmpt_module_read_interleaved_float_quad( openmpt_module * mod, int32_t samplerate, size_t count, float * interleaved_quad );
+/*@}*/
+
+/*! \brief Get the list of supported metadata item keys
+ *
+ * \param mod The module handle to work on.
+ * \return Metadata item keys supported by openmpt_module_get_metadata, as a semicolon-separated list.
+ * \sa openmpt_module_get_metadata
+ */
+LIBOPENMPT_API const char * openmpt_module_get_metadata_keys( openmpt_module * mod );
+/*! \brief Get a metadata item value
+ *
+ * \param mod The module handle to work on.
+ * \param key Metadata item key to query. Use openmpt_module_get_metadata_keys to check for available keys.
+ * Possible keys are:
+ * - type: Module format extension (e.g. it)
+ * - type_long: Format name associated with the module format (e.g. Impulse Tracker)
+ * - originaltype: Module format extension (e.g. it) of the original module in case the actual type is a converted format (e.g. mo3 or gdm)
+ * - originaltype_long: Format name associated with the module format (e.g. Impulse Tracker) of the original module in case the actual type is a converted format (e.g. mo3 or gdm)
+ * - container: Container format the module file is embedded in, if any (e.g. umx)
+ * - container_long: Full container name if the module is embedded in a container (e.g. Unreal Music)
+ * - tracker: Tracker that was (most likely) used to save the module file, if known
+ * - artist: Author of the module
+ * - title: Module title
+ * - date: Date the module was last saved, in ISO-8601 format.
+ * - message: Song message. If the song message is empty or the module format does not support song messages, a list of instrument and sample names is returned instead.
+ * - message_raw: Song message. If the song message is empty or the module format does not support song messages, an empty string is returned.
+ * - warnings: A list of warnings that were generated while loading the module.
+ * \return The associated value for key.
+ * \sa openmpt_module_get_metadata_keys
+ */
+LIBOPENMPT_API const char * openmpt_module_get_metadata( openmpt_module * mod, const char * key );
+
+/*! \brief Get the current speed
+ *
+ * \param mod The module handle to work on.
+ * \return The current speed in ticks per row.
+ */
+LIBOPENMPT_API int32_t openmpt_module_get_current_speed( openmpt_module * mod );
+/*! \brief Get the current tempo
+ *
+ * \param mod The module handle to work on.
+ * \return The current tempo in tracker units. The exact meaning of this value depends on the tempo mode being used.
+ */
+LIBOPENMPT_API int32_t openmpt_module_get_current_tempo( openmpt_module * mod );
+/*! \brief Get the current order
+ *
+ * \param mod The module handle to work on.
+ * \return The current order at which the module is being played back.
+ */
+LIBOPENMPT_API int32_t openmpt_module_get_current_order( openmpt_module * mod );
+/*! \brief Get the current pattern
+ *
+ * \param mod The module handle to work on.
+ * \return The current pattern that is being played.
+ */
+LIBOPENMPT_API int32_t openmpt_module_get_current_pattern( openmpt_module * mod );
+/*! \brief Get the current row
+ *
+ * \param mod The module handle to work on.
+ * \return The current row at which the current pattern is being played.
+ */
+LIBOPENMPT_API int32_t openmpt_module_get_current_row( openmpt_module * mod );
+/*! \brief Get the current amount of playing channels.
+ *
+ * \param mod The module handle to work on.
+ * \return The amount of sample channels that are currently being rendered.
+ */
+LIBOPENMPT_API int32_t openmpt_module_get_current_playing_channels( openmpt_module * mod );
+
+/*! \brief Get an approximate indication of the channel volume.
+ *
+ * \param mod The module handle to work on.
+ * \param channel The channel whose volume should be retrieved.
+ * \return The approximate channel volume.
+ * \remarks The returned value is solely based on the note velocity and does not take the actual waveform of the playing sample into account.
+ */
+LIBOPENMPT_API float openmpt_module_get_current_channel_vu_mono( openmpt_module * mod, int32_t channel );
+/*! \brief Get an approximate indication of the channel volume on the front-left speaker.
+ *
+ * \param mod The module handle to work on.
+ * \param channel The channel whose volume should be retrieved.
+ * \return The approximate channel volume.
+ * \remarks The returned value is solely based on the note velocity and does not take the actual waveform of the playing sample into account.
+ */
+LIBOPENMPT_API float openmpt_module_get_current_channel_vu_left( openmpt_module * mod, int32_t channel );
+/*! \brief Get an approximate indication of the channel volume on the front-right speaker.
+ *
+ * \param mod The module handle to work on.
+ * \param channel The channel whose volume should be retrieved.
+ * \return The approximate channel volume.
+ * \remarks The returned value is solely based on the note velocity and does not take the actual waveform of the playing sample into account.
+ */
+LIBOPENMPT_API float openmpt_module_get_current_channel_vu_right( openmpt_module * mod, int32_t channel );
+/*! \brief Get an approximate indication of the channel volume on the rear-left speaker.
+ *
+ * \param mod The module handle to work on.
+ * \param channel The channel whose volume should be retrieved.
+ * \return The approximate channel volume.
+ * \remarks The returned value is solely based on the note velocity and does not take the actual waveform of the playing sample into account.
+ */
+LIBOPENMPT_API float openmpt_module_get_current_channel_vu_rear_left( openmpt_module * mod, int32_t channel );
+/*! \brief Get an approximate indication of the channel volume on the rear-right speaker.
+ *
+ * \param mod The module handle to work on.
+ * \param channel The channel whose volume should be retrieved.
+ * \return The approximate channel volume.
+ * \remarks The returned value is solely based on the note velocity and does not take the actual waveform of the playing sample into account.
+ */
+LIBOPENMPT_API float openmpt_module_get_current_channel_vu_rear_right( openmpt_module * mod, int32_t channel );
+
+/*! \brief Get the number of sub-songs
+ *
+ * \param mod The module handle to work on.
+ * \return The number of sub-songs in the module. This includes any "hidden" songs (songs that share the same sequence, but start at different order indices) and "normal" sub-songs or "sequences" (if the format supports them).
+ * \sa openmpt_module_get_subsong_name, openmpt_module_select_subsong, openmpt_module_get_selected_subsong
+ */
+LIBOPENMPT_API int32_t openmpt_module_get_num_subsongs( openmpt_module * mod );
+/*! \brief Get the number of pattern channels
+ *
+ * \param mod The module handle to work on.
+ * \return The number of pattern channels in the module. Not all channels do necessarily contain data.
+ * \remarks The number of pattern channels is completely independent of the number of output channels. libopenmpt can render modules in mono, stereo or quad surround, but the choice of which of the three modes to use must not be made based on the return value of this function, which may be any positive integer amount. Only use this function for informational purposes.
+ */
+LIBOPENMPT_API int32_t openmpt_module_get_num_channels( openmpt_module * mod );
+/*! \brief Get the number of orders
+ *
+ * \param mod The module handle to work on.
+ * \return The number of orders in the current sequence of the module.
+ */
+LIBOPENMPT_API int32_t openmpt_module_get_num_orders( openmpt_module * mod );
+/*! \brief Get the number of patterns
+ *
+ * \param mod The module handle to work on.
+ * \return The number of distinct patterns in the module.
+ */
+LIBOPENMPT_API int32_t openmpt_module_get_num_patterns( openmpt_module * mod );
+/*! \brief Get the number of instruments
+ *
+ * \param mod The module handle to work on.
+ * \return The number of instrument slots in the module. Instruments are a layer on top of samples, and are not supported by all module formats.
+ */
+LIBOPENMPT_API int32_t openmpt_module_get_num_instruments( openmpt_module * mod );
+/*! \brief Get the number of samples
+ *
+ * \param mod The module handle to work on.
+ * \return The number of sample slots in the module.
+ */
+LIBOPENMPT_API int32_t openmpt_module_get_num_samples( openmpt_module * mod );
+
+/*! \brief Get a sub-song name
+ *
+ * \param mod The module handle to work on.
+ * \param index The sub-song whose name should be retrieved
+ * \return The sub-song name.
+ * \sa openmpt_module_get_num_subsongs, openmpt_module_select_subsong, openmpt_module_get_selected_subsong
+ */
+LIBOPENMPT_API const char * openmpt_module_get_subsong_name( openmpt_module * mod, int32_t index );
+/*! \brief Get a channel name
+ *
+ * \param mod The module handle to work on.
+ * \param index The channel whose name should be retrieved
+ * \return The channel name.
+ * \sa openmpt_module_get_num_channels
+ */
+LIBOPENMPT_API const char * openmpt_module_get_channel_name( openmpt_module * mod, int32_t index );
+/*! \brief Get an order name
+ *
+ * \param mod The module handle to work on.
+ * \param index The order whose name should be retrieved
+ * \return The order name.
+ * \sa openmpt_module_get_num_orders
+ */
+LIBOPENMPT_API const char * openmpt_module_get_order_name( openmpt_module * mod, int32_t index );
+/*! \brief Get a pattern name
+ *
+ * \param mod The module handle to work on.
+ * \param index The pattern whose name should be retrieved
+ * \return The pattern name.
+ * \sa openmpt_module_get_num_patterns
+ */
+LIBOPENMPT_API const char * openmpt_module_get_pattern_name( openmpt_module * mod, int32_t index );
+/*! \brief Get an instrument name
+ *
+ * \param mod The module handle to work on.
+ * \param index The instrument whose name should be retrieved
+ * \return The instrument name.
+ * \sa openmpt_module_get_num_instruments
+ */
+LIBOPENMPT_API const char * openmpt_module_get_instrument_name( openmpt_module * mod, int32_t index );
+/*! \brief Get a sample name
+ *
+ * \param mod The module handle to work on.
+ * \param index The sample whose name should be retrieved
+ * \return The sample name.
+ * \sa openmpt_module_get_num_samples
+ */
+LIBOPENMPT_API const char * openmpt_module_get_sample_name( openmpt_module * mod, int32_t index );
+
+/*! \brief Get pattern at order position
+ *
+ * \param mod The module handle to work on.
+ * \param order The order item whose pattern index should be retrieved.
+ * \return The pattern index found at the given order position of the current sequence.
+ */
+LIBOPENMPT_API int32_t openmpt_module_get_order_pattern( openmpt_module * mod, int32_t order );
+/*! \brief Get the number of rows in a pattern
+ *
+ * \param mod The module handle to work on.
+ * \param pattern The pattern whose row count should be retrieved.
+ * \return The number of rows in the given pattern. If the pattern does not exist, 0 is returned.
+ */
+LIBOPENMPT_API int32_t openmpt_module_get_pattern_num_rows( openmpt_module * mod, int32_t pattern );
+
+/*! \brief Get raw pattern content
+ *
+ * \param mod The module handle to work on.
+ * \param pattern The pattern whose data should be retrieved.
+ * \param row The row from which the data should be retrieved.
+ * \param channel The channel from which the data should be retrieved.
+ * \param command The cell index at which the data should be retrieved. See \ref openmpt_module_command_index
+ * \return The internal, raw pattern data at the given pattern position.
+ */
+LIBOPENMPT_API uint8_t openmpt_module_get_pattern_row_channel_command( openmpt_module * mod, int32_t pattern, int32_t row, int32_t channel, int command );
+
+/*! \brief Get formatted (human-readable) pattern content
+ *
+ * \param mod The module handle to work on.
+ * \param pattern The pattern whose data should be retrieved.
+ * \param row The row from which the data should be retrieved.
+ * \param channel The channel from which the data should be retrieved.
+ * \param command The cell index at which the data should be retrieved.
+ * \return The formatted pattern data at the given pattern position. See \ref openmpt_module_command_index
+ * \sa openmpt_module_highlight_pattern_row_channel_command
+ */
+LIBOPENMPT_API const char * openmpt_module_format_pattern_row_channel_command( openmpt_module * mod, int32_t pattern, int32_t row, int32_t channel, int command );
+/*! \brief Get highlighting information for formatted pattern content
+ *
+ * \param mod The module handle to work on.
+ * \param pattern The pattern whose data should be retrieved.
+ * \param row The row from which the data should be retrieved.
+ * \param channel The channel from which the data should be retrieved.
+ * \param command The cell index at which the data should be retrieved. See \ref openmpt_module_command_index
+ * \return The highlighting string for the formatted pattern data as retrieved by openmpt_module_get_pattern_row_channel_command at the given pattern position.
+ * \remarks The returned string will map each character position of the string returned by openmpt_module_get_pattern_row_channel_command to a highlighting instruction.
+ * Possible highlighting characters are:
+ * - " " : empty/space
+ * - "." : empty/dot
+ * - "n" : generic note
+ * - "m" : special note
+ * - "i" : generic instrument
+ * - "u" : generic volume column effect
+ * - "v" : generic volume column parameter
+ * - "e" : generic effect column effect
+ * - "f" : generic effect column parameter
+ * \sa openmpt_module_get_pattern_row_channel_command
+ */
+LIBOPENMPT_API const char * openmpt_module_highlight_pattern_row_channel_command( openmpt_module * mod, int32_t pattern, int32_t row, int32_t channel, int command );
+
+/*! \brief Get formatted (human-readable) pattern content
+ *
+ * \param mod The module handle to work on.
+ * \param pattern The pattern whose data should be retrieved.
+ * \param row The row from which the data should be retrieved.
+ * \param channel The channel from which the data should be retrieved.
+ * \param width The maximum number of characters the string should contain. 0 means no limit.
+ * \param pad If true, the string will be resized to the exact length provided in the width parameter.
+ * \return The formatted pattern data at the given pattern position.
+ * \sa openmpt_module_highlight_pattern_row_channel
+ */
+LIBOPENMPT_API const char * openmpt_module_format_pattern_row_channel( openmpt_module * mod, int32_t pattern, int32_t row, int32_t channel, size_t width, int pad );
+/*! \brief Get highlighting information for formatted pattern content
+ *
+ * \param mod The module handle to work on.
+ * \param pattern The pattern whose data should be retrieved.
+ * \param row The row from which the data should be retrieved.
+ * \param channel The channel from which the data should be retrieved.
+ * \param width The maximum number of characters the string should contain. 0 means no limit.
+ * \param pad If true, the string will be resized to the exact length provided in the width parameter.
+ * \return The highlighting string for the formatted pattern data as retrieved by openmpt_module_format_pattern_row_channel at the given pattern position.
+ * \sa openmpt_module_format_pattern_row_channel
+ */
+LIBOPENMPT_API const char * openmpt_module_highlight_pattern_row_channel( openmpt_module * mod, int32_t pattern, int32_t row, int32_t channel, size_t width, int pad );
+
+/*! \brief Retrieve supported ctl keys
+ *
+ * \param mod The module handle to work on.
+ * \return A semicolon-separated list containing all supported ctl keys.
+ * \remarks Currently supported ctl values are:
+ * - load.skip_samples: Set to "1" to avoid loading samples into memory
+ * - load.skip_patterns: Set to "1" to avoid loading patterns into memory
+ * - load.skip_plugins: Set to "1" to avoid loading plugins
+ * - load.skip_subsongs_init: Set to "1" to avoid pre-initializing sub-songs. Skipping results in faster module loading but slower seeking.
+ * - seek.sync_samples: Set to "1" to sync sample playback when using openmpt_module_set_position_seconds or openmpt_module_set_position_order_row.
+ * - subsong: The current subsong. Setting it has identical semantics as openmpt_module_select_subsong(), getting it returns the currently selected subsong.
+ * - play.at_end: Chooses the behaviour when the end of song is reached:
+ * - "fadeout": Fades the module out for a short while. Subsequent reads after the fadeout will return 0 rendered frames.
+ * - "continue": Returns 0 rendered frames when the song end is reached. Subsequent reads will continue playing from the song start or loop start.
+ * - "stop": Returns 0 rendered frames when the song end is reached. Subsequent reads will return 0 rendered frames.
+ * - play.tempo_factor: Set a floating point tempo factor. "1.0" is the default tempo.
+ * - play.pitch_factor: Set a floating point pitch factor. "1.0" is the default pitch.
+ * - render.resampler.emulate_amiga: Set to "1" to enable the Amiga resampler for Amiga modules. This emulates the sound characteristics of the Paula chip and overrides the selected interpolation filter. Non-Amiga module formats are not affected by this setting.
+ * - render.opl.volume_factor: Set volume factor applied to synthesized OPL sounds, relative to the default OPL volume.
+ * - dither: Set the dither algorithm that is used for the 16 bit versions of openmpt_module_read. Supported values are:
+ * - 0: No dithering.
+ * - 1: Default mode. Chosen by OpenMPT code, might change.
+ * - 2: Rectangular, 0.5 bit depth, no noise shaping (original ModPlug Tracker).
+ * - 3: Rectangular, 1 bit depth, simple 1st order noise shaping
+ */
+LIBOPENMPT_API const char * openmpt_module_get_ctls( openmpt_module * mod );
+/*! \brief Get current ctl value
+ *
+ * \param mod The module handle to work on.
+ * \param ctl The ctl key whose value should be retrieved.
+ * \return The associated ctl value, or NULL on failure.
+ * \sa openmpt_module_get_ctls
+ */
+LIBOPENMPT_API const char * openmpt_module_ctl_get( openmpt_module * mod, const char * ctl );
+/*! \brief Set ctl value
+ *
+ * \param mod The module handle to work on.
+ * \param ctl The ctl key whose value should be set.
+ * \param value The value that should be set.
+ * \return 1 if successful, 0 in case the value is not sensible (e.g. negative tempo factor) or the ctl is not recognized.
+ * \sa openmpt_module_get_ctls
+ */
+LIBOPENMPT_API int openmpt_module_ctl_set( openmpt_module * mod, const char * ctl, const char * value );
+
+/* remember to add new functions to both C and C++ interfaces and to increase OPENMPT_API_VERSION_MINOR */
+
+#ifdef __cplusplus
+}
+#endif
+
+/*!
+ * @}
+ */
+
+#endif /* LIBOPENMPT_H */
+
diff --git a/libs/libopenmpt/inc/libopenmpt/libopenmpt.hpp b/libs/libopenmpt/inc/libopenmpt/libopenmpt.hpp
new file mode 100644
index 000000000..55097f830
--- /dev/null
+++ b/libs/libopenmpt/inc/libopenmpt/libopenmpt.hpp
@@ -0,0 +1,1015 @@
+/*
+ * libopenmpt.hpp
+ * --------------
+ * Purpose: libopenmpt public c++ interface
+ * Notes : (currently none)
+ * Authors: OpenMPT Devs
+ * The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
+ */
+
+#ifndef LIBOPENMPT_HPP
+#define LIBOPENMPT_HPP
+
+#include "libopenmpt_config.h"
+
+#include
+#include
+#include
+#include