diff --git a/.travis.yml b/.travis.yml
index a9f4ddfb4..3166ed783 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -70,8 +70,23 @@ matrix:
               - p7zip-full
               - gcc-7
           compiler: gcc-7
-          env: WFLAGS="-Wno-tautological-compare -Wno-error=implicit-fallthrough -Wimplicit-fallthrough=3"
+          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
+        - 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)
@@ -212,6 +227,7 @@ matrix:
       - compiler: clang-3.9
       - compiler: clang-4.0
       - compiler: clang-5.0
+      - compiler: gcc-8
 
 cache:
   apt: true
diff --git a/README.md b/README.md
index d16071454..7d92ab303 100644
--- a/README.md
+++ b/README.md
@@ -13,8 +13,6 @@
 - libupnp (Linux/OS X only)
 - libgme (Linux/OS X only)
 
-Warning: 64-bit builds are not netgame compatible with 32-bit builds. Use at your own risk.
-
 ## Compiling
 
 See [SRB2 Wiki/Source code compiling](http://wiki.srb2.org/wiki/Source_code_compiling)
diff --git a/SRB2.cbp b/SRB2.cbp
index 74ec96c6e..5aa623fa8 100644
--- a/SRB2.cbp
+++ b/SRB2.cbp
@@ -1174,6 +1174,39 @@ HW3SOUND for 3D hardware sound  support
 			<Option target="Debug Mingw64/DirectX" />
 			<Option target="Release Mingw64/DirectX" />
 		</Unit>
+		<Unit filename="src/hardware/hw_clip.c">
+			<Option compilerVar="CC" />
+			<Option target="Debug Native/SDL" />
+			<Option target="Release Native/SDL" />
+			<Option target="Debug Mingw/SDL" />
+			<Option target="Release Mingw/SDL" />
+			<Option target="Debug Mingw/DirectX" />
+			<Option target="Release Mingw/DirectX" />
+			<Option target="Debug Any/Dummy" />
+			<Option target="Release Any/Dummy" />
+			<Option target="Debug Linux/SDL" />
+			<Option target="Release Linux/SDL" />
+			<Option target="Debug Mingw64/SDL" />
+			<Option target="Release Mingw64/SDL" />
+			<Option target="Debug Mingw64/DirectX" />
+			<Option target="Release Mingw64/DirectX" />
+		</Unit>
+		<Unit filename="src/hardware/hw_clip.h">
+			<Option target="Debug Native/SDL" />
+			<Option target="Release Native/SDL" />
+			<Option target="Debug Mingw/SDL" />
+			<Option target="Release Mingw/SDL" />
+			<Option target="Debug Mingw/DirectX" />
+			<Option target="Release Mingw/DirectX" />
+			<Option target="Debug Any/Dummy" />
+			<Option target="Release Any/Dummy" />
+			<Option target="Debug Linux/SDL" />
+			<Option target="Release Linux/SDL" />
+			<Option target="Debug Mingw64/SDL" />
+			<Option target="Release Mingw64/SDL" />
+			<Option target="Debug Mingw64/DirectX" />
+			<Option target="Release Mingw64/DirectX" />
+		</Unit>
 		<Unit filename="src/hardware/hw_data.h">
 			<Option target="Debug Native/SDL" />
 			<Option target="Release Native/SDL" />
diff --git a/assets/.gitignore b/assets/.gitignore
index 37bb465dc..9ed61ca1a 100644
--- a/assets/.gitignore
+++ b/assets/.gitignore
@@ -1,2 +1,5 @@
 *
 *.*
+!README.txt
+!LICENSE.txt
+!LICENSE-3RD-PARTY.txt
\ No newline at end of file
diff --git a/assets/CMakeLists.txt b/assets/CMakeLists.txt
index 292e184c7..6edb3df13 100644
--- a/assets/CMakeLists.txt
+++ b/assets/CMakeLists.txt
@@ -8,6 +8,9 @@ set(SRB2_ASSET_ALL
 	${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
 )
 
 set(SRB2_ASSET_HASHED
diff --git a/assets/LICENSE-3RD-PARTY.txt b/assets/LICENSE-3RD-PARTY.txt
new file mode 100644
index 000000000..42ea20e96
--- /dev/null
+++ b/assets/LICENSE-3RD-PARTY.txt
@@ -0,0 +1,1710 @@
+--------------------------------------------------------------------------------
+                        3-Clause BSD License
+        applies to:
+        - MiniUPnPc
+          Copyright (c) 2005-2011, Thomas BERNARD
+          All rights reserved.
+          http://miniupnp.free.fr
+--------------------------------------------------------------------------------
+
+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.
+    * The name of the author may not 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 COPYRIGHT OWNER 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.
+
+--------------------------------------------------------------------------------
+                        curl License
+        applies to:
+        - curl
+          Copyright (c) 1996 - 2018, Daniel Stenberg, daniel@haxx.se,
+          and many contributors, see the THANKS file.
+          https://curl.haxx.se
+--------------------------------------------------------------------------------
+
+All rights reserved.
+
+Permission to use, copy, modify, and distribute this software for any purpose
+with or without fee is hereby granted, provided that the above copyright notice
+and this permission notice appear in all copies.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN
+NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
+OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of a copyright holder shall not be
+used in advertising or otherwise to promote the sale, use or other dealings in
+this Software without prior written authorization of the copyright holder.
+
+--------------------------------------------------------------------------------
+                        FMOD End User License Agreement
+        applies to:
+        - FMOD Ex
+          Copyright (c), Firelight Technologies Pty, Ltd. 2004-2018.
+          https://www.fmod.com
+--------------------------------------------------------------------------------
+
+This FMOD End User Licence Agreement (EULA) is a legal agreement between you and Firelight
+Technologies Pty Ltd (ACN 099 182 448) (us or we) and governs your use of FMOD Studio and FMOD
+Engine software (FMOD).
+
+1. GRANT OF LICENCE
+This EULA grants you the right to use FMOD, in a software application (Product), for
+personal (hobbyist), educational (students and teachers) or Non-Commercial use only,
+subject to the following:
+i)	Non-Commercial use does not involve any form of monetisation, sponsorship
+or promotion.
+ii)	FMOD is distributed as integrated into a Product only;
+iii)	FMOD is not distributed as part of any Commercial Product or service;
+iv)	FMOD is not distributed as part of a game engine or tool set;
+v)	FMOD is not used in any Commercial enterprise or for any Commercial
+production or subcontracting, except for the purposes of Evaluation or
+Development of a Commercial Product;
+vi)	Product includes attribution in accordance with Clause 3;
+
+2.	OTHER USE
+For all Commercial use, and any Non Commercial use not permitted by this license, a
+separate license is required. Refer to www.fmod.com/licensing for information.
+
+3.	CREDITS AND LOGO
+All Products require an in game credit line which must include the words "FMOD" or
+"FMOD Studio" (if applicable) and "Firelight Technologies Pty Ltd". This is non
+negotiable. Refer to www.fmod.com/licensing for examples. All products require a
+logo to be presented during start up of the application, before encountering any
+menus or interactivity. See www.fmod.com/licensing for logo information. The user
+has the option to 'buy out'	the requirement to have a logo at the start of the
+product.
+
+4.	INTELLECTUAL PROPERTY RIGHTS
+a)	We are and remain at all times the owner of FMOD (including all intellectual
+property rights in or to the Software). For the avoidance of doubt, nothing in
+this EULA may be deemed to grant or assign to you any proprietary or ownership
+interest or intellectual property rights in or to FMOD other than the rights
+licensed pursuant to clause 1.
+b)	You acknowledge and agree that you have no right, title or interest in and to the
+intellectual property rights in FMOD.
+
+5.	SECURITY AND RISK
+You are responsible for protecting FMOD and any related materials at all times from
+unauthorised access, use or damage.
+
+6.	WARRANTY AND LIMITATION OF LIABILITY
+a)	FMOD is provided by us "as is" and, to the maximum extent permitted by law,
+any express or implied warranties of any kind, including (but not limited to) all
+implied warranties of merchantability and fitness for a particular purpose are
+disclaimed.
+b)	In no event shall we (and our employees, contractors and subcontractors),
+developers and contributors be liable for any direct, special, indirect or
+consequential damages whatsoever resulting from loss of use of data or profits,
+whether in an action of contract, negligence or other tortious conduct, arising
+out of or in connection with the use or performance FMOD.
+
+7.	OGG VORBIS CODEC
+a)	FMOD uses the Ogg Vorbis codec.
+b)	(c) 2002, Xiph.Org Foundation
+c)	Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+i)	Redistributions of source code must retain the above copyright notice, the
+list of conditions and the following disclaimer.
+ii)	Redistributions in binary form must reproduce the above copyright notice,
+this list of conditions and the following disclaimer in the documentation
+and/or other material provided with the distribution.
+iii)	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.
+d)	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, INCIDENTIAL, 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
+NEGLIENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+8.	GOOGLE VR (GVR)
+FMOD includes Google VR, licensed under the Apache Licence, Version 2.0 (the Licence);
+you may not use this file except in compliance with the License. You may obtain a copy of
+the License at:
+http://www.apache.org/licenses/LICENSE-2.0
+Unless required by applicable law or agreed to in writing, software distributed under the
+License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
+either express or implied. See the License for the specific language governing permissions
+and limitations under the License.
+
+9. ANDROID PLATFORM CODE
+Copyright (C) 2010 The Android Open Source Project 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.
+
+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
+COPYRIGHT OWNER 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.
+
+10.	AUDIOGAMING AUDIOMOTORS DEMO CONTENT
+AudioGaming AudioMotors Demo Engine.agp is provided for evaluation purposes
+only and is not to be redistributed. To create your own engine content, you
+will need AudioMotors V2 Pro. A trial version be found at
+http://store.audiogaming.net/content/audiomotors-v2-pro-trial. For access to
+the full version, contact sales@fmod.com.
+
+© 2018 Firelight Technologies Pty Ltd.
+
+--------------------------------------------------------------------------------
+                        GCC Runtime Library Exception, Version 3.1
+        applies to:
+        - GCC Runtime Library
+          Copyright (C) Free Software Foundation, Inc.
+          https://www.gnu.org/software/gcc/
+--------------------------------------------------------------------------------
+
+GCC RUNTIME LIBRARY EXCEPTION Version 3.1, 31 March 2009
+
+Copyright © 2009 Free Software Foundation, Inc. <https://fsf.org/>
+
+Everyone is permitted to copy and distribute verbatim copies of this license
+document, but changing it is not allowed.
+
+This GCC Runtime Library Exception ("Exception") is an additional permission
+under section 7 of the GNU General Public License, version 3 ("GPLv3"). It
+applies to a given file (the "Runtime Library") that bears a notice placed by
+the copyright holder of the file stating that the file is governed by GPLv3
+along with this Exception.
+
+When you use GCC to compile a program, GCC may combine portions of certain GCC
+header files and runtime libraries with the compiled program. The purpose of
+this Exception is to allow compilation of non-GPL (including proprietary)
+programs to use, in this way, the header files and runtime libraries covered by
+this Exception.
+
+0. Definitions. A file is an "Independent Module" if it either requires the
+Runtime Library for execution after a Compilation Process, or makes use of an
+interface provided by the Runtime Library, but is not otherwise based on the
+Runtime Library.
+
+"GCC" means a version of the GNU Compiler Collection, with or without
+modifications, governed by version 3 (or a specified later version) of the GNU
+General Public License (GPL) with the option of using any subsequent versions
+published by the FSF.
+
+"GPL-compatible Software" is software whose conditions of propagation,
+modification and use would permit combination with GCC in accord with the
+license of GCC.
+
+"Target Code" refers to output from any compiler for a real or virtual target
+processor architecture, in executable form or suitable for input to an
+assembler, loader, linker and/or execution phase. Notwithstanding that, Target
+Code does not include data in any format that is used as a compiler
+intermediate representation, or used for producing a compiler intermediate
+representation.
+
+The "Compilation Process" transforms code entirely represented in
+non-intermediate languages designed for human-written code, and/or in Java
+Virtual Machine byte code, into Target Code. Thus, for example, use of source
+code generators and preprocessors need not be considered part of the
+Compilation Process, since the Compilation Process can be understood as
+starting with the output of the generators or preprocessors.
+
+A Compilation Process is "Eligible" if it is done using GCC, alone or with
+other GPL-compatible software, or if it is done without using any work based on
+GCC. For example, using non-GPL-compatible Software to optimize any GCC
+intermediate representations would not qualify as an Eligible Compilation
+Process.
+
+1. Grant of Additional Permission. You have permission to propagate a work of
+Target Code formed by combining the Runtime Library with Independent Modules,
+even if such propagation would otherwise violate the terms of GPLv3, provided
+that all Target Code was generated by Eligible Compilation Processes. You may
+then convey such a combination under terms of your choice, consistent with the
+licensing of the Independent Modules.
+
+2. No Weakening of GCC Copyleft. The availability of this Exception does not
+imply any general presumption that third-party software is unaffected by the
+copyleft requirements of the license of GCC.
+
+--------------------------------------------------------------------------------
+                        GNU General Public License, Version 3
+        applies to:
+        - GCC Runtime Library
+          Copyright (C) Free Software Foundation, Inc.
+          https://www.gnu.org/software/gcc/
+--------------------------------------------------------------------------------
+
+                    GNU GENERAL PUBLIC LICENSE
+                       Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
+ 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.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    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 <https://www.gnu.org/licenses/>.
+
+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:
+
+    <program>  Copyright (C) <year>  <name of author>
+    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
+<https://www.gnu.org/licenses/>.
+
+  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
+<https://www.gnu.org/licenses/why-not-lgpl.html>.
+
+--------------------------------------------------------------------------------
+                        GNU Lesser General Public License, Version 2.1
+        applies to:
+        - Game_Music_Emu
+          Shay Green <gblargg@gmail.com>
+          http://www.slack.net/~ant/
+
+        - libintl
+          Copyright (C) 1995-2018 Free Software Foundation, Inc.
+          https://www.gnu.org/software/gettext/
+
+        - mpg123
+          Copyright (c) 1995-2013 by Michael Hipp and others,
+          free software under the terms of the LGPL v2.1
+          https://www.mpg123.de
+--------------------------------------------------------------------------------
+
+		  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
+
+           How to Apply These Terms to Your New Libraries
+
+  If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change.  You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+  To apply these terms, attach the following notices to the library.  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.
+
+    <one line to give the library's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This library 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 library 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 library; 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.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the
+  library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+  <signature of Ty Coon>, 1 April 1990
+  Ty Coon, President of Vice
+
+That's all there is to it!
+
+--------------------------------------------------------------------------------
+                  libpng License
+        applies to:
+        - libpng
+          Copyright (c) 2000-2002, 2004, 2006-2018 Glenn Randers-Pehrson
+          http://www.libpng.org/pub/png/libpng.html
+--------------------------------------------------------------------------------
+
+This copy of the libpng notices is provided for your convenience.  In case of
+any discrepancy between this copy and the notices in the file png.h that is
+included in the libpng distribution, the latter shall prevail.
+
+COPYRIGHT NOTICE, DISCLAIMER, and LICENSE:
+
+If you modify libpng you may insert additional notices immediately following
+this sentence.
+
+This code is released under the libpng license.
+
+libpng versions 1.0.7, July 1, 2000 through 1.6.35, July 15, 2018 are
+Copyright (c) 2000-2002, 2004, 2006-2018 Glenn Randers-Pehrson, are
+derived from libpng-1.0.6, and are distributed according to the same
+disclaimer and license as libpng-1.0.6 with the following individuals
+added to the list of Contributing Authors:
+
+   Simon-Pierre Cadieux
+   Eric S. Raymond
+   Mans Rullgard
+   Cosmin Truta
+   Gilles Vollant
+   James Yu
+   Mandar Sahastrabuddhe
+   Google Inc.
+   Vadim Barkov
+
+and with the following additions to the disclaimer:
+
+   There is no warranty against interference with your enjoyment of the
+   library or against infringement.  There is no warranty that our
+   efforts or the library will fulfill any of your particular purposes
+   or needs.  This library is provided with all faults, and the entire
+   risk of satisfactory quality, performance, accuracy, and effort is with
+   the user.
+
+Some files in the "contrib" directory and some configure-generated
+files that are distributed with libpng have other copyright owners and
+are released under other open source licenses.
+
+libpng versions 0.97, January 1998, through 1.0.6, March 20, 2000, are
+Copyright (c) 1998-2000 Glenn Randers-Pehrson, are derived from
+libpng-0.96, and are distributed according to the same disclaimer and
+license as libpng-0.96, with the following individuals added to the list
+of Contributing Authors:
+
+   Tom Lane
+   Glenn Randers-Pehrson
+   Willem van Schaik
+
+libpng versions 0.89, June 1996, through 0.96, May 1997, are
+Copyright (c) 1996-1997 Andreas Dilger, are derived from libpng-0.88,
+and are distributed according to the same disclaimer and license as
+libpng-0.88, with the following individuals added to the list of
+Contributing Authors:
+
+   John Bowler
+   Kevin Bracey
+   Sam Bushell
+   Magnus Holmgren
+   Greg Roelofs
+   Tom Tanner
+
+Some files in the "scripts" directory have other copyright owners
+but are released under this license.
+
+libpng versions 0.5, May 1995, through 0.88, January 1996, are
+Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
+
+For the purposes of this copyright and license, "Contributing Authors"
+is defined as the following set of individuals:
+
+   Andreas Dilger
+   Dave Martindale
+   Guy Eric Schalnat
+   Paul Schmidt
+   Tim Wegner
+
+The PNG Reference Library is supplied "AS IS".  The Contributing Authors
+and Group 42, Inc. disclaim all warranties, expressed or implied,
+including, without limitation, the warranties of merchantability and of
+fitness for any purpose.  The Contributing Authors and Group 42, Inc.
+assume no liability for direct, indirect, incidental, special, exemplary,
+or consequential damages, which may result from the use of the PNG
+Reference Library, even if advised of the possibility of such damage.
+
+Permission is hereby granted to use, copy, modify, and distribute this
+source code, or portions hereof, for any purpose, without fee, subject
+to the following restrictions:
+
+  1. The origin of this source code must not be misrepresented.
+
+  2. Altered versions must be plainly marked as such and must not
+     be misrepresented as being the original source.
+
+  3. This Copyright notice may not be removed or altered from any
+     source or altered source distribution.
+
+The Contributing Authors and Group 42, Inc. specifically permit, without
+fee, and encourage the use of this source code as a component to
+supporting the PNG file format in commercial products.  If you use this
+source code in a product, acknowledgment is not required but would be
+appreciated.
+
+END OF COPYRIGHT NOTICE, DISCLAIMER, and LICENSE.
+
+TRADEMARK:
+
+The name "libpng" has not been registered by the Copyright owner
+as a trademark in any jurisdiction.  However, because libpng has
+been distributed and maintained world-wide, continually since 1995,
+the Copyright owner claims "common-law trademark protection" in any
+jurisdiction where common-law trademark is recognized.
+
+OSI CERTIFICATION:
+
+Libpng is OSI Certified Open Source Software.  OSI Certified Open Source is
+a certification mark of the Open Source Initiative. OSI has not addressed
+the additional disclaimers inserted at version 1.0.7.
+
+EXPORT CONTROL:
+
+The Copyright owner believes that the Export Control Classification
+Number (ECCN) for libpng is EAR99, which means not subject to export
+controls or International Traffic in Arms Regulations (ITAR) because
+it is open source, publicly available software, that does not contain
+any encryption software.  See the EAR, paragraphs 734.3(b)(3) and
+734.7(b).
+
+Glenn Randers-Pehrson
+glennrp at users.sourceforge.net
+July 15, 2018
+
+--------------------------------------------------------------------------------
+                  New BSD License
+        applies to:
+        - FLAC
+          Copyright (C) 2000-2009  Josh Coalson
+          Copyright (C) 2011-2016  Xiph.Org Foundation
+          https://xiph.org/flac/api/
+
+        - Vorbis
+          Copyright (c) 2002-2008 Xiph.org Foundation
+          https://xiph.org/vorbis/
+
+        - Opus
+          Copyright 2001-2011 Xiph.Org, Skype Limited, Octasic,
+                    Jean-Marc Valin, Timothy B. Terriberry,
+                    CSIRO, Gregory Maxwell, Mark Borgerding,
+                    Erik de Castro Lopo
+          https://opus-codec.org
+
+        - Opus File
+          Copyright (c) 1994-2013 Xiph.Org Foundation and contributors
+          https://opus-codec.org
+--------------------------------------------------------------------------------
+
+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.
+
+[ For FLAC, Vorbis, and Opus File
+- 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.
+]
+
+[ For Opus
+- Neither the name of Internet Society, IETF or IETF Trust, nor the
+names of specific 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.
+
+--------------------------------------------------------------------------------
+                  Public Domain
+        applies to:
+        - win_iconv
+          Yukihiro Nakadaira <yukihiro.nakadaira@gmail.com>
+          win_iconv is placed in the public domain.
+          https://github.com/win-iconv/win-iconv
+
+        - libmodplug
+          ModPlug-XMMS and libmodplug are now in the public domain.
+          http://modplug-xmms.sourceforge.net
+--------------------------------------------------------------------------------
+
+--------------------------------------------------------------------------------
+                        zlib License
+        applies to:
+        - Simple DirectMedia Layer
+          Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+          https://www.libsdl.org/hg.php
+
+        - SDL_mixer:  An audio mixer library based on the SDL library
+          Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+          https://www.libsdl.org/projects/SDL_mixer/
+
+        - zlib
+          Copyright (C) 1995-2017 Jean-loup Gailly and Mark Adler
+          https://zlib.net
+--------------------------------------------------------------------------------
+
+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/assets/LICENSE.txt b/assets/LICENSE.txt
new file mode 100644
index 000000000..d159169d1
--- /dev/null
+++ b/assets/LICENSE.txt
@@ -0,0 +1,339 @@
+                    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.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    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.
+
+  <signature of Ty Coon>, 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/assets/README.txt b/assets/README.txt
new file mode 100644
index 000000000..37f7d8f29
--- /dev/null
+++ b/assets/README.txt
@@ -0,0 +1,51 @@
+SONIC ROBO BLAST 2
+
+Sonic Robo Blast 2 (SRB2) is a 3D Sonic the Hedgehog fangame based on a
+modified version of Doom Legacy.
+
+LICENSE
+
+The source code for SRB2 is licensed under the GNU General Public
+License, Version 2. See LICENSE.txt for the full text of this license.
+
+SRB2 uses various third-party libraries, including SDL, SDL Mixer, and
+their dependencies. See LICENSE-3RD-PARTY.txt for the licenses of these
+libraries.
+
+SOURCE CODE
+
+You may obtain the source code for SRB2, including the source code for
+specific version releases, at the following web sites:
+
+STJr GitLab:
+https://git.magicalgirl.moe/STJr/SRB2
+
+GitHub:
+https://github.com/STJr/SRB2
+
+CONTACT
+
+You may contact Sonic Team Junior via the following web sites:
+
+SRB2.ORG:
+https://www.srb2.org
+
+SRB2 Message Board:
+https://mb.srb2.org
+
+SRB2 Official Discord:
+https://discord.gg/pYDXzpX
+
+COPYRIGHT AND DISCLAIMER
+
+Design and content on SRB2 is copyright 1998-2018 by Sonic Team Junior.
+All non-original material on SRB2.ORG is copyrighted by their
+respective owners, and no copyright infringement is intended. The owner
+of the SRB2.ORG domain is only acting as an ISP, and is therefore not
+responsible for any content on SRB2.ORG under the 1998 DMCA. This
+site, its webmaster, and its staff make no profit whatsoever (in fact,
+we lose money). Sonic Team Junior assumes no responsibility for the
+content on any Sonic Team Junior fan sites.
+
+Sonic Team Junior is in no way affiliated with SEGA or Sonic Team. We do
+not claim ownership of any of SEGA's intellectual property used in SRB2.
diff --git a/assets/debian/README.Debian b/assets/debian/README.Debian
index 4d9f067ac..68c952a4e 100644
--- a/assets/debian/README.Debian
+++ b/assets/debian/README.Debian
@@ -3,10 +3,45 @@ srb2 for Debian
 
 SRB2 Debian package!
 Hi there, to rebuild this package just use the SRB2 Makefile system, or, optionally, run
-dpkg-buildpackage in the in /bin/Resources directory. You can build these with or without a key
+dpkg-buildpackage in the in /assets directory. You can build these with or without a key
 if you want, but if you want to put these on a repo, generate your own GnuPG key as per the
 https://help.ubuntu.com/community/GnuPrivacyGuardHowto instructions and pass the -k<keyid>
 command to debuild. Make sure you export the key footprint and give them to your users to install
 with apt-key add. Thanks!
 
  -- Callum Dickinson <gcfreak_ag20@hotmail.com>  Fri, 26 Nov 2010 18:25:31 +1300
+
+
+Signing for Launchpad PPA
+
+First, follow the above 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
+
+Next, you will have to add that key fingerprint to your Launchpad account. Go to your Launchpad
+profile and click the yellow Edit button next to "OpenPGP keys". Once you add the key, you can
+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.
+
+
+Building for Launchpad PPA
+
+Use these steps to prepare building a source package for Launchpad:
+
+    1. Highly recommend copying the assets/ folder to outside your repo folder, or else the asset
+       files may be included in the main source package, when you build that.
+    2. cd [wherever-your-assets-folder-is]/assets/
+    3. debuild -T clean (optional, if you already have asset files)
+
+Building the source package is a two-step process:
+
+    1. debuild -T build (this downloads the asset files from srb2.org if necessary)
+    2. debuild -S (builds the source package for Launchpad, including the asset files)
+
+Then follow the instructions at <https://help.launchpad.net/Packaging/PPA/Uploading> to upload
+to your PPA and have Launchpad build your binary deb packages.
+
+ -- Marco Zafra <marco.a.zafra@gmail.com>  Mon, 26 Nov 2018 21:13:00 -0500
diff --git a/assets/debian/changelog b/assets/debian/changelog
index a316b7df7..f3a92e1cd 100644
--- a/assets/debian/changelog
+++ b/assets/debian/changelog
@@ -1,3 +1,10 @@
+srb2-data (2.1.21~7) trusty; urgency=high
+
+  * Updated for SRB2 v2.1.21
+
+ -- Marco Zafra <marco.a.zafra@gmail.com>  Mon, 26 Nov 2018 14:31:00 -0500
+
+
 srb2-data (2.1.14~1) unstable; urgency=low
 
   * Updated for SRB2 v2.1.14
diff --git a/assets/debian/control b/assets/debian/control
index 123b58429..22d9643ee 100644
--- a/assets/debian/control
+++ b/assets/debian/control
@@ -3,8 +3,9 @@
 Source: srb2-data
 Section: games
 Priority: extra
-Maintainer: Callum Dickinson <gcfreak_ag20@hotmail.com>
-Build-Depends: debhelper (>= 7.0.50~)
+Maintainer: Sonic Team Junior <stjr@srb2.org>
+Build-Depends: debhelper (>= 7.0.50~),
+ wget
 Standards-Version: 3.8.4
 Homepage: http://www.srb2.org
 
@@ -15,8 +16,7 @@ Description: A cross-platform 3D Sonic fangame
  fangame built using a modified version of the Doom Legacy
  port of Doom. SRB2 is closely inspired by the original
  Sonic games from the Sega Genesis, and attempts to recreate
- the design in 3D. While SRB2 isn't fully completed, it already
- features tons of levels, enemies, speed, and quite a lot
- of the fun that the original Sonic games provided.
+ the design in 3D. It features tons of levels, enemies, speed,
+ and quite a lot of the fun that the original Sonic games provided.
  This is the data package that provides the data files that
- SRB2 requires to run, it will not work without it.
+ SRB2 requires to run; it will not work without it.
diff --git a/assets/debian/copyright b/assets/debian/copyright
index 8a8705190..97d606b0f 100644
--- a/assets/debian/copyright
+++ b/assets/debian/copyright
@@ -1,6 +1,6 @@
 This work was packaged for Debian by:
 
-    Callum Dickinson <gcfreak_ag20@hotmail.com> on Fri, 26 Nov 2010 15:19:16 +1300
+    Marco Zafra <marco.a.zafra@gmail.com>  Mon, 26 Nov 2018 14:31:00 -0500
 
 It was downloaded from:
 
@@ -12,7 +12,7 @@ Upstream Author(s):
 
 Copyright:
 
-    Copyright (C) 1998-2010 Sonic Team Junior
+    Copyright (C) 1998-2018 Sonic Team Junior
 
 License:
 
@@ -21,6 +21,7 @@ License:
 The Debian packaging is:
 
     Copyright (C) 2010 Callum Dickinson <gcfreak_ag20@hotmail.com>
+    Copyright (C) 2010-2018 Sonic Team Junior <stjr@srb2.org>
 
 and is licensed under the GPL version 2,
 see "/usr/share/common-licenses/GPL-2".
diff --git a/assets/debian/rules b/assets/debian/rules
index d86f92af2..a34a3393f 100755
--- a/assets/debian/rules
+++ b/assets/debian/rules
@@ -37,7 +37,7 @@ 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
+DATAFILES := srb2.srb zones.dta player.dta rings.dta music.dta patch.dta README.txt LICENSE.txt LICENSE-3RD-PARTY.txt
 
 DATADIR	:= usr/games/SRB2
 RESOURCEDIR := .
@@ -45,16 +45,21 @@ 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 \
-		$(WGET) http://alam.srb2.org/SRB2/2.1.14-Final/Resources/$$file; \
-		if test "$$file" = "srb2.wad"; then \
-			$(INSTALL) $(RESOURCEDIR)/$$file $(DIR)/debian/tmp/$(DATADIR)/srb2.srb; \
-		else \
-			$(INSTALL) $(RESOURCEDIR)/$$file $(DIR)/debian/tmp/$(DATADIR)/$$file; \
+		if [ ! -f $(RESOURCEDIR)/$$file ]; then \
+			$(WGET) http://alam.srb2.org/SRB2/2.1.21-Final/Resources/$$file; \
+		fi; \
+		if [ -f $(RESOURCEDIR)/$$file ]; then \
+			$(INSTALL) $(RESOURCEDIR)/$$file $(DIR)/debian/tmp/$(DATADIR)/$$file; \
+			echo $(RESOURCEDIR)/$$file >> $(DIR)/debian/source/include-binaries; \
+		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; \
-		echo $(RESOURCEDIR)/$$file >> $(DIR)/debian/source/include-binaries; \
 	done
 
 binary-indep:
@@ -95,15 +100,18 @@ binary: binary-indep
 	dh_builddeb
 
 clean:
-	$(RM) $(RESOURCEDIR)/*.wad
-	$(RM) $(RESOURCEDIR)/*.dta
-	$(RM) $(RESOURCEDIR)/*.plr
-	$(RM) $(RESOURCEDIR)/*.wpn
-	$(RM) $(RESOURCEDIR)/*.srb
-	$(RM) $(RESOURCEDIR)/*.dll
-	$(RM) $(DIR)/debian/tmp/*
-	$(RM) $(DIR)/debian/$(PACKAGE).install
-	$(RM) $(DIR)/debian/files
-	$(RM) $(DIR)/debian/source/include-binaries
+	$(RM) $(DIR)/debian/tmp/*; \
+	$(RM) $(DIR)/debian/$(PACKAGE).install; \
+	$(RM) $(DIR)/debian/files; \
+
+clean-all: clean
+	$(RM) $(RESOURCEDIR)/*.wad; \
+	$(RM) $(RESOURCEDIR)/*.dta; \
+	$(RM) $(RESOURCEDIR)/*.plr; \
+	$(RM) $(RESOURCEDIR)/*.wpn; \
+	$(RM) $(RESOURCEDIR)/*.srb; \
+	$(RM) $(RESOURCEDIR)/*.dll; \
+	$(RM) $(RESOURCEDIR)/*.txt; \
+	$(RM) $(DIR)/debian/source/include-binaries; \
 
 .PHONY: all clean binary binary-arch binary-indep build
diff --git a/assets/debian/source/options b/assets/debian/source/options
new file mode 100644
index 000000000..8b331485a
--- /dev/null
+++ b/assets/debian/source/options
@@ -0,0 +1 @@
+tar-ignore = "tmp/*"
diff --git a/bin/Resources/exchndl.dll b/bin/Resources/i686/exchndl.dll
similarity index 100%
rename from bin/Resources/exchndl.dll
rename to bin/Resources/i686/exchndl.dll
diff --git a/bin/Resources/fmod.dll b/bin/Resources/i686/fmod.dll
similarity index 100%
rename from bin/Resources/fmod.dll
rename to bin/Resources/i686/fmod.dll
diff --git a/bin/Resources/fmodex.dll b/bin/Resources/i686/fmodex.dll
similarity index 100%
rename from bin/Resources/fmodex.dll
rename to bin/Resources/i686/fmodex.dll
diff --git a/bin/Resources/fmodexL.dll b/bin/Resources/i686/fmodexL.dll
similarity index 100%
rename from bin/Resources/fmodexL.dll
rename to bin/Resources/i686/fmodexL.dll
diff --git a/bin/Resources/libgcc_s_dw2-1.dll b/bin/Resources/i686/libgcc_s_dw2-1.dll
similarity index 100%
rename from bin/Resources/libgcc_s_dw2-1.dll
rename to bin/Resources/i686/libgcc_s_dw2-1.dll
diff --git a/bin/Resources/libgme.dll b/bin/Resources/i686/libgme.dll
similarity index 100%
rename from bin/Resources/libgme.dll
rename to bin/Resources/i686/libgme.dll
diff --git a/bin/Resources/libintl-8.dll b/bin/Resources/i686/libintl-8.dll
similarity index 100%
rename from bin/Resources/libintl-8.dll
rename to bin/Resources/i686/libintl-8.dll
diff --git a/bin/Resources/fmod64.dll b/bin/Resources/x86_64/fmod64.dll
similarity index 100%
rename from bin/Resources/fmod64.dll
rename to bin/Resources/x86_64/fmod64.dll
diff --git a/bin/Resources/fmodex64.dll b/bin/Resources/x86_64/fmodex64.dll
similarity index 100%
rename from bin/Resources/fmodex64.dll
rename to bin/Resources/x86_64/fmodex64.dll
diff --git a/bin/Resources/fmodexL64.dll b/bin/Resources/x86_64/fmodexL64.dll
similarity index 100%
rename from bin/Resources/fmodexL64.dll
rename to bin/Resources/x86_64/fmodexL64.dll
diff --git a/bin/Resources/x86_64/libgme.dll b/bin/Resources/x86_64/libgme.dll
new file mode 100644
index 000000000..2ba99450f
Binary files /dev/null and b/bin/Resources/x86_64/libgme.dll differ
diff --git a/debian/README.Debian b/debian/README.Debian
index bbc306b16..4b724816e 100644
--- a/debian/README.Debian
+++ b/debian/README.Debian
@@ -9,3 +9,38 @@ instructions and pass the -k<keyid> command to debuild. Make sure you export the
 and give them to your users to install with apt-key add. Thanks!
 
  -- Callum Dickinson <gcfreak_ag20@hotmail.com>  Fri, 26 Nov 2010 18:25:31 +1300
+
+
+Signing for Launchpad PPA
+
+First, follow the above 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
+
+Next, you will have to add that key fingerprint to your Launchpad account. Go to your Launchpad
+profile and click the yellow Edit button next to "OpenPGP keys". Once you add the key, you can
+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.
+
+
+Building for Launchpad PPA
+
+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!
+
+Building the source package takes just one step:
+
+    1. debuild -S (builds the source package for Launchpad)
+
+Then follow the instructions at <https://help.launchpad.net/Packaging/PPA/Uploading> to upload
+to your PPA and have Launchpad build your binary deb packages.
+
+ -- Marco Zafra <marco.a.zafra@gmail.com>  Mon, 26 Nov 2018 21:13:00 -0500
diff --git a/debian/README.source b/debian/README.source
index ff2dddd41..f63a42cac 100644
--- a/debian/README.source
+++ b/debian/README.source
@@ -22,6 +22,10 @@ Build instructions:
 
 make -C src LINUX=1
 
+Build instructions for non-X86 devices (such as X64):
+
+make -C src LINUX=1 NONX86=1
+
 Build instructions to build for Wii Linux/SRB2Wii on a PowerPC system,
 follow cross-compiling instructions for cross-compiling on a x86 system:
 
diff --git a/debian/changelog b/debian/changelog
index b454b1abd..855c1c1b3 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,10 @@
+srb2 (2.1.21~9) trusty; urgency=high
+
+  * SRB2 v2.1.21 release
+
+ -- Marco Zafra <marco.a.zafra@gmail.com>  Mon, 27 Nov 2018 16:45:00 -0500
+
+
 srb2 (2.0.6-5) maverick; urgency=high
 
   * Initial proper release..
diff --git a/debian/control b/debian/control
index 63b075f17..ce3b33fbd 100644
--- a/debian/control
+++ b/debian/control
@@ -3,11 +3,13 @@
 Source: srb2
 Section: games
 Priority: extra
-Maintainer: Callum Dickinson <gcfreak_ag20@hotmail.com>
+Maintainer: Sonic Team Junior <stjr@srb2.org>
 Build-Depends: debhelper (>= 7.0.50~),
  libsdl2-dev,
  libsdl2-mixer-dev,
- libpng12-dev (>= 1.2.7),
+ libpng12-dev (>= 1.2.7) | libpng-dev,
+ zlib1g-dev,
+ libgme-dev,
  libglu1-dev | libglu-dev,
  libosmesa6-dev | libgl-dev,
  nasm [i386]
@@ -16,27 +18,26 @@ Homepage: http://www.srb2.org
 
 Package: srb2
 Architecture: any
-Depends: ${shlibs:Depends}, ${misc:Depends}, srb2-data (= 2.1.14)
+Depends: ${shlibs:Depends}, ${misc:Depends}, srb2-data (>= 2.1.15), srb2-data (<= 2.1.21)
 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
  port of Doom. SRB2 is closely inspired by the original
  Sonic games from the Sega Genesis, and attempts to recreate
- the design in 3D. While SRB2 isn't fully completed, it already
- features tons of levels, enemies, speed, and quite a lot
- of the fun that the original Sonic games provided.
+ the design in 3D. It features tons of levels, enemies, speed,
+ and quite a lot of the fun that the original Sonic games provided.
+
 
 Package: srb2-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.14), srb2
+Depends: libc6, ${misc:Depends}, srb2-data (>= 2.1.15), srb2-data (<= 2.1.21), srb2
 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
  port of Doom. SRB2 is closely inspired by the original
  Sonic games from the Sega Genesis, and attempts to recreate
- the design in 3D. While SRB2 isn't fully completed, it already
- features tons of levels, enemies, speed, and quite a lot
- of the fun that the original Sonic games provided.
- This is a debug binary, its symbols will be loaded by gdb
+ the design in 3D. It features tons of levels, enemies, speed,
+ and quite a lot of the fun that the original Sonic games provided.
+ This is a debug binary; its symbols will be loaded by gdb
  when the user starts the game with gdb for debugging.
diff --git a/debian/copyright b/debian/copyright
index 8a8705190..97d606b0f 100644
--- a/debian/copyright
+++ b/debian/copyright
@@ -1,6 +1,6 @@
 This work was packaged for Debian by:
 
-    Callum Dickinson <gcfreak_ag20@hotmail.com> on Fri, 26 Nov 2010 15:19:16 +1300
+    Marco Zafra <marco.a.zafra@gmail.com>  Mon, 26 Nov 2018 14:31:00 -0500
 
 It was downloaded from:
 
@@ -12,7 +12,7 @@ Upstream Author(s):
 
 Copyright:
 
-    Copyright (C) 1998-2010 Sonic Team Junior
+    Copyright (C) 1998-2018 Sonic Team Junior
 
 License:
 
@@ -21,6 +21,7 @@ License:
 The Debian packaging is:
 
     Copyright (C) 2010 Callum Dickinson <gcfreak_ag20@hotmail.com>
+    Copyright (C) 2010-2018 Sonic Team Junior <stjr@srb2.org>
 
 and is licensed under the GPL version 2,
 see "/usr/share/common-licenses/GPL-2".
diff --git a/debian/docs b/debian/docs
index b43bf86b5..dba2cd4c8 100644
--- a/debian/docs
+++ b/debian/docs
@@ -1 +1,4 @@
 README.md
+assets/README.txt
+assets/LICENSE.txt
+assets/LICENSE-3RD-PARTY.txt
diff --git a/debian/rules b/debian/rules
index e49784a0f..02e3dc78e 100755
--- a/debian/rules
+++ b/debian/rules
@@ -57,21 +57,32 @@ SECTION = Games/Action
 EXENAME = srb2
 DBGNAME	= debug/$(EXENAME)
 
-PKGDIR	= usr/games
+PKGDIR	= usr/games/SRB2
 DBGDIR	= usr/lib/debug/$(PKGDIR)
 PIXMAPS_DIR = usr/share/pixmaps
 DESKTOP_DIR = usr/share/applications
 PREFIX	= $(shell test "$(CROSS_COMPILE_BUILD)" != "$(CROSS_COMPILE_HOST)" && echo "PREFIX=$(CROSS_COMPILE_HOST)")
 OS	= LINUX=1
 NONX86	= $(shell test "`echo $(CROSS_COMPILE_HOST) | grep 'i[3-6]86'`" || echo "NONX86=1")
-MAKEARGS = $(OS) $(NONX86) $(PREFIX) EXENAME=$(EXENAME) DBGNAME=$(DBGNAME) SDL_PKGCONFIG=sdl2 PNG_PKGCONFIG=libpng NOOBJDUMP=1
+MAKEARGS = $(OS) $(NONX86) $(PREFIX) EXENAME=$(EXENAME) DBGNAME=$(DBGNAME) NOOBJDUMP=1 # SDL_PKGCONFIG=sdl2 PNG_PKGCONFIG=libpng
 MENUFILE1 = ?package($(PACKAGE)):needs="X11" section="$(SECTION)"
 MENUFILE2 = title="$(TITLE)" command="/$(PKGDIR)/$(PACKAGE)"
-# FIXME pkg-config dir hacks
-export PKG_CONFIG_LIBDIR = /usr/lib/$(CROSS_COMPILE_HOST)/pkgconfig
 BINDIR :=  $(DIR)/bin/Linux/Release
+
+# FIXME pkg-config dir hacks
+# Launchpad doesn't need this; it actually makes i386 builds fail due to cross-compile
+# export PKG_CONFIG_LIBDIR = /usr/lib/$(CROSS_COMPILE_HOST)/pkgconfig
 LDFLAGS += "-Wl,-rpath=/usr/lib/$(CROSS_COMPILE_HOST)"
 
+# Some libgme-dev packages don't use pkg-config yet, so include the linker flag ourselves
+PKG_CONFIG?=pkg-config
+LIBGME_PKGCONFIG?=libgme
+LIBGME_LDFLAGS?=$(shell $(PKG_CONFIG) $(LIBGME_PKGCONFIG) --libs)
+
+ifeq ($(LIBGME_LDFLAGS),)
+MAKEARGS += LIBGME_LDFLAGS=-lgme
+endif
+
 build:
 	$(MKDIR) $(BINDIR)/debug
 	$(MAKE) -C $(DIR)/src $(MAKEARGS)
@@ -100,8 +111,8 @@ binary-arch:
 	echo $(DESKTOP_DIR) >> $(DIR)/debian/$(PACKAGE).install
 	echo $(PIXMAPS_DIR) >> $(DIR)/debian/$(PACKAGE).install
 	echo $(DBGDIR) > $(DIR)/debian/$(DBGPKG).install
-
-binary: binary-arch
+# Launchpad only calls binary-arch, so just move everything up
+#binary: binary-arch
 	# Generate .desktop specifications
 	echo "`echo '$(MENUFILE1)\\'`" > $(DIR)/debian/menu
 	echo " `echo '$(MENUFILE2)'`" >> $(DIR)/debian/menu
@@ -133,6 +144,8 @@ binary: binary-arch
 	dh_md5sums
 	dh_builddeb
 
+binary: binary-arch
+
 clean:
 	$(MAKE) -C $(DIR)/src $(MAKEARGS) clean cleandep
 	$(RM) $(BINDIR)/*
@@ -145,4 +158,4 @@ clean:
 	$(RM) $(DIR)/debian/files
 	$(RM) $(DIR)/debian/source/include-binaries
 
-.PHONY: all clean binary binary-arch binary-indep build
+.PHONY: all clean binary binary-indep build
diff --git a/debian/source/options b/debian/source/options
new file mode 100644
index 000000000..841c65a6f
--- /dev/null
+++ b/debian/source/options
@@ -0,0 +1,10 @@
+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/tmp/*"
+tar-ignore = "*.obj"
+tar-ignore = "*.dep"
+tar-ignore = ".git/*"
+tar-ignore = ".git*"
diff --git a/debian/srb2.desktop b/debian/srb2.desktop
index 661832b93..3a1cac9f6 100644
--- a/debian/srb2.desktop
+++ b/debian/srb2.desktop
@@ -1,8 +1,8 @@
 [Desktop Entry]
 Name=Sonic Robo Blast 2
-Comment=A free 3D Sonic the Hedgehog fan-game built using a modified ver. of the Doom Legacy source port
+Comment=A free 3D Sonic the Hedgehog fangame closely inspired by the original Sonic games on the Sega Genesis.
 Encoding=UTF-8
-Exec=srb2
+Exec=/usr/games/SRB2/srb2
 Icon=/usr/share/pixmaps/srb2.png
 Terminal=false
 Type=Application
diff --git a/libs/SDL2/COPYING.txt b/libs/SDL2/COPYING.txt
index a1c8bbe5a..694e58a09 100644
--- a/libs/SDL2/COPYING.txt
+++ b/libs/SDL2/COPYING.txt
@@ -1,6 +1,6 @@
 
 Simple DirectMedia Layer
-Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
   
 This software is provided 'as-is', without any express or implied
 warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/Makefile b/libs/SDL2/Makefile
index a2e6bb9ba..9edfd003e 100644
--- a/libs/SDL2/Makefile
+++ b/libs/SDL2/Makefile
@@ -1,12 +1,12 @@
 #
 # Makefile for installing the mingw32 version of the SDL library
 
-CROSS_PATH := /usr/local/cross-tools
+CROSS_PATH := /usr/local
 ARCHITECTURES := i686-w64-mingw32 x86_64-w64-mingw32
 
 all install:
 	@echo "Type \"make native\" to install 32-bit to /usr"
-	@echo "Type \"make cross\" to install 32-bit and 64-bit to CROSS_PATH ($(CROSS_PATH))"
+	@echo "Type \"make cross\" to install 32-bit and 64-bit to $(CROSS_PATH)"
 
 native:
 	make install-package arch=i686-w64-mingw32 prefix=/usr
@@ -22,6 +22,7 @@ install-package:
 	    sed "s|^prefix=.*|prefix=$(prefix)|" <$(arch)/bin/sdl2-config >$(prefix)/bin/sdl2-config; \
 	    chmod 755 $(prefix)/bin/sdl2-config; \
 	    sed "s|^libdir=.*|libdir=\'$(prefix)/lib\'|" <$(arch)/lib/libSDL2.la >$(prefix)/lib/libSDL2.la; \
+	    sed "s|^libdir=.*|libdir=\'$(prefix)/lib\'|" <$(arch)/lib/libSDL2main.la >$(prefix)/lib/libSDL2main.la; \
 	    sed "s|^prefix=.*|prefix=$(prefix)|" <$(arch)/lib/pkgconfig/sdl2.pc >$(prefix)/lib/pkgconfig/sdl2.pc; \
 	else \
 	    echo "*** ERROR: $(arch) or $(prefix) does not exist!"; \
diff --git a/libs/SDL2/SRB2NOTE.txt b/libs/SDL2/SRB2NOTE.txt
new file mode 100644
index 000000000..b7da4c9ab
--- /dev/null
+++ b/libs/SDL2/SRB2NOTE.txt
@@ -0,0 +1,15 @@
+# SDL Development Libaries
+
+Download both the VC and MinGW packages and extract them here.
+
+https://www.libsdl.org/download-2.0.php
+
+## VC Package
+
+* include
+* lib
+
+## MinGW Package
+
+* i686-w64-mingw32
+* x86_64-w64-mingw32
diff --git a/libs/SDL2/WhatsNew.txt b/libs/SDL2/WhatsNew.txt
index 9c8d53840..9074b12ba 100644
--- a/libs/SDL2/WhatsNew.txt
+++ b/libs/SDL2/WhatsNew.txt
@@ -1,6 +1,91 @@
 
 This is a list of major changes in SDL's version history.
 
+---------------------------------------------------------------------------
+2.0.9:
+---------------------------------------------------------------------------
+
+General:
+* Added a new sensor API, initialized by passing SDL_INIT_SENSOR to SDL_Init(), and defined in SDL_sensor.h
+* Added an event SDL_SENSORUPDATE which is sent when a sensor is updated
+* Added SDL_GetDisplayOrientation() to return the current display orientation
+* Added an event SDL_DISPLAYEVENT which is sent when the display orientation changes
+* Added HIDAPI joystick drivers for more consistent support for Xbox, PS4 and Nintendo Switch Pro controller support across platforms. (Thanks to Valve for contributing the PS4 and Nintendo Switch Pro controller support)
+* Added support for many other popular game controllers
+* Added SDL_JoystickGetDevicePlayerIndex(), SDL_JoystickGetPlayerIndex(), and SDL_GameControllerGetPlayerIndex() to get the player index for a controller. For XInput controllers this returns the XInput index for the controller.
+* Added SDL_GameControllerRumble() and SDL_JoystickRumble() which allow simple rumble without using the haptics API
+* Added SDL_GameControllerMappingForDeviceIndex() to get the mapping for a controller before it's opened
+* Added the hint SDL_HINT_MOUSE_DOUBLE_CLICK_TIME to control the mouse double-click time
+* Added the hint SDL_HINT_MOUSE_DOUBLE_CLICK_RADIUS to control the mouse double-click radius, in pixels
+* Added SDL_HasColorKey() to return whether a surface has a colorkey active
+* Added SDL_HasAVX512F() to return whether the CPU has AVX-512F features
+* Added SDL_IsTablet() to return whether the application is running on a tablet
+* Added SDL_THREAD_PRIORITY_TIME_CRITICAL for threads that must run at the highest priority
+
+Mac OS X:
+* Fixed black screen at start on Mac OS X Mojave
+
+Linux:
+* Added SDL_LinuxSetThreadPriority() to allow adjusting the thread priority of native threads using RealtimeKit if available.
+
+iOS:
+* Fixed Asian IME input
+
+Android:
+* Updated required Android SDK to API 26, to match Google's new App Store requirements
+* Added support for wired USB Xbox, PS4, and Nintendo Switch Pro controllers
+* Added support for relative mouse mode on Android 7.0 and newer (except where it's broken, on Chromebooks and when in DeX mode with Samsung Experience 9.0)
+* Added support for custom mouse cursors on Android 7.0 and newer
+* Added the hint SDL_HINT_ANDROID_TRAP_BACK_BUTTON to control whether the back button will back out of the app (the default) or be passed to the application as SDL_SCANCODE_AC_BACK
+* Added SDL_AndroidBackButton() to trigger the Android system back button behavior when handling the back button in the application
+* Added SDL_IsChromebook() to return whether the app is running in the Chromebook Android runtime
+* Added SDL_IsDeXMode() to return whether the app is running while docked in the Samsung DeX
+
+
+---------------------------------------------------------------------------
+2.0.8:
+---------------------------------------------------------------------------
+
+General:
+* Added SDL_fmod() and SDL_log10()
+* Each of the SDL math functions now has the corresponding float version
+* Added SDL_SetYUVConversionMode() and SDL_GetYUVConversionMode() to control the formula used when converting to and from YUV colorspace. The options are JPEG, BT.601, and BT.709
+
+Windows:
+* Implemented WASAPI support on Windows UWP and removed the deprecated XAudio2 implementation
+* Added resampling support on WASAPI on Windows 7 and above
+
+Windows UWP:
+* Added SDL_WinRTGetDeviceFamily() to find out what type of device your application is running on
+
+Mac OS X:
+* Added support for the Vulkan SDK for Mac:
+  https://www.lunarg.com/lunarg-releases-vulkan-sdk-1-0-69-0-for-mac/
+* Added support for OpenGL ES using ANGLE when it's available
+
+Mac OS X / iOS / tvOS:
+* Added a Metal 2D render implementation
+* Added SDL_RenderGetMetalLayer() and SDL_RenderGetMetalCommandEncoder() to insert your own drawing into SDL rendering when using the Metal implementation
+
+iOS:
+* Added the hint SDL_HINT_IOS_HIDE_HOME_INDICATOR to control whether the home indicator bar on iPhone X should be hidden. This defaults to dimming the indicator for fullscreen applications and showing the indicator for windowed applications.
+
+iOS / Android:
+* Added the hint SDL_HINT_RETURN_KEY_HIDES_IME to control whether the return key on the software keyboard should hide the keyboard or send a key event (the default)
+
+Android:
+* SDL now supports building with Android Studio and Gradle by default, and the old Ant project is available in android-project-ant
+* SDL now requires the API 19 SDK to build, but can still target devices down to API 14 (Android 4.0.1)
+* Added SDL_IsAndroidTV() to tell whether the application is running on Android TV
+
+Android / tvOS:
+* Added the hint SDL_HINT_TV_REMOTE_AS_JOYSTICK to control whether TV remotes should be listed as joystick devices (the default) or send keyboard events.
+
+Linux:
+* Added the hint SDL_HINT_VIDEO_X11_NET_WM_BYPASS_COMPOSITOR to control whether the X server should skip the compositor for the SDL application. This defaults to "1"
+* Added the hint SDL_HINT_VIDEO_DOUBLE_BUFFER to control whether the Raspberry Pi and KMSDRM video drivers should use double or triple buffering (the default)
+
+
 ---------------------------------------------------------------------------
 2.0.7:
 ---------------------------------------------------------------------------
diff --git a/libs/SDL2/docs/README-android.md b/libs/SDL2/docs/README-android.md
index 62874f435..7f3263dc3 100644
--- a/libs/SDL2/docs/README-android.md
+++ b/libs/SDL2/docs/README-android.md
@@ -4,20 +4,24 @@ Android
 Matt Styles wrote a tutorial on building SDL for Android with Visual Studio:
 http://trederia.blogspot.de/2017/03/building-sdl2-for-android-with-visual.html
 
-The rest of this README covers the old style build process.
+The rest of this README covers the Android gradle style build process.
+
+If you are using the older ant build process, it is no longer officially
+supported, but you can use the "android-project-ant" directory as a template.
+
 
 ================================================================================
  Requirements
 ================================================================================
 
-Android SDK (version 16 or later)
+Android SDK (version 26 or later)
 https://developer.android.com/sdk/index.html
 
-Android NDK r7 or later
+Android NDK r15c or later
 https://developer.android.com/tools/sdk/ndk/index.html
 
-Minimum API level supported by SDL: 10 (Android 2.3.3)
-Joystick support is available for API level >= 12 devices.
+Minimum API level supported by SDL: 14 (Android 4.0.1)
+
 
 ================================================================================
  How the port works
@@ -31,15 +35,12 @@ Joystick support is available for API level >= 12 devices.
 - This eventually produces a standard Android .apk package
 
 The Android Java code implements an "Activity" and can be found in:
-android-project/src/org/libsdl/app/SDLActivity.java
+android-project/app/src/main/java/org/libsdl/app/SDLActivity.java
 
 The Java code loads your game code, the SDL shared library, and
 dispatches to native functions implemented in the SDL library:
 src/core/android/SDL_android.c
 
-Your project must include some glue code that starts your main() routine:
-src/main/android/SDL_android_main.c
-
 
 ================================================================================
  Building an app
@@ -74,71 +75,30 @@ For more complex projects, follow these instructions:
     
 1. Copy the android-project directory wherever you want to keep your projects
    and rename it to the name of your project.
-2. Move or symlink this SDL directory into the "<project>/jni" directory
-3. Edit "<project>/jni/src/Android.mk" to include your source files
-4. Run 'ndk-build' (a script provided by the NDK). This compiles the C source
+2. Move or symlink this SDL directory into the "<project>/app/jni" directory
+3. Edit "<project>/app/jni/src/Android.mk" to include your source files
 
-If you want to use the Eclipse IDE, skip to the Eclipse section below.
+4a. If you want to use Android Studio, simply open your <project> directory and start building.
 
-5. Create "<project>/local.properties" and use that to point to the Android SDK directory, by writing a line with the following form:
-
-       sdk.dir=PATH_TO_ANDROID_SDK
-
-6. Run 'ant debug' in android/project. This compiles the .java and eventually 
-   creates a .apk with the native code embedded
-7. 'ant debug install' will push the apk to the device or emulator (if connected)
+4b. If you want to build manually, run './gradlew installDebug' in the project directory. This compiles the .java, creates an .apk with the native code embedded, and installs it on any connected Android device
 
 Here's an explanation of the files in the Android project, so you can customize them:
 
-    android-project/
-        AndroidManifest.xml	- package manifest. Among others, it contains the class name
-        			  of the main Activity and the package name of the application.
-        build.properties	- empty
-        build.xml		- build description file, used by ant. The actual application name
-        			  is specified here.
-        default.properties	- holds the target ABI for the application, android-10 and up
-        project.properties	- holds the target ABI for the application, android-10 and up
-        local.properties	- holds the SDK path, you should change this to the path to your SDK
+    android-project/app
+        build.gradle            - build info including the application version and SDK
+        src/main/AndroidManifest.xml	- package manifest. Among others, it contains the class name of the main Activity and the package name of the application.
         jni/			- directory holding native code
-        jni/Android.mk		- Android makefile that can call recursively the Android.mk files
-        			  in all subdirectories
+        jni/Application.mk	- Application JNI settings, including target platform and STL library
+        jni/Android.mk		- Android makefile that can call recursively the Android.mk files in all subdirectories
         jni/SDL/		- (symlink to) directory holding the SDL library files
         jni/SDL/Android.mk	- Android makefile for creating the SDL shared library
         jni/src/		- directory holding your C/C++ source
-        jni/src/Android.mk	- Android makefile that you should customize to include your 
-                                  source code and any library references
-        res/			- directory holding resources for your application
-        res/drawable-*		- directories holding icons for different phone hardware. Could be
-        			  one dir called "drawable".
-        res/layout/main.xml	- Usually contains a file main.xml, which declares the screen layout.
-        			  We don't need it because we use the SDL video output.
-        res/values/strings.xml	- strings used in your application, including the application name
-        			  shown on the phone.
-        src/org/libsdl/app/SDLActivity.java - the Java class handling the initialization and binding
-        			  to SDL.  Be very careful changing this, as the SDL library relies
-        			  on this implementation.
-
-
-================================================================================
- Build an app with static linking of libSDL
-================================================================================
-
-This build uses the Android NDK module system.
-
-Instructions:
-1. Copy the android-project directory wherever you want to keep your projects
-   and rename it to the name of your project.
-2. Rename "<project>/jni/src/Android_static.mk" to "<project>/jni/src/Android.mk"
-   (overwrite the existing one)
-3. Edit "<project>/jni/src/Android.mk" to include your source files
-4. create and export an environment variable named NDK_MODULE_PATH that points
-   to the parent directory of this SDL directory. e.g.:
-
-       export NDK_MODULE_PATH="$PWD"/..
-
-5. Edit "<project>/src/org/libsdl/app/SDLActivity.java" and remove the call to
-   System.loadLibrary("SDL2").
-6. Run 'ndk-build' (a script provided by the NDK). This compiles the C source
+        jni/src/Android.mk	- Android makefile that you should customize to include your source code and any library references
+        src/main/assets/	- directory holding asset files for your application
+        src/main/res/		- directory holding resources for your application
+        src/main/res/mipmap-*	- directories holding icons for different phone hardware
+        src/main/res/values/strings.xml	- strings used in your application, including the application name
+        src/main/java/org/libsdl/app/SDLActivity.java - the Java class handling the initialization and binding to SDL. Be very careful changing this, as the SDL library relies on this implementation. You should instead subclass this for your application.
 
 
 ================================================================================
@@ -171,25 +131,23 @@ Here's an example of a minimal class file:
 Then replace "SDLActivity" in AndroidManifest.xml with the name of your
 class, .e.g. "MyGame"
 
+
 ================================================================================
  Customizing your application icon
 ================================================================================
 
 Conceptually changing your icon is just replacing the "ic_launcher.png" files in
-the drawable directories under the res directory. There are four directories for
-different screen sizes. These can be replaced with one dir called "drawable",
-containing an icon file "ic_launcher.png" with dimensions 48x48 or 72x72.
+the drawable directories under the res directory. There are several directories
+for different screen sizes.
 
-You may need to change the name of your icon in AndroidManifest.xml to match
-this icon filename.
 
 ================================================================================
  Loading assets
 ================================================================================
 
-Any files you put in the "assets" directory of your android-project directory
-will get bundled into the application package and you can load them using the
-standard functions in SDL_rwops.h.
+Any files you put in the "app/src/main/assets" directory of your project
+directory will get bundled into the application package and you can load
+them using the standard functions in SDL_rwops.h.
 
 There are also a few Android specific functions that allow you to get other
 useful paths for saving and loading data:
@@ -211,6 +169,7 @@ disable this behaviour, see for example:
     
 http://ponystyle.com/blog/2010/03/26/dealing-with-asset-compression-in-android-apps/
 
+
 ================================================================================
  Pause / Resume behaviour
 ================================================================================
@@ -231,6 +190,7 @@ a specific message, (which is not yet implemented!) and restore your textures
 manually or quit the app (which is actually the kind of behaviour you'll see
 under iOS, if the OS can not restore your GL context it will just kill your app)
 
+
 ================================================================================
  Threads and the Java VM
 ================================================================================
@@ -246,6 +206,7 @@ Android_JNI_SetupThread() before doing anything else otherwise SDL will attach
 your thread automatically anyway (when you make an SDL call), but it'll never
 detach it.
 
+
 ================================================================================
  Using STL
 ================================================================================
@@ -253,34 +214,10 @@ detach it.
 You can use STL in your project by creating an Application.mk file in the jni
 folder and adding the following line:
 
-    APP_STL := stlport_static
+    APP_STL := c++_shared
 
-For more information check out CPLUSPLUS-SUPPORT.html in the NDK documentation.
-
-================================================================================
- Additional documentation
-================================================================================
-
-The documentation in the NDK docs directory is very helpful in understanding the
-build process and how to work with native code on the Android platform.
-
-The best place to start is with docs/OVERVIEW.TXT
-
-
-================================================================================
- Using Eclipse
-================================================================================
-
-First make sure that you've installed Eclipse and the Android extensions as described here:
-	https://developer.android.com/tools/sdk/eclipse-adt.html
-
-Once you've copied the SDL android project and customized it, you can create an Eclipse project from it:
- * File -> New -> Other
- * Select the Android -> Android Project wizard and click Next
- * Enter the name you'd like your project to have
- * Select "Create project from existing source" and browse for your project directory
- * Make sure the Build Target is set to Android 3.1 (API 12)
- * Click Finish
+For more information go here:
+	https://developer.android.com/ndk/guides/cpp-support
 
 
 ================================================================================
@@ -295,13 +232,11 @@ Especially useful is the info on setting up OpenGL ES 2.0 emulation.
 Notice that this software emulator is incredibly slow and needs a lot of disk space.
 Using a real device works better.
 
+
 ================================================================================
  Troubleshooting
 ================================================================================
 
-You can create and run an emulator from the Eclipse IDE:
- * Window -> Android SDK and AVD Manager
-
 You can see if adb can see any devices with the following command:
 
     adb devices
@@ -338,7 +273,10 @@ You can see the complete command line that ndk-build is using by passing V=1 on
 
     ndk-build V=1
 
-If your application crashes in native code, you can use addr2line to convert the
+If your application crashes in native code, you can use ndk-stack to get a symbolic stack trace:
+	https://developer.android.com/ndk/guides/ndk-stack
+
+If you want to go through the process manually, you can use addr2line to convert the
 addresses in the stack trace to lines in your code.
 
 For example, if your crash looks like this:
@@ -426,36 +364,30 @@ When you're done instrumenting with valgrind, you can disable the wrapper:
 
     adb shell setprop wrap.org.libsdl.app ""
 
+
 ================================================================================
  Graphics debugging
 ================================================================================
 
 If you are developing on a compatible Tegra-based tablet, NVidia provides
-Tegra Graphics Debugger at their website.  Because SDL2 dynamically loads EGL
+Tegra Graphics Debugger at their website. Because SDL2 dynamically loads EGL
 and GLES libraries, you must follow their instructions for installing the
-interposer library on a rooted device.  The non-rooted instructions are not
+interposer library on a rooted device. The non-rooted instructions are not
 compatible with applications that use SDL2 for video.
 
 The Tegra Graphics Debugger is available from NVidia here:
 https://developer.nvidia.com/tegra-graphics-debugger
 
+
 ================================================================================
- Why is API level 10 the minimum required?
+ Why is API level 14 the minimum required?
 ================================================================================
 
-API level 10 is the minimum required level at runtime (that is, on the device) 
-because SDL requires some functionality for running not
-available on older devices. Since the incorporation of joystick support into SDL,
-the minimum SDK required to *build* SDL is version 12. Devices running API levels
-10-11 are still supported, only with the joystick functionality disabled.
-
-Support for native OpenGL ES and ES2 applications was introduced in the NDK for
-API level 4 and 8. EGL was made a stable API in the NDK for API level 9, which
-has since then been obsoleted, with the recommendation to developers to bump the
-required API level to 10.
+The latest NDK toolchain doesn't support targeting earlier than API level 14.
 As of this writing, according to https://developer.android.com/about/dashboards/index.html
-about 90% of the Android devices accessing Google Play support API level 10 or
-higher (March 2013).
+about 99% of the Android devices accessing Google Play support API level 14 or
+higher (October 2017).
+
 
 ================================================================================
  A note regarding the use of the "dirty rectangles" rendering technique
@@ -475,6 +407,7 @@ screen each frame.
 
 Reference: http://www.khronos.org/registry/egl/specs/EGLTechNote0001.html
 
+
 ================================================================================
  Known issues
 ================================================================================
diff --git a/libs/SDL2/docs/README-dynapi.md b/libs/SDL2/docs/README-dynapi.md
index bfaecb344..b9a58bce1 100644
--- a/libs/SDL2/docs/README-dynapi.md
+++ b/libs/SDL2/docs/README-dynapi.md
@@ -64,7 +64,7 @@ level of indirection, we can do things like this:
     export SDL_DYNAMIC_API=/my/actual/libSDL-2.0.so.0
     ./MyGameThatIsStaticallyLinkedToSDL2
 
-And now, this game that is staticallly linked to SDL, can still be overridden 
+And now, this game that is statically linked to SDL, can still be overridden 
 with a newer, or better, SDL. The statically linked one will only be used as 
 far as calling into the jump table in this case. But in cases where no override
 is desired, the statically linked version will provide its own jump table, 
diff --git a/libs/SDL2/docs/README-raspberrypi.md b/libs/SDL2/docs/README-raspberrypi.md
index d64e7cb36..2c95e0649 100644
--- a/libs/SDL2/docs/README-raspberrypi.md
+++ b/libs/SDL2/docs/README-raspberrypi.md
@@ -27,6 +27,16 @@ OpenGL ES 2.x, it usually comes pre-installed, but in any case:
     
 sudo apt-get install libraspberrypi0 libraspberrypi-bin libraspberrypi-dev
 
+
+================================================================================
+ NEON
+================================================================================
+
+If your Pi has NEON support, make sure you add -mfpu=neon to your CFLAGS so
+that SDL will select some otherwise-disabled highly-optimized code. The
+original Pi units don't have NEON, the Pi2 probably does, and the Pi3
+definitely does.
+
 ================================================================================
  Cross compiling from x86 Linux
 ================================================================================
diff --git a/libs/SDL2/docs/README-winrt.md b/libs/SDL2/docs/README-winrt.md
index 8e993b57a..35b7e6d87 100644
--- a/libs/SDL2/docs/README-winrt.md
+++ b/libs/SDL2/docs/README-winrt.md
@@ -23,7 +23,7 @@ Requirements
     typically do not include support for creating WinRT apps, to note.
     (The "Community" editions of Visual C++ do, however, support both
     desktop/Win32 and WinRT development).
-  - Visual Studio 2017 can be used, however it is recommented that you install
+  - Visual Studio 2017 can be used, however it is recommended that you install
     the Visual C++ 2015 build tools.  These build tools can be installed
     using VS 2017's installer.  Be sure to also install the workload for
     "Universal Windows Platform development", its optional component, the
@@ -33,7 +33,7 @@ Requirements
     earlier versions of Windows, such as Windows 7, is not always supported
     by Visual Studio, and you may get error(s) when attempting to do so.
   - Visual C++ 2012 can only build apps that target versions 8.0 of Windows,
-    or  Windows Phone.  8.0-targetted apps will run on devices running 8.1
+    or  Windows Phone.  8.0-targeted apps will run on devices running 8.1
     editions of Windows, however they will not be able to take advantage of
     8.1-specific features.
   - Visual C++ 2013 cannot create app projects that target Windows 8.0.
@@ -54,7 +54,7 @@ Requirements
 Status
 ------
 
-Here is a rough list of what works, and what doens't:
+Here is a rough list of what works, and what doesn't:
 
 * What works:
   * compilation via Visual C++ 2012 through 2015
@@ -70,7 +70,10 @@ Here is a rough list of what works, and what doens't:
     SDL_GetPerformanceFrequency(), etc.)
   * file I/O via SDL_RWops
   * mouse input  (unsupported on Windows Phone)
-  * audio, via a modified version of SDL's XAudio2 backend
+  * audio, via SDL's WASAPI backend (if you want to record, your app must 
+    have "Microphone" capabilities enabled in its manifest, and the user must 
+    not have blocked access. Otherwise, capture devices will fail to work,
+    presenting as a device disconnect shortly after opening it.)
   * .DLL file loading.  Libraries *MUST* be packaged inside applications.  Loading
     anything outside of the app is not supported.
   * system path retrieval via SDL's filesystem APIs
diff --git a/libs/SDL2/i686-w64-mingw32/bin/SDL2.dll b/libs/SDL2/i686-w64-mingw32/bin/SDL2.dll
index c21f747c2..701779044 100755
Binary files a/libs/SDL2/i686-w64-mingw32/bin/SDL2.dll and b/libs/SDL2/i686-w64-mingw32/bin/SDL2.dll differ
diff --git a/libs/SDL2/i686-w64-mingw32/bin/sdl2-config b/libs/SDL2/i686-w64-mingw32/bin/sdl2-config
index 7fdb82515..e1060b3f2 100755
--- a/libs/SDL2/i686-w64-mingw32/bin/sdl2-config
+++ b/libs/SDL2/i686-w64-mingw32/bin/sdl2-config
@@ -1,6 +1,6 @@
 #!/bin/sh
 
-prefix=/usr/local/i686-w64-mingw32
+prefix=/opt/local/i686-w64-mingw32
 exec_prefix=${prefix}
 exec_prefix_set=no
 libdir=${exec_prefix}/lib
@@ -39,17 +39,17 @@ while test $# -gt 0; do
       echo $exec_prefix
       ;;
     --version)
-      echo 2.0.7
+      echo 2.0.9
       ;;
     --cflags)
       echo -I${prefix}/include/SDL2  -Dmain=SDL_main
       ;;
     --libs)
-      echo -L${exec_prefix}/lib  -lmingw32 -lSDL2main -lSDL2  -mwindows
+      echo -L${exec_prefix}/lib  -lmingw32 -lSDL2main -lSDL2 -mwindows
       ;;
     --static-libs)
 #    --libs|--static-libs)
-      echo -L${exec_prefix}/lib  -lmingw32 -lSDL2main -lSDL2  -mwindows  -Wl,--no-undefined -lm -ldinput8 -ldxguid -ldxerr8 -luser32 -lgdi32 -lwinmm -limm32 -lole32 -loleaut32 -lshell32 -lversion -luuid -static-libgcc
+      echo -L${exec_prefix}/lib  -lmingw32 -lSDL2main -lSDL2 -mwindows  -Wl,--no-undefined -lm -ldinput8 -ldxguid -ldxerr8 -luser32 -lgdi32 -lwinmm -limm32 -lole32 -loleaut32 -lshell32 -lsetupapi -lversion -luuid -static-libgcc
       ;;
     *)
       echo "${usage}" 1>&2
diff --git a/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL.h b/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL.h
index 366d50fa3..fc35a419e 100644
--- a/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL.h
+++ b/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
@@ -51,6 +51,7 @@
 #include "SDL_power.h"
 #include "SDL_render.h"
 #include "SDL_rwops.h"
+#include "SDL_sensor.h"
 #include "SDL_shape.h"
 #include "SDL_system.h"
 #include "SDL_thread.h"
@@ -80,10 +81,11 @@ extern "C" {
 #define SDL_INIT_HAPTIC         0x00001000u
 #define SDL_INIT_GAMECONTROLLER 0x00002000u  /**< SDL_INIT_GAMECONTROLLER implies SDL_INIT_JOYSTICK */
 #define SDL_INIT_EVENTS         0x00004000u
+#define SDL_INIT_SENSOR         0x00008000u
 #define SDL_INIT_NOPARACHUTE    0x00100000u  /**< compatibility; this flag is ignored. */
 #define SDL_INIT_EVERYTHING ( \
                 SDL_INIT_TIMER | SDL_INIT_AUDIO | SDL_INIT_VIDEO | SDL_INIT_EVENTS | \
-                SDL_INIT_JOYSTICK | SDL_INIT_HAPTIC | SDL_INIT_GAMECONTROLLER \
+                SDL_INIT_JOYSTICK | SDL_INIT_HAPTIC | SDL_INIT_GAMECONTROLLER | SDL_INIT_SENSOR \
             )
 /* @} */
 
diff --git a/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_assert.h b/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_assert.h
index 90abbe39b..b38f928ae 100644
--- a/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_assert.h
+++ b/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_assert.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_atomic.h b/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_atomic.h
index 36e37f3b7..b2287748c 100644
--- a/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_atomic.h
+++ b/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_atomic.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
@@ -158,6 +158,9 @@ extern DECLSPEC void SDLCALL SDL_MemoryBarrierAcquireFunction(void);
 #if defined(__GNUC__) && (defined(__powerpc__) || defined(__ppc__))
 #define SDL_MemoryBarrierRelease()   __asm__ __volatile__ ("lwsync" : : : "memory")
 #define SDL_MemoryBarrierAcquire()   __asm__ __volatile__ ("lwsync" : : : "memory")
+#elif defined(__GNUC__) && defined(__aarch64__)
+#define SDL_MemoryBarrierRelease()   __asm__ __volatile__ ("dmb ish" : : : "memory")
+#define SDL_MemoryBarrierAcquire()   __asm__ __volatile__ ("dmb ish" : : : "memory")
 #elif defined(__GNUC__) && defined(__arm__)
 #if defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7EM__) || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7S__)
 #define SDL_MemoryBarrierRelease()   __asm__ __volatile__ ("dmb ish" : : : "memory")
diff --git a/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_audio.h b/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_audio.h
index f119c2b26..d3e1bface 100644
--- a/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_audio.h
+++ b/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_audio.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
@@ -140,7 +140,8 @@ typedef Uint16 SDL_AudioFormat;
 #define SDL_AUDIO_ALLOW_FREQUENCY_CHANGE    0x00000001
 #define SDL_AUDIO_ALLOW_FORMAT_CHANGE       0x00000002
 #define SDL_AUDIO_ALLOW_CHANNELS_CHANGE     0x00000004
-#define SDL_AUDIO_ALLOW_ANY_CHANGE          (SDL_AUDIO_ALLOW_FREQUENCY_CHANGE|SDL_AUDIO_ALLOW_FORMAT_CHANGE|SDL_AUDIO_ALLOW_CHANNELS_CHANGE)
+#define SDL_AUDIO_ALLOW_SAMPLES_CHANGE      0x00000008
+#define SDL_AUDIO_ALLOW_ANY_CHANGE          (SDL_AUDIO_ALLOW_FREQUENCY_CHANGE|SDL_AUDIO_ALLOW_FORMAT_CHANGE|SDL_AUDIO_ALLOW_CHANNELS_CHANGE|SDL_AUDIO_ALLOW_SAMPLES_CHANGE)
 /* @} */
 
 /* @} *//* Audio flags */
@@ -527,7 +528,7 @@ extern DECLSPEC SDL_AudioStream * SDLCALL SDL_NewAudioStream(const SDL_AudioForm
  *
  *  \param stream The stream the audio data is being added to
  *  \param buf A pointer to the audio data to add
- *  \param int The number of bytes to write to the stream
+ *  \param len The number of bytes to write to the stream
  *  \return 0 on success, or -1 on error.
  *
  *  \sa SDL_NewAudioStream
diff --git a/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_bits.h b/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_bits.h
index bc2857290..eb8322f0d 100644
--- a/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_bits.h
+++ b/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_bits.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_blendmode.h b/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_blendmode.h
index 9abd0bd4c..36a5ea76f 100644
--- a/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_blendmode.h
+++ b/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_blendmode.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_clipboard.h b/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_clipboard.h
index 341f4ba42..f28751ebb 100644
--- a/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_clipboard.h
+++ b/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_clipboard.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_config.h b/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_config.h
index 1bbb83848..c58be8e72 100644
--- a/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_config.h
+++ b/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_config.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
@@ -82,6 +82,9 @@ typedef unsigned int uintptr_t;
 #define HAVE_DSOUND_H 1
 #define HAVE_DXGI_H 1
 #define HAVE_XINPUT_H 1
+#define HAVE_MMDEVICEAPI_H 1
+#define HAVE_AUDIOCLIENT_H 1
+#define HAVE_ENDPOINTVOLUME_H 1
 
 /* This is disabled by default to avoid C runtime dependencies and manifest requirements */
 #ifdef HAVE_LIBC
@@ -109,13 +112,15 @@ typedef unsigned int uintptr_t;
 #define HAVE_MEMCMP 1
 #define HAVE_STRLEN 1
 #define HAVE__STRREV 1
-#define HAVE__STRUPR 1
-#define HAVE__STRLWR 1
+/* These functions have security warnings, so we won't use them */
+/* #undef HAVE__STRUPR */
+/* #undef HAVE__STRLWR */
 #define HAVE_STRCHR 1
 #define HAVE_STRRCHR 1
 #define HAVE_STRSTR 1
-#define HAVE__LTOA 1
-#define HAVE__ULTOA 1
+/* These functions have security warnings, so we won't use them */
+/* #undef HAVE__LTOA */
+/* #undef HAVE__ULTOA */
 #define HAVE_STRTOL 1
 #define HAVE_STRTOUL 1
 #define HAVE_STRTOD 1
@@ -125,30 +130,45 @@ typedef unsigned int uintptr_t;
 #define HAVE_STRNCMP 1
 #define HAVE__STRICMP 1
 #define HAVE__STRNICMP 1
-#define HAVE_ATAN 1
-#define HAVE_ATAN2 1
-#define HAVE_ACOS  1
-#define HAVE_ASIN  1
-#define HAVE_CEIL 1
-#define HAVE_COS 1
-#define HAVE_COSF 1
-#define HAVE_FABS 1
-#define HAVE_FLOOR 1
-#define HAVE_LOG 1
-#define HAVE_POW 1
-#define HAVE_SIN 1
-#define HAVE_SINF 1
-#define HAVE_SQRT 1
-#define HAVE_SQRTF 1
-#define HAVE_TAN 1
-#define HAVE_TANF 1
-#define HAVE__COPYSIGN 1
+#define HAVE_ACOS   1
+#define HAVE_ACOSF  1
+#define HAVE_ASIN   1
+#define HAVE_ASINF  1
+#define HAVE_ATAN   1
+#define HAVE_ATANF  1
+#define HAVE_ATAN2  1
+#define HAVE_ATAN2F 1
+#define HAVE_CEILF  1
+#define HAVE__COPYSIGN  1
+#define HAVE_COS    1
+#define HAVE_COSF   1
+#define HAVE_EXP    1
+#define HAVE_EXPF   1
+#define HAVE_FABS   1
+#define HAVE_FABSF  1
+#define HAVE_FLOOR  1
+#define HAVE_FLOORF 1
+#define HAVE_FMOD   1
+#define HAVE_FMODF  1
+#define HAVE_LOG    1
+#define HAVE_LOGF   1
+#define HAVE_LOG10  1
+#define HAVE_LOG10F 1
+#define HAVE_POW    1
+#define HAVE_POWF   1
+#define HAVE_SIN    1
+#define HAVE_SINF   1
+#define HAVE_SQRT   1
+#define HAVE_SQRTF  1
+#define HAVE_TAN    1
+#define HAVE_TANF   1
 #if defined(_MSC_VER)
 /* These functions were added with the VC++ 2013 C runtime library */
 #if _MSC_VER >= 1800
 #define HAVE_STRTOLL 1
 #define HAVE_VSSCANF 1
 #define HAVE_SCALBN 1
+#define HAVE_SCALBNF    1
 #endif
 /* This function is available with at least the VC++ 2008 C runtime library */
 #if _MSC_VER >= 1400
@@ -166,7 +186,6 @@ typedef unsigned int uintptr_t;
 /* Enable various audio drivers */
 #define SDL_AUDIO_DRIVER_WASAPI 1
 #define SDL_AUDIO_DRIVER_DSOUND 1
-#define SDL_AUDIO_DRIVER_XAUDIO2    0
 #define SDL_AUDIO_DRIVER_WINMM  1
 #define SDL_AUDIO_DRIVER_DISK   1
 #define SDL_AUDIO_DRIVER_DUMMY  1
@@ -174,9 +193,13 @@ typedef unsigned int uintptr_t;
 /* Enable various input drivers */
 #define SDL_JOYSTICK_DINPUT 1
 #define SDL_JOYSTICK_XINPUT 1
+#define SDL_JOYSTICK_HIDAPI 1
 #define SDL_HAPTIC_DINPUT   1
 #define SDL_HAPTIC_XINPUT   1
 
+/* Enable the dummy sensor driver */
+#define SDL_SENSOR_DUMMY  1
+
 /* Enable various shared object loading systems */
 #define SDL_LOADSO_WINDOWS  1
 
@@ -194,7 +217,7 @@ typedef unsigned int uintptr_t;
 #define SDL_VIDEO_RENDER_D3D    1
 #endif
 #ifndef SDL_VIDEO_RENDER_D3D11
-#define SDL_VIDEO_RENDER_D3D11	0
+#define SDL_VIDEO_RENDER_D3D11  0
 #endif
 
 /* Enable OpenGL support */
diff --git a/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_cpuinfo.h b/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_cpuinfo.h
index 94b64b03b..ee3a47e84 100644
--- a/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_cpuinfo.h
+++ b/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_cpuinfo.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
@@ -51,27 +51,35 @@
 #include <intrin.h>
 #else
 #ifdef __ALTIVEC__
-#if HAVE_ALTIVEC_H && !defined(__APPLE_ALTIVEC__)
+#if defined(HAVE_ALTIVEC_H) && !defined(__APPLE_ALTIVEC__) && !defined(SDL_DISABLE_ALTIVEC_H)
 #include <altivec.h>
 #undef pixel
+#undef bool
 #endif
 #endif
-#ifdef __MMX__
-#include <mmintrin.h>
+#if defined(__ARM_NEON__) && !defined(SDL_DISABLE_ARM_NEON_H)
+#include <arm_neon.h>
 #endif
-#ifdef __3dNOW__
+#if defined(__3dNOW__) && !defined(SDL_DISABLE_MM3DNOW_H)
 #include <mm3dnow.h>
 #endif
-#ifdef __SSE__
+#if defined(HAVE_IMMINTRIN_H) && !defined(SDL_DISABLE_IMMINTRIN_H)
+#include <immintrin.h>
+#else
+#if defined(__MMX__) && !defined(SDL_DISABLE_MMINTRIN_H)
+#include <mmintrin.h>
+#endif
+#if defined(__SSE__) && !defined(SDL_DISABLE_XMMINTRIN_H)
 #include <xmmintrin.h>
 #endif
-#ifdef __SSE2__
+#if defined(__SSE2__) && !defined(SDL_DISABLE_EMMINTRIN_H)
 #include <emmintrin.h>
 #endif
-#ifdef __SSE3__
+#if defined(__SSE3__) && !defined(SDL_DISABLE_PMMINTRIN_H)
 #include <pmmintrin.h>
 #endif
-#endif
+#endif /* HAVE_IMMINTRIN_H */
+#endif /* compiler version */
 
 #include "begin_code.h"
 /* Set up for C function definitions, even when using C++ */
@@ -154,6 +162,11 @@ extern DECLSPEC SDL_bool SDLCALL SDL_HasAVX(void);
  */
 extern DECLSPEC SDL_bool SDLCALL SDL_HasAVX2(void);
 
+/**
+ *  This function returns true if the CPU has AVX-512F (foundation) features.
+ */
+extern DECLSPEC SDL_bool SDLCALL SDL_HasAVX512F(void);
+
 /**
  *  This function returns true if the CPU has NEON (ARM SIMD) features.
  */
@@ -164,7 +177,6 @@ extern DECLSPEC SDL_bool SDLCALL SDL_HasNEON(void);
  */
 extern DECLSPEC int SDLCALL SDL_GetSystemRAM(void);
 
-
 /* Ends C function definitions when using C++ */
 #ifdef __cplusplus
 }
diff --git a/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_egl.h b/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_egl.h
index e47fbe862..d65ed437c 100644
--- a/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_egl.h
+++ b/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_egl.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
@@ -24,7 +24,7 @@
  *
  *  This is a simple file to encapsulate the EGL API headers.
  */
-#ifndef _MSC_VER
+#if !defined(_MSC_VER) && !defined(__ANDROID__)
 
 #include <EGL/egl.h>
 #include <EGL/eglext.h>
diff --git a/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_endian.h b/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_endian.h
index 3eda7f287..ed0bf5ba8 100644
--- a/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_endian.h
+++ b/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_endian.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_error.h b/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_error.h
index 49be9827e..c0e46298e 100644
--- a/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_error.h
+++ b/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_error.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_events.h b/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_events.h
index 0fc09bc37..af22eb646 100644
--- a/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_events.h
+++ b/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_events.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
@@ -85,6 +85,9 @@ typedef enum
                                      Called on Android in onResume()
                                 */
 
+    /* Display events */
+    SDL_DISPLAYEVENT   = 0x150,  /**< Display state change */
+
     /* Window events */
     SDL_WINDOWEVENT    = 0x200, /**< Window state change */
     SDL_SYSWMEVENT,             /**< System specific event */
@@ -144,6 +147,9 @@ typedef enum
     SDL_AUDIODEVICEADDED = 0x1100, /**< A new audio device is available */
     SDL_AUDIODEVICEREMOVED,        /**< An audio device has been removed. */
 
+    /* Sensor events */
+    SDL_SENSORUPDATE = 0x1200,     /**< A sensor was updated */
+
     /* Render events */
     SDL_RENDER_TARGETS_RESET = 0x2000, /**< The render targets have been reset and their contents need to be updated */
     SDL_RENDER_DEVICE_RESET, /**< The device has been reset and all textures need to be recreated */
@@ -168,6 +174,21 @@ typedef struct SDL_CommonEvent
     Uint32 timestamp;   /**< In milliseconds, populated using SDL_GetTicks() */
 } SDL_CommonEvent;
 
+/**
+ *  \brief Display state change event data (event.display.*)
+ */
+typedef struct SDL_DisplayEvent
+{
+    Uint32 type;        /**< ::SDL_DISPLAYEVENT */
+    Uint32 timestamp;   /**< In milliseconds, populated using SDL_GetTicks() */
+    Uint32 display;     /**< The associated display index */
+    Uint8 event;        /**< ::SDL_DisplayEventID */
+    Uint8 padding1;
+    Uint8 padding2;
+    Uint8 padding3;
+    Sint32 data1;       /**< event dependent data */
+} SDL_DisplayEvent;
+
 /**
  *  \brief Window state change event data (event.window.*)
  */
@@ -471,6 +492,17 @@ typedef struct SDL_DropEvent
 } SDL_DropEvent;
 
 
+/**
+ *  \brief Sensor event structure (event.sensor.*)
+ */
+typedef struct SDL_SensorEvent
+{
+    Uint32 type;        /**< ::SDL_SENSORUPDATE */
+    Uint32 timestamp;   /**< In milliseconds, populated using SDL_GetTicks() */
+    Sint32 which;       /**< The instance ID of the sensor */
+    float data[6];      /**< Up to 6 values from the sensor - additional values can be queried using SDL_SensorGetData() */
+} SDL_SensorEvent;
+
 /**
  *  \brief The "quit requested" event
  */
@@ -526,6 +558,7 @@ typedef union SDL_Event
 {
     Uint32 type;                    /**< Event type, shared with all events */
     SDL_CommonEvent common;         /**< Common event data */
+    SDL_DisplayEvent display;       /**< Window event data */
     SDL_WindowEvent window;         /**< Window event data */
     SDL_KeyboardEvent key;          /**< Keyboard event data */
     SDL_TextEditingEvent edit;      /**< Text editing event data */
@@ -542,6 +575,7 @@ typedef union SDL_Event
     SDL_ControllerButtonEvent cbutton;  /**< Game Controller button event data */
     SDL_ControllerDeviceEvent cdevice;  /**< Game Controller device event data */
     SDL_AudioDeviceEvent adevice;   /**< Audio device event data */
+    SDL_SensorEvent sensor;         /**< Sensor event data */
     SDL_QuitEvent quit;             /**< Quit request event data */
     SDL_UserEvent user;             /**< Custom event data */
     SDL_SysWMEvent syswm;           /**< System dependent window event data */
diff --git a/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_filesystem.h b/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_filesystem.h
index a1c846ad0..fa6a1fa6e 100644
--- a/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_filesystem.h
+++ b/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_filesystem.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_gamecontroller.h b/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_gamecontroller.h
index c9215132e..6ae9c9542 100644
--- a/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_gamecontroller.h
+++ b/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_gamecontroller.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
@@ -175,6 +175,14 @@ extern DECLSPEC SDL_bool SDLCALL SDL_IsGameController(int joystick_index);
  */
 extern DECLSPEC const char *SDLCALL SDL_GameControllerNameForIndex(int joystick_index);
 
+/**
+ *  Get the mapping of a game controller.
+ *  This can be called before any controllers are opened.
+ *
+ *  \return the mapping string.  Must be freed with SDL_free().  Returns NULL if no mapping is available
+ */
+extern DECLSPEC char *SDLCALL SDL_GameControllerMappingForDeviceIndex(int joystick_index);
+
 /**
  *  Open a game controller for use.
  *  The index passed as an argument refers to the N'th game controller on the system.
@@ -196,6 +204,13 @@ extern DECLSPEC SDL_GameController *SDLCALL SDL_GameControllerFromInstanceID(SDL
  */
 extern DECLSPEC const char *SDLCALL SDL_GameControllerName(SDL_GameController *gamecontroller);
 
+/**
+ *  Get the player index of an opened game controller, or -1 if it's not available
+ *
+ *  For XInput controllers this returns the XInput user index.
+ */
+extern DECLSPEC int SDLCALL SDL_GameControllerGetPlayerIndex(SDL_GameController *gamecontroller);
+
 /**
  *  Get the USB vendor ID of an opened controller, if available.
  *  If the vendor ID isn't available this function returns 0.
@@ -345,6 +360,19 @@ SDL_GameControllerGetBindForButton(SDL_GameController *gamecontroller,
 extern DECLSPEC Uint8 SDLCALL SDL_GameControllerGetButton(SDL_GameController *gamecontroller,
                                                           SDL_GameControllerButton button);
 
+/**
+ *  Trigger a rumble effect
+ *  Each call to this function cancels any previous rumble effect, and calling it with 0 intensity stops any rumbling.
+ *
+ *  \param gamecontroller The controller to vibrate
+ *  \param low_frequency_rumble The intensity of the low frequency (left) rumble motor, from 0 to 0xFFFF
+ *  \param high_frequency_rumble The intensity of the high frequency (right) rumble motor, from 0 to 0xFFFF
+ *  \param duration_ms The duration of the rumble effect, in milliseconds
+ *
+ *  \return 0, or -1 if rumble isn't supported on this joystick
+ */
+extern DECLSPEC int SDLCALL SDL_GameControllerRumble(SDL_GameController *gamecontroller, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble, Uint32 duration_ms);
+
 /**
  *  Close a controller previously opened with SDL_GameControllerOpen().
  */
diff --git a/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_gesture.h b/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_gesture.h
index 2bba6a729..b223d80d4 100644
--- a/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_gesture.h
+++ b/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_gesture.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_haptic.h b/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_haptic.h
index 60daefaa7..2ea1bfc16 100644
--- a/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_haptic.h
+++ b/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_haptic.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
@@ -117,6 +117,17 @@
 extern "C" {
 #endif /* __cplusplus */
 
+/* FIXME: For SDL 2.1, adjust all the magnitude variables to be Uint16 (0xFFFF).
+ *
+ * At the moment the magnitude variables are mixed between signed/unsigned, and
+ * it is also not made clear that ALL of those variables expect a max of 0x7FFF.
+ *
+ * Some platforms may have higher precision than that (Linux FF, Windows XInput)
+ * so we should fix the inconsistency in favor of higher possible precision,
+ * adjusting for platforms that use different scales.
+ * -flibit
+ */
+
 /**
  *  \typedef SDL_Haptic
  *
@@ -656,8 +667,8 @@ typedef struct SDL_HapticRamp
  * This struct is exclusively for the ::SDL_HAPTIC_LEFTRIGHT effect.
  *
  * The Left/Right effect is used to explicitly control the large and small
- * motors, commonly found in modern game controllers. One motor is high
- * frequency, the other is low frequency.
+ * motors, commonly found in modern game controllers. The small (right) motor
+ * is high frequency, and the large (left) motor is low frequency.
  *
  * \sa SDL_HAPTIC_LEFTRIGHT
  * \sa SDL_HapticEffect
@@ -668,7 +679,7 @@ typedef struct SDL_HapticLeftRight
     Uint16 type;            /**< ::SDL_HAPTIC_LEFTRIGHT */
 
     /* Replay */
-    Uint32 length;          /**< Duration of the effect. */
+    Uint32 length;          /**< Duration of the effect in milliseconds. */
 
     /* Rumble */
     Uint16 large_magnitude; /**< Control of the large controller motor. */
diff --git a/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_hints.h b/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_hints.h
index 007a4bee0..4ee72e97d 100644
--- a/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_hints.h
+++ b/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_hints.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
@@ -76,6 +76,7 @@ extern "C" {
  *    "opengl"
  *    "opengles2"
  *    "opengles"
+ *    "metal"
  *    "software"
  *
  *  The default varies by platform, but it's the first one in the list that
@@ -210,6 +211,18 @@ extern "C" {
  */
 #define SDL_HINT_VIDEO_X11_NET_WM_PING      "SDL_VIDEO_X11_NET_WM_PING"
 
+/**
+ * \brief A variable controlling whether the X11 _NET_WM_BYPASS_COMPOSITOR hint should be used.
+ * 
+ * This variable can be set to the following values:
+ * "0" - Disable _NET_WM_BYPASS_COMPOSITOR
+ * "1" - Enable _NET_WM_BYPASS_COMPOSITOR
+ * 
+ * By default SDL will use _NET_WM_BYPASS_COMPOSITOR
+ * 
+ */
+#define SDL_HINT_VIDEO_X11_NET_WM_BYPASS_COMPOSITOR "SDL_VIDEO_X11_NET_WM_BYPASS_COMPOSITOR"
+
 /**
  *  \brief  A variable controlling whether the window frame and title bar are interactive when the cursor is hidden 
  *
@@ -249,6 +262,16 @@ extern "C" {
  */
 #define SDL_HINT_GRAB_KEYBOARD              "SDL_GRAB_KEYBOARD"
 
+/**
+ *  \brief  A variable setting the double click time, in milliseconds.
+ */
+#define SDL_HINT_MOUSE_DOUBLE_CLICK_TIME    "SDL_MOUSE_DOUBLE_CLICK_TIME"
+
+/**
+ *  \brief  A variable setting the double click radius, in pixels.
+ */
+#define SDL_HINT_MOUSE_DOUBLE_CLICK_RADIUS    "SDL_MOUSE_DOUBLE_CLICK_RADIUS"
+
 /**
  *  \brief  A variable setting the speed scale for mouse motion, in floating point, when the mouse is not in relative mode
  */
@@ -316,7 +339,7 @@ extern "C" {
 #define SDL_HINT_IDLE_TIMER_DISABLED "SDL_IOS_IDLE_TIMER_DISABLED"
 
 /**
- *  \brief  A variable controlling which orientations are allowed on iOS.
+ *  \brief  A variable controlling which orientations are allowed on iOS/Android.
  *
  *  In some circumstances it is necessary to be able to explicitly control
  *  which UI orientations are allowed.
@@ -355,16 +378,36 @@ extern "C" {
 #define SDL_HINT_APPLE_TV_REMOTE_ALLOW_ROTATION "SDL_APPLE_TV_REMOTE_ALLOW_ROTATION"
 
 /**
- *  \brief  A variable controlling whether the Android / iOS built-in
- *  accelerometer should be listed as a joystick device, rather than listing
- *  actual joysticks only.
+ * \brief  A variable controlling whether the home indicator bar on iPhone X
+ *         should be hidden.
  *
  *  This variable can be set to the following values:
- *    "0"       - List only real joysticks and accept input from them
- *    "1"       - List real joysticks along with the accelerometer as if it were a 3 axis joystick (the default).
+ *    "0"       - The indicator bar is not hidden (default for windowed applications)
+ *    "1"       - The indicator bar is hidden and is shown when the screen is touched (useful for movie playback applications)
+ *    "2"       - The indicator bar is dim and the first swipe makes it visible and the second swipe performs the "home" action (default for fullscreen applications)
+ */
+#define SDL_HINT_IOS_HIDE_HOME_INDICATOR "SDL_IOS_HIDE_HOME_INDICATOR"
+
+/**
+ *  \brief  A variable controlling whether the Android / iOS built-in
+ *  accelerometer should be listed as a joystick device.
+ *
+ *  This variable can be set to the following values:
+ *    "0"       - The accelerometer is not listed as a joystick
+ *    "1"       - The accelerometer is available as a 3 axis joystick (the default).
  */
 #define SDL_HINT_ACCELEROMETER_AS_JOYSTICK "SDL_ACCELEROMETER_AS_JOYSTICK"
 
+/**
+ *  \brief  A variable controlling whether the Android / tvOS remotes
+ *  should be listed as joystick devices, instead of sending keyboard events.
+ *
+ *  This variable can be set to the following values:
+ *    "0"       - Remotes send enter/escape/arrow key events
+ *    "1"       - Remotes are available as 2 axis, 2 button joysticks (the default).
+ */
+#define SDL_HINT_TV_REMOTE_AS_JOYSTICK "SDL_TV_REMOTE_AS_JOYSTICK"
+
 /**
  *  \brief  A variable that lets you disable the detection and use of Xinput gamepad devices
  *
@@ -432,6 +475,88 @@ extern "C" {
  */
 #define SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS "SDL_JOYSTICK_ALLOW_BACKGROUND_EVENTS"
 
+/**
+ *  \brief  A variable controlling whether the HIDAPI joystick drivers should be used.
+ *
+ *  This variable can be set to the following values:
+ *    "0"       - HIDAPI drivers are not used
+ *    "1"       - HIDAPI drivers are used (the default)
+ *
+ *  This variable is the default for all drivers, but can be overridden by the hints for specific drivers below.
+ */
+#define SDL_HINT_JOYSTICK_HIDAPI "SDL_JOYSTICK_HIDAPI"
+
+/**
+ *  \brief  A variable controlling whether the HIDAPI driver for PS4 controllers should be used.
+ *
+ *  This variable can be set to the following values:
+ *    "0"       - HIDAPI driver is not used
+ *    "1"       - HIDAPI driver is used
+ *
+ *  The default is the value of SDL_HINT_JOYSTICK_HIDAPI
+ */
+#define SDL_HINT_JOYSTICK_HIDAPI_PS4 "SDL_JOYSTICK_HIDAPI_PS4"
+
+/**
+ *  \brief  A variable controlling whether extended input reports should be used for PS4 controllers when using the HIDAPI driver.
+ *
+ *  This variable can be set to the following values:
+ *    "0"       - extended reports are not enabled (the default)
+ *    "1"       - extended reports
+ *
+ *  Extended input reports allow rumble on Bluetooth PS4 controllers, but
+ *  break DirectInput handling for applications that don't use SDL.
+ *
+ *  Once extended reports are enabled, they can not be disabled without
+ *  power cycling the controller.
+ */
+#define SDL_HINT_JOYSTICK_HIDAPI_PS4_RUMBLE "SDL_JOYSTICK_HIDAPI_PS4_RUMBLE"
+
+/**
+ *  \brief  A variable controlling whether the HIDAPI driver for Steam Controllers should be used.
+ *
+ *  This variable can be set to the following values:
+ *    "0"       - HIDAPI driver is not used
+ *    "1"       - HIDAPI driver is used
+ *
+ *  The default is the value of SDL_HINT_JOYSTICK_HIDAPI
+ */
+#define SDL_HINT_JOYSTICK_HIDAPI_STEAM "SDL_JOYSTICK_HIDAPI_STEAM"
+
+/**
+ *  \brief  A variable controlling whether the HIDAPI driver for Nintendo Switch controllers should be used.
+ *
+ *  This variable can be set to the following values:
+ *    "0"       - HIDAPI driver is not used
+ *    "1"       - HIDAPI driver is used
+ *
+ *  The default is the value of SDL_HINT_JOYSTICK_HIDAPI
+ */
+#define SDL_HINT_JOYSTICK_HIDAPI_SWITCH "SDL_JOYSTICK_HIDAPI_SWITCH"
+
+/**
+ *  \brief  A variable controlling whether the HIDAPI driver for XBox controllers should be used.
+ *
+ *  This variable can be set to the following values:
+ *    "0"       - HIDAPI driver is not used
+ *    "1"       - HIDAPI driver is used
+ *
+ *  The default is the value of SDL_HINT_JOYSTICK_HIDAPI
+ */
+#define SDL_HINT_JOYSTICK_HIDAPI_XBOX   "SDL_JOYSTICK_HIDAPI_XBOX"
+
+/**
+ *  \brief  A variable that controls whether Steam Controllers should be exposed using the SDL joystick and game controller APIs
+ *
+ *  The variable can be set to the following values:
+ *    "0"       - Do not scan for Steam Controllers
+ *    "1"       - Scan for Steam Controllers (the default)
+ *
+ *  The default value is "1".  This hint must be set before initializing the joystick subsystem.
+ */
+#define SDL_HINT_ENABLE_STEAM_CONTROLLERS "SDL_ENABLE_STEAM_CONTROLLERS"
+
+
 /**
  *  \brief If set to "0" then never set the top most bit on a SDL Window, even if the video mode expects it.
  *      This is a debugging aid for developers and not expected to be used by end users. The default is "1"
@@ -494,6 +619,10 @@ extern "C" {
 *  This is specially useful if you build SDL against a non glibc libc library (such as musl) which
 *  provides a relatively small default thread stack size (a few kilobytes versus the default 8MB glibc uses).
 *  Support for this hint is currently available only in the pthread, Windows, and PSP backend.
+*
+*  Instead of this hint, in 2.0.9 and later, you can use
+*  SDL_CreateThreadWithStackSize(). This hint only works with the classic
+*  SDL_CreateThread().
 */
 #define SDL_HINT_THREAD_STACK_SIZE              "SDL_THREAD_STACK_SIZE"
 
@@ -719,6 +848,35 @@ extern "C" {
  */
 #define SDL_HINT_ANDROID_SEPARATE_MOUSE_AND_TOUCH "SDL_ANDROID_SEPARATE_MOUSE_AND_TOUCH"
 
+ /**
+ * \brief A variable to control whether we trap the Android back button to handle it manually.
+ *        This is necessary for the right mouse button to work on some Android devices, or
+ *        to be able to trap the back button for use in your code reliably.  If set to true,
+ *        the back button will show up as an SDL_KEYDOWN / SDL_KEYUP pair with a keycode of 
+ *        SDL_SCANCODE_AC_BACK.
+ *
+ * The variable can be set to the following values:
+ *   "0"       - Back button will be handled as usual for system. (default)
+ *   "1"       - Back button will be trapped, allowing you to handle the key press
+ *               manually.  (This will also let right mouse click work on systems 
+ *               where the right mouse button functions as back.)
+ *
+ * The value of this hint is used at runtime, so it can be changed at any time.
+ */
+#define SDL_HINT_ANDROID_TRAP_BACK_BUTTON "SDL_ANDROID_TRAP_BACK_BUTTON"
+
+ /**
+ * \brief A variable to control whether the return key on the soft keyboard
+ *        should hide the soft keyboard on Android and iOS.
+ *
+ * The variable can be set to the following values:
+ *   "0"       - The return key will be handled as a key event. This is the behaviour of SDL <= 2.0.3. (default)
+ *   "1"       - The return key will hide the keyboard.
+ *
+ * The value of this hint is used at runtime, so it can be changed at any time.
+ */
+#define SDL_HINT_RETURN_KEY_HIDES_IME "SDL_RETURN_KEY_HIDES_IME"
+
 /**
  *  \brief override the binding element for keyboard inputs for Emscripten builds
  *
@@ -752,7 +910,7 @@ extern "C" {
  *   "0"       - SDL will generate a window-close event when it sees Alt+F4.
  *   "1"       - SDL will only do normal key handling for Alt+F4.
  */
-#define SDL_HINT_WINDOWS_NO_CLOSE_ON_ALT_F4	"SDL_WINDOWS_NO_CLOSE_ON_ALT_F4"
+#define SDL_HINT_WINDOWS_NO_CLOSE_ON_ALT_F4 "SDL_WINDOWS_NO_CLOSE_ON_ALT_F4"
 
 /**
  *  \brief Prevent SDL from using version 4 of the bitmap header when saving BMPs.
@@ -797,6 +955,24 @@ extern "C" {
  */
 #define SDL_HINT_RPI_VIDEO_LAYER           "SDL_RPI_VIDEO_LAYER"
 
+/**
+ * \brief Tell the video driver that we only want a double buffer.
+ *
+ * By default, most lowlevel 2D APIs will use a triple buffer scheme that 
+ * wastes no CPU time on waiting for vsync after issuing a flip, but
+ * introduces a frame of latency. On the other hand, using a double buffer
+ * scheme instead is recommended for cases where low latency is an important
+ * factor because we save a whole frame of latency.
+ * We do so by waiting for vsync immediately after issuing a flip, usually just
+ * after eglSwapBuffers call in the backend's *_SwapWindow function.
+ *
+ * Since it's driver-specific, it's only supported where possible and
+ * implemented. Currently supported the following drivers:
+ * - KMSDRM (kmsdrm)
+ * - Raspberry Pi (raspberrypi)
+ */
+#define SDL_HINT_VIDEO_DOUBLE_BUFFER      "SDL_VIDEO_DOUBLE_BUFFER"
+
 /**
  *  \brief  A variable controlling what driver to use for OpenGL ES contexts.
  *
diff --git a/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_joystick.h b/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_joystick.h
index f598dc828..6e05a9c20 100644
--- a/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_joystick.h
+++ b/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_joystick.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
@@ -97,10 +97,10 @@ typedef enum
 typedef enum
 {
     SDL_JOYSTICK_POWER_UNKNOWN = -1,
-    SDL_JOYSTICK_POWER_EMPTY,
-    SDL_JOYSTICK_POWER_LOW,
-    SDL_JOYSTICK_POWER_MEDIUM,
-    SDL_JOYSTICK_POWER_FULL,
+    SDL_JOYSTICK_POWER_EMPTY,   /* <= 5% */
+    SDL_JOYSTICK_POWER_LOW,     /* <= 20% */
+    SDL_JOYSTICK_POWER_MEDIUM,  /* <= 70% */
+    SDL_JOYSTICK_POWER_FULL,    /* <= 100% */
     SDL_JOYSTICK_POWER_WIRED,
     SDL_JOYSTICK_POWER_MAX
 } SDL_JoystickPowerLevel;
@@ -132,6 +132,12 @@ extern DECLSPEC int SDLCALL SDL_NumJoysticks(void);
  */
 extern DECLSPEC const char *SDLCALL SDL_JoystickNameForIndex(int device_index);
 
+/**
+ *  Get the player index of a joystick, or -1 if it's not available
+ *  This can be called before any joysticks are opened.
+ */
+extern DECLSPEC int SDLCALL SDL_JoystickGetDevicePlayerIndex(int device_index);
+
 /**
  *  Return the GUID for the joystick at this index
  *  This can be called before any joysticks are opened.
@@ -194,6 +200,13 @@ extern DECLSPEC SDL_Joystick *SDLCALL SDL_JoystickFromInstanceID(SDL_JoystickID
  */
 extern DECLSPEC const char *SDLCALL SDL_JoystickName(SDL_Joystick * joystick);
 
+/**
+ *  Get the player index of an opened joystick, or -1 if it's not available
+ *
+ *  For XInput controllers this returns the XInput user index.
+ */
+extern DECLSPEC int SDLCALL SDL_JoystickGetPlayerIndex(SDL_Joystick * joystick);
+
 /**
  *  Return the GUID for this opened joystick
  */
@@ -361,6 +374,19 @@ extern DECLSPEC int SDLCALL SDL_JoystickGetBall(SDL_Joystick * joystick,
 extern DECLSPEC Uint8 SDLCALL SDL_JoystickGetButton(SDL_Joystick * joystick,
                                                     int button);
 
+/**
+ *  Trigger a rumble effect
+ *  Each call to this function cancels any previous rumble effect, and calling it with 0 intensity stops any rumbling.
+ *
+ *  \param joystick The joystick to vibrate
+ *  \param low_frequency_rumble The intensity of the low frequency (left) rumble motor, from 0 to 0xFFFF
+ *  \param high_frequency_rumble The intensity of the high frequency (right) rumble motor, from 0 to 0xFFFF
+ *  \param duration_ms The duration of the rumble effect, in milliseconds
+ *
+ *  \return 0, or -1 if rumble isn't supported on this joystick
+ */
+extern DECLSPEC int SDLCALL SDL_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble, Uint32 duration_ms);
+
 /**
  *  Close a joystick previously opened with SDL_JoystickOpen().
  */
diff --git a/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_keyboard.h b/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_keyboard.h
index e78ca4690..874823171 100644
--- a/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_keyboard.h
+++ b/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_keyboard.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_keycode.h b/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_keycode.h
index c41e45ff6..d7d5b1dbc 100644
--- a/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_keycode.h
+++ b/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_keycode.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_loadso.h b/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_loadso.h
index 6ea256c6a..da56fb452 100644
--- a/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_loadso.h
+++ b/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_loadso.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_log.h b/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_log.h
index 356d0e1cf..e12b65886 100644
--- a/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_log.h
+++ b/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_log.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_main.h b/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_main.h
index 2af32360f..98558217f 100644
--- a/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_main.h
+++ b/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_main.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
@@ -63,10 +63,13 @@
 /* On Android SDL provides a Java class in SDLActivity.java that is the
    main activity entry point.
 
-   See README-android.md for more details on extending that class.
+   See docs/README-android.md for more details on extending that class.
  */
 #define SDL_MAIN_NEEDED
 
+/* We need to export SDL_main so it can be launched from Java */
+#define SDLMAIN_DECLSPEC    DECLSPEC
+
 #elif defined(__NACL__)
 /* On NACL we use ppapi_simple to set up the application helper code,
    then wait for the first PSE_INSTANCE_DIDCHANGEVIEW event before 
@@ -85,6 +88,10 @@
 #define C_LINKAGE
 #endif /* __cplusplus */
 
+#ifndef SDLMAIN_DECLSPEC
+#define SDLMAIN_DECLSPEC
+#endif
+
 /**
  *  \file SDL_main.h
  *
@@ -107,7 +114,7 @@
 /**
  *  The prototype for the application's main() function
  */
-extern C_LINKAGE DECLSPEC int SDL_main(int argc, char *argv[]);
+extern C_LINKAGE SDLMAIN_DECLSPEC int SDL_main(int argc, char *argv[]);
 
 
 #include "begin_code.h"
diff --git a/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_messagebox.h b/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_messagebox.h
index c326d8f01..b7be59d88 100644
--- a/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_messagebox.h
+++ b/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_messagebox.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_mouse.h b/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_mouse.h
index 6001bd46c..d3c9f6156 100644
--- a/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_mouse.h
+++ b/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_mouse.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_mutex.h b/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_mutex.h
index 0272379e5..ba4247ced 100644
--- a/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_mutex.h
+++ b/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_mutex.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_name.h b/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_name.h
index 8095ed3ff..ecd863f4c 100644
--- a/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_name.h
+++ b/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_name.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_opengl.h b/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_opengl.h
index 314dd57ed..253d9c93a 100644
--- a/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_opengl.h
+++ b/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_opengl.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_opengles.h b/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_opengles.h
index 800c59307..18dd984b3 100644
--- a/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_opengles.h
+++ b/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_opengles.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_opengles2.h b/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_opengles2.h
index 102f2f3fa..6ccecf216 100644
--- a/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_opengles2.h
+++ b/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_opengles2.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_pixels.h b/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_pixels.h
index 04246689f..0b4364b18 100644
--- a/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_pixels.h
+++ b/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_pixels.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
@@ -287,7 +287,9 @@ enum
     SDL_PIXELFORMAT_NV12 =      /**< Planar mode: Y + U/V interleaved  (2 planes) */
         SDL_DEFINE_PIXELFOURCC('N', 'V', '1', '2'),
     SDL_PIXELFORMAT_NV21 =      /**< Planar mode: Y + V/U interleaved  (2 planes) */
-        SDL_DEFINE_PIXELFOURCC('N', 'V', '2', '1')
+        SDL_DEFINE_PIXELFOURCC('N', 'V', '2', '1'),
+    SDL_PIXELFORMAT_EXTERNAL_OES =      /**< Android video texture format */
+        SDL_DEFINE_PIXELFOURCC('O', 'E', 'S', ' ')
 };
 
 typedef struct SDL_Color
diff --git a/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_platform.h b/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_platform.h
index 9dde385fa..7dea4ce94 100644
--- a/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_platform.h
+++ b/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_platform.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
@@ -121,7 +121,12 @@
 #if defined(WIN32) || defined(_WIN32) || defined(__CYGWIN__) || defined(__MINGW32__)
 /* Try to find out if we're compiling for WinRT or non-WinRT */
 #if defined(_MSC_VER) && defined(__has_include)
-#define HAVE_WINAPIFAMILY_H __has_include(<winapifamily.h>)
+#if __has_include(<winapifamily.h>)
+#define HAVE_WINAPIFAMILY_H 1
+#else
+#define HAVE_WINAPIFAMILY_H 0
+#endif
+
 /* If _USING_V110_SDK71_ is defined it means we are using the Windows XP toolset. */
 #elif defined(_MSC_VER) && (_MSC_VER >= 1700 && !_USING_V110_SDK71_)    /* _MSC_VER == 1700 for Visual Studio 2012 */
 #define HAVE_WINAPIFAMILY_H 1
diff --git a/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_power.h b/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_power.h
index d48e8a379..a4fe8a935 100644
--- a/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_power.h
+++ b/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_power.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_quit.h b/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_quit.h
index 9283c3810..fea56a8d8 100644
--- a/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_quit.h
+++ b/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_quit.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_rect.h b/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_rect.h
index c4f6d74b3..543bb6186 100644
--- a/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_rect.h
+++ b/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_rect.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_render.h b/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_render.h
index ea6ef9ff6..d33619297 100644
--- a/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_render.h
+++ b/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_render.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
@@ -898,6 +898,27 @@ extern DECLSPEC int SDLCALL SDL_GL_BindTexture(SDL_Texture *texture, float *texw
  */
 extern DECLSPEC int SDLCALL SDL_GL_UnbindTexture(SDL_Texture *texture);
 
+/**
+ *  \brief Get the CAMetalLayer associated with the given Metal renderer
+ *
+ *  \param renderer The renderer to query
+ *
+ *  \return CAMetalLayer* on success, or NULL if the renderer isn't a Metal renderer
+ *
+ *  \sa SDL_RenderGetMetalCommandEncoder()
+ */
+extern DECLSPEC void *SDLCALL SDL_RenderGetMetalLayer(SDL_Renderer * renderer);
+
+/**
+ *  \brief Get the Metal command encoder for the current frame
+ *
+ *  \param renderer The renderer to query
+ *
+ *  \return id<MTLRenderCommandEncoder> on success, or NULL if the renderer isn't a Metal renderer
+ *
+ *  \sa SDL_RenderGetMetalLayer()
+ */
+extern DECLSPEC void *SDLCALL SDL_RenderGetMetalCommandEncoder(SDL_Renderer * renderer);
 
 /* Ends C function definitions when using C++ */
 #ifdef __cplusplus
diff --git a/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_revision.h b/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_revision.h
index 9376093ee..92fbe67b1 100644
--- a/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_revision.h
+++ b/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_revision.h
@@ -1,2 +1,2 @@
-#define SDL_REVISION "hg-11645:2088cd828335"
-#define SDL_REVISION_NUMBER 11645
+#define SDL_REVISION "hg-12373:8feb5da6f2fb"
+#define SDL_REVISION_NUMBER 12373
diff --git a/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_rwops.h b/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_rwops.h
index 7f0cbdfd5..0960699d4 100644
--- a/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_rwops.h
+++ b/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_rwops.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_scancode.h b/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_scancode.h
index 1d5521204..63871aa3b 100644
--- a/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_scancode.h
+++ b/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_scancode.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_sensor.h b/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_sensor.h
new file mode 100644
index 000000000..ac163a8cd
--- /dev/null
+++ b/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_sensor.h
@@ -0,0 +1,251 @@
+/*
+  Simple DirectMedia Layer
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+  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 SDL_sensor.h
+ *
+ *  Include file for SDL sensor event handling
+ *
+ */
+
+#ifndef _SDL_sensor_h
+#define _SDL_sensor_h
+
+#include "SDL_stdinc.h"
+#include "SDL_error.h"
+
+#include "begin_code.h"
+/* Set up for C function definitions, even when using C++ */
+#ifdef __cplusplus
+/* *INDENT-OFF* */
+extern "C" {
+/* *INDENT-ON* */
+#endif
+
+/**
+ *  \brief SDL_sensor.h
+ *
+ *  In order to use these functions, SDL_Init() must have been called
+ *  with the ::SDL_INIT_SENSOR flag.  This causes SDL to scan the system
+ *  for sensors, and load appropriate drivers.
+ */
+
+struct _SDL_Sensor;
+typedef struct _SDL_Sensor SDL_Sensor;
+
+/**
+ * This is a unique ID for a sensor for the time it is connected to the system,
+ * and is never reused for the lifetime of the application.
+ *
+ * The ID value starts at 0 and increments from there. The value -1 is an invalid ID.
+ */
+typedef Sint32 SDL_SensorID;
+
+/* The different sensors defined by SDL
+ *
+ * Additional sensors may be available, using platform dependent semantics.
+ *
+ * Hare are the additional Android sensors:
+ * https://developer.android.com/reference/android/hardware/SensorEvent.html#values
+ */
+typedef enum
+{
+    SDL_SENSOR_INVALID = -1,    /**< Returned for an invalid sensor */
+    SDL_SENSOR_UNKNOWN,         /**< Unknown sensor type */
+    SDL_SENSOR_ACCEL,           /**< Accelerometer */
+    SDL_SENSOR_GYRO             /**< Gyroscope */
+} SDL_SensorType;
+
+/**
+ * Accelerometer sensor
+ *
+ * The accelerometer returns the current acceleration in SI meters per
+ * second squared. This includes gravity, so a device at rest will have
+ * an acceleration of SDL_STANDARD_GRAVITY straight down.
+ *
+ * values[0]: Acceleration on the x axis
+ * values[1]: Acceleration on the y axis
+ * values[2]: Acceleration on the z axis
+ *
+ * For phones held in portrait mode, the axes are defined as follows:
+ * -X ... +X : left ... right
+ * -Y ... +Y : bottom ... top
+ * -Z ... +Z : farther ... closer
+ * 
+ * The axis data is not changed when the phone is rotated.
+ *
+ * \sa SDL_GetDisplayOrientation()
+ */
+#define SDL_STANDARD_GRAVITY    9.80665f
+
+/**
+ * Gyroscope sensor
+ *
+ * The gyroscope returns the current rate of rotation in radians per second.
+ * The rotation is positive in the counter-clockwise direction. That is,
+ * an observer looking from a positive location on one of the axes would
+ * see positive rotation on that axis when it appeared to be rotating
+ * counter-clockwise.
+ *
+ * values[0]: Angular speed around the x axis
+ * values[1]: Angular speed around the y axis
+ * values[2]: Angular speed around the z axis
+ *
+ * For phones held in portrait mode, the axes are defined as follows:
+ * -X ... +X : left ... right
+ * -Y ... +Y : bottom ... top
+ * -Z ... +Z : farther ... closer
+ * 
+ * The axis data is not changed when the phone is rotated.
+ *
+ * \sa SDL_GetDisplayOrientation()
+ */
+
+/* Function prototypes */
+
+/**
+ *  \brief Count the number of sensors attached to the system right now
+ */
+extern DECLSPEC int SDLCALL SDL_NumSensors(void);
+
+/**
+ *  \brief Get the implementation dependent name of a sensor.
+ *
+ *  This can be called before any sensors are opened.
+ * 
+ *  \return The sensor name, or NULL if device_index is out of range.
+ */
+extern DECLSPEC const char *SDLCALL SDL_SensorGetDeviceName(int device_index);
+
+/**
+ *  \brief Get the type of a sensor.
+ *
+ *  This can be called before any sensors are opened.
+ *
+ *  \return The sensor type, or SDL_SENSOR_INVALID if device_index is out of range.
+ */
+extern DECLSPEC SDL_SensorType SDLCALL SDL_SensorGetDeviceType(int device_index);
+
+/**
+ *  \brief Get the platform dependent type of a sensor.
+ *
+ *  This can be called before any sensors are opened.
+ *
+ *  \return The sensor platform dependent type, or -1 if device_index is out of range.
+ */
+extern DECLSPEC int SDLCALL SDL_SensorGetDeviceNonPortableType(int device_index);
+
+/**
+ *  \brief Get the instance ID of a sensor.
+ *
+ *  This can be called before any sensors are opened.
+ *
+ *  \return The sensor instance ID, or -1 if device_index is out of range.
+ */
+extern DECLSPEC SDL_SensorID SDLCALL SDL_SensorGetDeviceInstanceID(int device_index);
+
+/**
+ *  \brief Open a sensor for use.
+ *
+ *  The index passed as an argument refers to the N'th sensor on the system.
+ *
+ *  \return A sensor identifier, or NULL if an error occurred.
+ */
+extern DECLSPEC SDL_Sensor *SDLCALL SDL_SensorOpen(int device_index);
+
+/**
+ * Return the SDL_Sensor associated with an instance id.
+ */
+extern DECLSPEC SDL_Sensor *SDLCALL SDL_SensorFromInstanceID(SDL_SensorID instance_id);
+
+/**
+ *  \brief Get the implementation dependent name of a sensor.
+ *
+ *  \return The sensor name, or NULL if the sensor is NULL.
+ */
+extern DECLSPEC const char *SDLCALL SDL_SensorGetName(SDL_Sensor *sensor);
+
+/**
+ *  \brief Get the type of a sensor.
+ *
+ *  This can be called before any sensors are opened.
+ *
+ *  \return The sensor type, or SDL_SENSOR_INVALID if the sensor is NULL.
+ */
+extern DECLSPEC SDL_SensorType SDLCALL SDL_SensorGetType(SDL_Sensor *sensor);
+
+/**
+ *  \brief Get the platform dependent type of a sensor.
+ *
+ *  This can be called before any sensors are opened.
+ *
+ *  \return The sensor platform dependent type, or -1 if the sensor is NULL.
+ */
+extern DECLSPEC int SDLCALL SDL_SensorGetNonPortableType(SDL_Sensor *sensor);
+
+/**
+ *  \brief Get the instance ID of a sensor.
+ *
+ *  This can be called before any sensors are opened.
+ *
+ *  \return The sensor instance ID, or -1 if the sensor is NULL.
+ */
+extern DECLSPEC SDL_SensorID SDLCALL SDL_SensorGetInstanceID(SDL_Sensor *sensor);
+
+/**
+ *  Get the current state of an opened sensor.
+ *
+ *  The number of values and interpretation of the data is sensor dependent.
+ *
+ *  \param sensor The sensor to query
+ *  \param data A pointer filled with the current sensor state
+ *  \param num_values The number of values to write to data
+ *
+ *  \return 0 or -1 if an error occurred.
+ */
+extern DECLSPEC int SDLCALL SDL_SensorGetData(SDL_Sensor * sensor, float *data, int num_values);
+
+/**
+ *  Close a sensor previously opened with SDL_SensorOpen()
+ */
+extern DECLSPEC void SDLCALL SDL_SensorClose(SDL_Sensor * sensor);
+
+/**
+ *  Update the current state of the open sensors.
+ *
+ *  This is called automatically by the event loop if sensor events are enabled.
+ *
+ *  This needs to be called from the thread that initialized the sensor subsystem.
+ */
+extern DECLSPEC void SDLCALL SDL_SensorUpdate(void);
+
+
+/* Ends C function definitions when using C++ */
+#ifdef __cplusplus
+/* *INDENT-OFF* */
+}
+/* *INDENT-ON* */
+#endif
+#include "close_code.h"
+
+#endif /* _SDL_sensor_h */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_shape.h b/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_shape.h
index 9e492d93a..40a6baaae 100644
--- a/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_shape.h
+++ b/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_shape.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_stdinc.h b/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_stdinc.h
index 72402299f..e373bc380 100644
--- a/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_stdinc.h
+++ b/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_stdinc.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
@@ -86,6 +86,28 @@
 #ifdef HAVE_FLOAT_H
 # include <float.h>
 #endif
+#if defined(HAVE_ALLOCA) && !defined(alloca)
+# if defined(HAVE_ALLOCA_H)
+#  include <alloca.h>
+# elif defined(__GNUC__)
+#  define alloca __builtin_alloca
+# elif defined(_MSC_VER)
+#  include <malloc.h>
+#  define alloca _alloca
+# elif defined(__WATCOMC__)
+#  include <malloc.h>
+# elif defined(__BORLANDC__)
+#  include <malloc.h>
+# elif defined(__DMC__)
+#  include <stdlib.h>
+# elif defined(__AIX__)
+#pragma alloca
+# elif defined(__MRC__)
+void *alloca(unsigned);
+# else
+char *alloca();
+# endif
+#endif
 
 /**
  *  The number of elements in an array.
@@ -328,28 +350,6 @@ SDL_COMPILE_TIME_ASSERT(enum, sizeof(SDL_DUMMY_ENUM) == sizeof(int));
 extern "C" {
 #endif
 
-#if defined(HAVE_ALLOCA) && !defined(alloca)
-# if defined(HAVE_ALLOCA_H)
-#  include <alloca.h>
-# elif defined(__GNUC__)
-#  define alloca __builtin_alloca
-# elif defined(_MSC_VER)
-#  include <malloc.h>
-#  define alloca _alloca
-# elif defined(__WATCOMC__)
-#  include <malloc.h>
-# elif defined(__BORLANDC__)
-#  include <malloc.h>
-# elif defined(__DMC__)
-#  include <stdlib.h>
-# elif defined(__AIX__)
-#pragma alloca
-# elif defined(__MRC__)
-void *alloca(unsigned);
-# else
-char *alloca();
-# endif
-#endif
 #ifdef HAVE_ALLOCA
 #define SDL_stack_alloc(type, count)    (type*)alloca(sizeof(type)*(count))
 #define SDL_stack_free(data)
@@ -445,12 +445,12 @@ SDL_FORCE_INLINE void SDL_memset4(void *dst, Uint32 val, size_t dwords)
 #endif
 }
 
-
 extern DECLSPEC void *SDLCALL SDL_memcpy(SDL_OUT_BYTECAP(len) void *dst, SDL_IN_BYTECAP(len) const void *src, size_t len);
 
 extern DECLSPEC void *SDLCALL SDL_memmove(SDL_OUT_BYTECAP(len) void *dst, SDL_IN_BYTECAP(len) const void *src, size_t len);
 extern DECLSPEC int SDLCALL SDL_memcmp(const void *s1, const void *s2, size_t len);
 
+extern DECLSPEC wchar_t *SDLCALL SDL_wcsdup(const wchar_t *wstr);
 extern DECLSPEC size_t SDLCALL SDL_wcslen(const wchar_t *wstr);
 extern DECLSPEC size_t SDLCALL SDL_wcslcpy(SDL_OUT_Z_CAP(maxlen) wchar_t *dst, const wchar_t *src, size_t maxlen);
 extern DECLSPEC size_t SDLCALL SDL_wcslcat(SDL_INOUT_Z_CAP(maxlen) wchar_t *dst, const wchar_t *src, size_t maxlen);
@@ -501,18 +501,35 @@ extern DECLSPEC int SDLCALL SDL_vsnprintf(SDL_OUT_Z_CAP(maxlen) char *text, size
 #endif
 
 extern DECLSPEC double SDLCALL SDL_acos(double x);
+extern DECLSPEC float SDLCALL SDL_acosf(float x);
 extern DECLSPEC double SDLCALL SDL_asin(double x);
+extern DECLSPEC float SDLCALL SDL_asinf(float x);
 extern DECLSPEC double SDLCALL SDL_atan(double x);
+extern DECLSPEC float SDLCALL SDL_atanf(float x);
 extern DECLSPEC double SDLCALL SDL_atan2(double x, double y);
+extern DECLSPEC float SDLCALL SDL_atan2f(float x, float y);
 extern DECLSPEC double SDLCALL SDL_ceil(double x);
+extern DECLSPEC float SDLCALL SDL_ceilf(float x);
 extern DECLSPEC double SDLCALL SDL_copysign(double x, double y);
+extern DECLSPEC float SDLCALL SDL_copysignf(float x, float y);
 extern DECLSPEC double SDLCALL SDL_cos(double x);
 extern DECLSPEC float SDLCALL SDL_cosf(float x);
+extern DECLSPEC double SDLCALL SDL_exp(double x);
+extern DECLSPEC float SDLCALL SDL_expf(float x);
 extern DECLSPEC double SDLCALL SDL_fabs(double x);
+extern DECLSPEC float SDLCALL SDL_fabsf(float x);
 extern DECLSPEC double SDLCALL SDL_floor(double x);
+extern DECLSPEC float SDLCALL SDL_floorf(float x);
+extern DECLSPEC double SDLCALL SDL_fmod(double x, double y);
+extern DECLSPEC float SDLCALL SDL_fmodf(float x, float y);
 extern DECLSPEC double SDLCALL SDL_log(double x);
+extern DECLSPEC float SDLCALL SDL_logf(float x);
+extern DECLSPEC double SDLCALL SDL_log10(double x);
+extern DECLSPEC float SDLCALL SDL_log10f(float x);
 extern DECLSPEC double SDLCALL SDL_pow(double x, double y);
+extern DECLSPEC float SDLCALL SDL_powf(float x, float y);
 extern DECLSPEC double SDLCALL SDL_scalbn(double x, int n);
+extern DECLSPEC float SDLCALL SDL_scalbnf(float x, int n);
 extern DECLSPEC double SDLCALL SDL_sin(double x);
 extern DECLSPEC float SDLCALL SDL_sinf(float x);
 extern DECLSPEC double SDLCALL SDL_sqrt(double x);
diff --git a/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_surface.h b/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_surface.h
index 510690c9c..730d49fc8 100644
--- a/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_surface.h
+++ b/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_surface.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
@@ -97,6 +97,17 @@ typedef struct SDL_Surface
 typedef int (SDLCALL *SDL_blit) (struct SDL_Surface * src, SDL_Rect * srcrect,
                                  struct SDL_Surface * dst, SDL_Rect * dstrect);
 
+/**
+ * \brief The formula used for converting between YUV and RGB
+ */
+typedef enum
+{
+    SDL_YUV_CONVERSION_JPEG,        /**< Full range JPEG */
+    SDL_YUV_CONVERSION_BT601,       /**< BT.601 (the default) */
+    SDL_YUV_CONVERSION_BT709,       /**< BT.709 */
+    SDL_YUV_CONVERSION_AUTOMATIC    /**< BT.601 for SD content, BT.709 for HD content */
+} SDL_YUV_CONVERSION_MODE;
+
 /**
  *  Allocate and free an RGB surface.
  *
@@ -237,6 +248,13 @@ extern DECLSPEC int SDLCALL SDL_SetSurfaceRLE(SDL_Surface * surface,
 extern DECLSPEC int SDLCALL SDL_SetColorKey(SDL_Surface * surface,
                                             int flag, Uint32 key);
 
+/**
+ *  \brief Returns whether the surface has a color key
+ *
+ *  \return SDL_TRUE if the surface has a color key, or SDL_FALSE if the surface is NULL or has no color key
+ */
+extern DECLSPEC SDL_bool SDLCALL SDL_HasColorKey(SDL_Surface * surface);
+
 /**
  *  \brief Gets the color key (transparent pixel) in a blittable surface.
  *
@@ -509,6 +527,20 @@ extern DECLSPEC int SDLCALL SDL_LowerBlitScaled
     (SDL_Surface * src, SDL_Rect * srcrect,
     SDL_Surface * dst, SDL_Rect * dstrect);
 
+/**
+ *  \brief Set the YUV conversion mode
+ */
+extern DECLSPEC void SDLCALL SDL_SetYUVConversionMode(SDL_YUV_CONVERSION_MODE mode);
+
+/**
+ *  \brief Get the YUV conversion mode
+ */
+extern DECLSPEC SDL_YUV_CONVERSION_MODE SDLCALL SDL_GetYUVConversionMode(void);
+
+/**
+ *  \brief Get the YUV conversion mode, returning the correct mode for the resolution when the current conversion mode is SDL_YUV_CONVERSION_AUTOMATIC
+ */
+extern DECLSPEC SDL_YUV_CONVERSION_MODE SDLCALL SDL_GetYUVConversionModeForResolution(int width, int height);
 
 /* Ends C function definitions when using C++ */
 #ifdef __cplusplus
diff --git a/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_system.h b/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_system.h
index eb069b33d..4dc372d6b 100644
--- a/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_system.h
+++ b/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_system.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
@@ -76,6 +76,18 @@ extern DECLSPEC SDL_bool SDLCALL SDL_DXGIGetOutputInfo( int displayIndex, int *a
 #endif /* __WIN32__ */
 
 
+/* Platform specific functions for Linux */
+#ifdef __LINUX__
+
+/**
+   \brief Sets the UNIX nice value for a thread, using setpriority() if possible, and RealtimeKit if available.
+
+   \return 0 on success, or -1 on error.
+ */
+extern DECLSPEC int SDLCALL SDL_LinuxSetThreadPriority(Sint64 threadID, int priority);
+ 
+#endif /* __LINUX__ */
+	
 /* Platform specific functions for iOS */
 #if defined(__IPHONEOS__) && __IPHONEOS__
 
@@ -108,6 +120,26 @@ extern DECLSPEC void * SDLCALL SDL_AndroidGetJNIEnv(void);
  */
 extern DECLSPEC void * SDLCALL SDL_AndroidGetActivity(void);
 
+/**
+   \brief Return true if the application is running on Android TV
+ */
+extern DECLSPEC SDL_bool SDLCALL SDL_IsAndroidTV(void);
+
+/**
+   \brief Return true if the application is running on a Chromebook
+ */
+extern DECLSPEC SDL_bool SDLCALL SDL_IsChromebook(void);
+
+/**
+  \brief Return true is the application is running on a Samsung DeX docking station
+ */
+extern DECLSPEC SDL_bool SDLCALL SDL_IsDeXMode(void);
+
+/**
+ \brief Trigger the Android system back button behavior.
+ */
+extern DECLSPEC void SDLCALL SDL_AndroidBackButton(void);
+
 /**
    See the official Android developer guide for more information:
    http://developer.android.com/guide/topics/data/data-storage.html
@@ -169,6 +201,25 @@ typedef enum
 } SDL_WinRT_Path;
 
 
+/**
+ *  \brief WinRT Device Family
+ */
+typedef enum
+{
+    /** \brief Unknown family  */
+    SDL_WINRT_DEVICEFAMILY_UNKNOWN,
+
+    /** \brief Desktop family*/
+    SDL_WINRT_DEVICEFAMILY_DESKTOP,
+
+    /** \brief Mobile family (for example smartphone) */
+    SDL_WINRT_DEVICEFAMILY_MOBILE,
+
+    /** \brief XBox family */
+    SDL_WINRT_DEVICEFAMILY_XBOX,
+} SDL_WinRT_DeviceFamily;
+
+
 /**
  *  \brief Retrieves a WinRT defined path on the local file system
  *
@@ -203,8 +254,20 @@ extern DECLSPEC const wchar_t * SDLCALL SDL_WinRTGetFSPathUNICODE(SDL_WinRT_Path
  */
 extern DECLSPEC const char * SDLCALL SDL_WinRTGetFSPathUTF8(SDL_WinRT_Path pathType);
 
+/**
+ *  \brief Detects the device family of WinRT plattform on runtime
+ *
+ *  \return Device family
+ */
+extern DECLSPEC SDL_WinRT_DeviceFamily SDLCALL SDL_WinRTGetDeviceFamily();
+
 #endif /* __WINRT__ */
 
+/**
+ \brief Return true if the current device is a tablet.
+ */
+extern DECLSPEC SDL_bool SDLCALL SDL_IsTablet(void);
+
 /* Ends C function definitions when using C++ */
 #ifdef __cplusplus
 }
diff --git a/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_syswm.h b/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_syswm.h
index 2d18afb6c..f1c4021cc 100644
--- a/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_syswm.h
+++ b/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_syswm.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
@@ -33,12 +33,6 @@
 #include "SDL_video.h"
 #include "SDL_version.h"
 
-#include "begin_code.h"
-/* Set up for C function definitions, even when using C++ */
-#ifdef __cplusplus
-extern "C" {
-#endif
-
 /**
  *  \file SDL_syswm.h
  *
@@ -110,6 +104,12 @@ typedef void *EGLSurface;
 #include "SDL_egl.h"
 #endif
 
+#include "begin_code.h"
+/* Set up for C function definitions, even when using C++ */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 /**
  *  These are the various supported windowing subsystems
  */
diff --git a/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_test.h b/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_test.h
index f55afcb02..6cc373bf8 100644
--- a/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_test.h
+++ b/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_test.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_test_assert.h b/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_test_assert.h
index 11d836394..1788d7a20 100644
--- a/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_test_assert.h
+++ b/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_test_assert.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_test_common.h b/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_test_common.h
index 24eeb32af..be2e6b2aa 100644
--- a/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_test_common.h
+++ b/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_test_common.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_test_compare.h b/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_test_compare.h
index 9f4c4587a..c22e447d8 100644
--- a/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_test_compare.h
+++ b/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_test_compare.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_test_crc32.h b/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_test_crc32.h
index add480c34..3d235d074 100644
--- a/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_test_crc32.h
+++ b/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_test_crc32.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_test_font.h b/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_test_font.h
index 58c9f9d5e..59cbdcad6 100644
--- a/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_test_font.h
+++ b/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_test_font.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_test_fuzzer.h b/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_test_fuzzer.h
index 6cf05747a..8fcb9ebbf 100644
--- a/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_test_fuzzer.h
+++ b/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_test_fuzzer.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_test_harness.h b/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_test_harness.h
index 68c4bcb7c..8641e0a7e 100644
--- a/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_test_harness.h
+++ b/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_test_harness.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_test_images.h b/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_test_images.h
index 683d2f8a6..9c4dd5b82 100644
--- a/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_test_images.h
+++ b/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_test_images.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_test_log.h b/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_test_log.h
index 9f993fbbc..ebd44fb50 100644
--- a/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_test_log.h
+++ b/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_test_log.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_test_md5.h b/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_test_md5.h
index 67ca7d1de..0e4105768 100644
--- a/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_test_md5.h
+++ b/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_test_md5.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_test_memory.h b/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_test_memory.h
index 43b67f521..4827ae6f2 100644
--- a/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_test_memory.h
+++ b/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_test_memory.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_test_random.h b/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_test_random.h
index 2b01922c3..0eb414ff2 100644
--- a/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_test_random.h
+++ b/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_test_random.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_thread.h b/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_thread.h
index d0f6575cd..554dd0b61 100644
--- a/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_thread.h
+++ b/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_thread.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
@@ -54,12 +54,13 @@ typedef unsigned int SDL_TLSID;
 /**
  *  The SDL thread priority.
  *
- *  \note On many systems you require special privileges to set high priority.
+ *  \note On many systems you require special privileges to set high or time critical priority.
  */
 typedef enum {
     SDL_THREAD_PRIORITY_LOW,
     SDL_THREAD_PRIORITY_NORMAL,
-    SDL_THREAD_PRIORITY_HIGH
+    SDL_THREAD_PRIORITY_HIGH,
+    SDL_THREAD_PRIORITY_TIME_CRITICAL
 } SDL_ThreadPriority;
 
 /**
@@ -105,14 +106,24 @@ SDL_CreateThread(SDL_ThreadFunction fn, const char *name, void *data,
                  pfnSDL_CurrentBeginThread pfnBeginThread,
                  pfnSDL_CurrentEndThread pfnEndThread);
 
+extern DECLSPEC SDL_Thread *SDLCALL
+SDL_CreateThreadWithStackSize(int (SDLCALL * fn) (void *),
+                 const char *name, const size_t stacksize, void *data,
+                 pfnSDL_CurrentBeginThread pfnBeginThread,
+                 pfnSDL_CurrentEndThread pfnEndThread);
+
+
 /**
  *  Create a thread.
  */
 #if defined(SDL_CreateThread) && SDL_DYNAMIC_API
 #undef SDL_CreateThread
 #define SDL_CreateThread(fn, name, data) SDL_CreateThread_REAL(fn, name, data, (pfnSDL_CurrentBeginThread)_beginthreadex, (pfnSDL_CurrentEndThread)_endthreadex)
+#undef SDL_CreateThreadWithStackSize
+#define SDL_CreateThreadWithStackSize(fn, name, stacksize, data) SDL_CreateThreadWithStackSize_REAL(fn, name, stacksize, data, (pfnSDL_CurrentBeginThread)_beginthreadex, (pfnSDL_CurrentEndThread)_endthreadex)
 #else
 #define SDL_CreateThread(fn, name, data) SDL_CreateThread(fn, name, data, (pfnSDL_CurrentBeginThread)_beginthreadex, (pfnSDL_CurrentEndThread)_endthreadex)
+#define SDL_CreateThreadWithStackSize(fn, name, stacksize, data) SDL_CreateThreadWithStackSize(fn, name, data, (pfnSDL_CurrentBeginThread)_beginthreadex, (pfnSDL_CurrentEndThread)_endthreadex)
 #endif
 
 #elif defined(__OS2__)
@@ -132,15 +143,31 @@ extern DECLSPEC SDL_Thread *SDLCALL
 SDL_CreateThread(SDL_ThreadFunction fn, const char *name, void *data,
                  pfnSDL_CurrentBeginThread pfnBeginThread,
                  pfnSDL_CurrentEndThread pfnEndThread);
+extern DECLSPEC SDL_Thread *SDLCALL
+SDL_CreateThreadWithStackSize(SDL_ThreadFunction fn, const char *name, const size_t stacksize, void *data,
+                 pfnSDL_CurrentBeginThread pfnBeginThread,
+                 pfnSDL_CurrentEndThread pfnEndThread);
 #if defined(SDL_CreateThread) && SDL_DYNAMIC_API
 #undef SDL_CreateThread
 #define SDL_CreateThread(fn, name, data) SDL_CreateThread_REAL(fn, name, data, (pfnSDL_CurrentBeginThread)_beginthread, (pfnSDL_CurrentEndThread)_endthread)
+#undef SDL_CreateThreadWithStackSize
+#define SDL_CreateThreadWithStackSize(fn, name, stacksize, data) SDL_CreateThreadWithStackSize_REAL(fn, name, data, (pfnSDL_CurrentBeginThread)_beginthread, (pfnSDL_CurrentEndThread)_endthread)
 #else
 #define SDL_CreateThread(fn, name, data) SDL_CreateThread(fn, name, data, (pfnSDL_CurrentBeginThread)_beginthread, (pfnSDL_CurrentEndThread)_endthread)
+#define SDL_CreateThreadWithStackSize(fn, name, stacksize, data) SDL_CreateThreadWithStackSize(fn, name, stacksize, data, (pfnSDL_CurrentBeginThread)_beginthread, (pfnSDL_CurrentEndThread)_endthread)
 #endif
 
 #else
 
+/**
+ *  Create a thread with a default stack size.
+ *
+ *  This is equivalent to calling:
+ *  SDL_CreateThreadWithStackSize(fn, name, 0, data);
+ */
+extern DECLSPEC SDL_Thread *SDLCALL
+SDL_CreateThread(SDL_ThreadFunction fn, const char *name, void *data);
+
 /**
  *  Create a thread.
  *
@@ -158,9 +185,17 @@ SDL_CreateThread(SDL_ThreadFunction fn, const char *name, void *data,
  *   If a system imposes requirements, SDL will try to munge the string for
  *    it (truncate, etc), but the original string contents will be available
  *    from SDL_GetThreadName().
+ *
+ *   The size (in bytes) of the new stack can be specified. Zero means "use
+ *    the system default" which might be wildly different between platforms
+ *    (x86 Linux generally defaults to eight megabytes, an embedded device
+ *    might be a few kilobytes instead).
+ *
+ *   In SDL 2.1, stacksize will be folded into the original SDL_CreateThread
+ *    function.
  */
 extern DECLSPEC SDL_Thread *SDLCALL
-SDL_CreateThread(SDL_ThreadFunction fn, const char *name, void *data);
+SDL_CreateThreadWithStackSize(SDL_ThreadFunction fn, const char *name, const size_t stacksize, void *data);
 
 #endif
 
diff --git a/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_timer.h b/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_timer.h
index 282625d3f..5600618ff 100644
--- a/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_timer.h
+++ b/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_timer.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_touch.h b/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_touch.h
index db9e25ebd..f4075e79a 100644
--- a/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_touch.h
+++ b/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_touch.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_types.h b/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_types.h
index 06ee80cb3..4ac248c8c 100644
--- a/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_types.h
+++ b/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_types.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_version.h b/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_version.h
index 5b4c40248..31443e149 100644
--- a/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_version.h
+++ b/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_version.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
@@ -59,7 +59,7 @@ typedef struct SDL_version
 */
 #define SDL_MAJOR_VERSION   2
 #define SDL_MINOR_VERSION   0
-#define SDL_PATCHLEVEL      7
+#define SDL_PATCHLEVEL      9
 
 /**
  *  \brief Macro to determine SDL version program was compiled against.
diff --git a/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_video.h b/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_video.h
index 6f6cda8b1..461f13805 100644
--- a/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_video.h
+++ b/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_video.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
@@ -110,7 +110,9 @@ typedef enum
     SDL_WINDOW_MOUSE_FOCUS = 0x00000400,        /**< window has mouse focus */
     SDL_WINDOW_FULLSCREEN_DESKTOP = ( SDL_WINDOW_FULLSCREEN | 0x00001000 ),
     SDL_WINDOW_FOREIGN = 0x00000800,            /**< window not created by SDL */
-    SDL_WINDOW_ALLOW_HIGHDPI = 0x00002000,      /**< window should be created in high-DPI mode if supported */
+    SDL_WINDOW_ALLOW_HIGHDPI = 0x00002000,      /**< window should be created in high-DPI mode if supported.
+                                                     On macOS NSHighResolutionCapable must be set true in the
+                                                     application's Info.plist for this to have any effect. */
     SDL_WINDOW_MOUSE_CAPTURE = 0x00004000,      /**< window has mouse captured (unrelated to INPUT_GRABBED) */
     SDL_WINDOW_ALWAYS_ON_TOP = 0x00008000,      /**< window should always be above others */
     SDL_WINDOW_SKIP_TASKBAR  = 0x00010000,      /**< window should not be added to the taskbar */
@@ -167,6 +169,24 @@ typedef enum
     SDL_WINDOWEVENT_HIT_TEST        /**< Window had a hit test that wasn't SDL_HITTEST_NORMAL. */
 } SDL_WindowEventID;
 
+/**
+ *  \brief Event subtype for display events
+ */
+typedef enum
+{
+    SDL_DISPLAYEVENT_NONE,          /**< Never used */
+    SDL_DISPLAYEVENT_ORIENTATION    /**< Display orientation has changed to data1 */
+} SDL_DisplayEventID;
+
+typedef enum
+{
+    SDL_ORIENTATION_UNKNOWN,            /**< The display orientation can't be determined */
+    SDL_ORIENTATION_LANDSCAPE,          /**< The display is in landscape mode, with the right side up, relative to portrait mode */
+    SDL_ORIENTATION_LANDSCAPE_FLIPPED,  /**< The display is in landscape mode, with the left side up, relative to portrait mode */
+    SDL_ORIENTATION_PORTRAIT,           /**< The display is in portrait mode */
+    SDL_ORIENTATION_PORTRAIT_FLIPPED    /**< The display is in portrait mode, upside down */
+} SDL_DisplayOrientation;
+
 /**
  *  \brief An opaque handle to an OpenGL context.
  */
@@ -314,18 +334,6 @@ extern DECLSPEC const char * SDLCALL SDL_GetDisplayName(int displayIndex);
  */
 extern DECLSPEC int SDLCALL SDL_GetDisplayBounds(int displayIndex, SDL_Rect * rect);
 
-/**
- *  \brief Get the dots/pixels-per-inch for a display
- *
- *  \note Diagonal, horizontal and vertical DPI can all be optionally
- *        returned if the parameter is non-NULL.
- *
- *  \return 0 on success, or -1 if no DPI information is available or the index is out of range.
- *
- *  \sa SDL_GetNumVideoDisplays()
- */
-extern DECLSPEC int SDLCALL SDL_GetDisplayDPI(int displayIndex, float * ddpi, float * hdpi, float * vdpi);
-
 /**
  *  \brief Get the usable desktop area represented by a display, with the
  *         primary display located at 0,0
@@ -345,6 +353,27 @@ extern DECLSPEC int SDLCALL SDL_GetDisplayDPI(int displayIndex, float * ddpi, fl
  */
 extern DECLSPEC int SDLCALL SDL_GetDisplayUsableBounds(int displayIndex, SDL_Rect * rect);
 
+/**
+ *  \brief Get the dots/pixels-per-inch for a display
+ *
+ *  \note Diagonal, horizontal and vertical DPI can all be optionally
+ *        returned if the parameter is non-NULL.
+ *
+ *  \return 0 on success, or -1 if no DPI information is available or the index is out of range.
+ *
+ *  \sa SDL_GetNumVideoDisplays()
+ */
+extern DECLSPEC int SDLCALL SDL_GetDisplayDPI(int displayIndex, float * ddpi, float * hdpi, float * vdpi);
+
+/**
+ *  \brief Get the orientation of a display
+ *
+ *  \return The orientation of the display, or SDL_ORIENTATION_UNKNOWN if it isn't available.
+ *
+ *  \sa SDL_GetNumVideoDisplays()
+ */
+extern DECLSPEC SDL_DisplayOrientation SDLCALL SDL_GetDisplayOrientation(int displayIndex);
+
 /**
  *  \brief Returns the number of available display modes.
  *
@@ -470,7 +499,7 @@ extern DECLSPEC Uint32 SDLCALL SDL_GetWindowPixelFormat(SDL_Window * window);
  *  If the window is created with any of the SDL_WINDOW_OPENGL or
  *  SDL_WINDOW_VULKAN flags, then the corresponding LoadLibrary function
  *  (SDL_GL_LoadLibrary or SDL_Vulkan_LoadLibrary) is called and the
- *  corrensponding UnloadLibrary function is called by SDL_DestroyWindow().
+ *  corresponding UnloadLibrary function is called by SDL_DestroyWindow().
  *
  *  If SDL_WINDOW_VULKAN is specified and there isn't a working Vulkan driver,
  *  SDL_CreateWindow() will fail because SDL_Vulkan_LoadLibrary() will fail.
diff --git a/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_vulkan.h b/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_vulkan.h
index 803b5feef..972cca4d7 100644
--- a/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_vulkan.h
+++ b/libs/SDL2/i686-w64-mingw32/include/SDL2/SDL_vulkan.h
@@ -69,30 +69,43 @@ typedef VkSurfaceKHR SDL_vulkanSurface; /* for compatibility with Tizen */
  *  \brief Dynamically load a Vulkan loader library.
  *
  *  \param [in] path The platform dependent Vulkan loader library name, or
- *              \c NULL to open the default Vulkan loader library.
+ *              \c NULL.
  *
  *  \return \c 0 on success, or \c -1 if the library couldn't be loaded.
  *
- *  This should be done after initializing the video driver, but before
+ *  If \a path is NULL SDL will use the value of the environment variable
+ *  \c SDL_VULKAN_LIBRARY, if set, otherwise it loads the default Vulkan
+ *  loader library.
+ *
+ *  This should be called after initializing the video driver, but before
  *  creating any Vulkan windows. If no Vulkan loader library is loaded, the
  *  default library will be loaded upon creation of the first Vulkan window.
  *
- *  \note If you specify a non-NULL \a path, you should retrieve all of the
- *        Vulkan functions used in your program from the dynamic library using
+ *  \note It is fairly common for Vulkan applications to link with \a libvulkan
+ *        instead of explicitly loading it at run time. This will work with
+ *        SDL provided the application links to a dynamic library and both it
+ *        and SDL use the same search path.
+ *
+ *  \note If you specify a non-NULL \c path, an application should retrieve all
+ *        of the Vulkan functions it uses from the dynamic library using
  *        \c SDL_Vulkan_GetVkGetInstanceProcAddr() unless you can guarantee
- *        \a path points to the same vulkan loader library that you linked to.
+ *        \c path points to the same vulkan loader library the application
+ *        linked to.
  *
  *  \note On Apple devices, if \a path is NULL, SDL will attempt to find
  *        the vkGetInstanceProcAddr address within all the mach-o images of
- *        the current process. This is because the currently (v0.17.0)
- *        recommended MoltenVK (Vulkan on Metal) usage is as a static library.
- *        If it is not found then SDL will attempt to load \c libMoltenVK.dylib.
- *        Applications using the dylib alternative therefore do not need to do
- *        anything special when calling SDL.
+ *        the current process. This is because it is fairly common for Vulkan
+ *        applications to link with libvulkan (and historically MoltenVK was
+ *        provided as a static library). If it is not found then, on macOS, SDL
+ *        will attempt to load \c vulkan.framework/vulkan, \c libvulkan.1.dylib,
+ *        \c MoltenVK.framework/MoltenVK and \c libMoltenVK.dylib in that order.
+ *        On iOS SDL will attempt to load \c libMoltenVK.dylib. Applications
+ *        using a dynamic framework or .dylib must ensure it is included in its
+ *        application bundle.
  *
- *  \note On non-Apple devices, SDL requires you to either not link to the
- *        Vulkan loader or link to a dynamic library version. This limitation
- *        may be removed in a future version of SDL.
+ *  \note On non-Apple devices, application linking with a static libvulkan is
+ *        not supported. Either do not link to the Vulkan loader or link to a
+ *        dynamic library version.
  *
  *  \note This function will fail if there are no working Vulkan drivers
  *        installed.
@@ -122,11 +135,11 @@ extern DECLSPEC void SDLCALL SDL_Vulkan_UnloadLibrary(void);
  *  \brief Get the names of the Vulkan instance extensions needed to create
  *         a surface with \c SDL_Vulkan_CreateSurface().
  *
- *  \param [in]     window Window for which the required Vulkan instance
+ *  \param [in]     \c NULL or window Window for which the required Vulkan instance
  *                  extensions should be retrieved
- *  \param [in,out] count pointer to an \c unsigned related to the number of
+ *  \param [in,out] pCount pointer to an \c unsigned related to the number of
  *                  required Vulkan instance extensions
- *  \param [out]    names \c NULL or a pointer to an array to be filled with the
+ *  \param [out]    pNames \c NULL or a pointer to an array to be filled with the
  *                  required Vulkan instance extensions
  *
  *  \return \c SDL_TRUE on success, \c SDL_FALSE on error.
@@ -140,6 +153,10 @@ extern DECLSPEC void SDLCALL SDL_Vulkan_UnloadLibrary(void);
  *  is smaller than the number of required extensions, \c SDL_FALSE will be
  *  returned instead of \c SDL_TRUE, to indicate that not all the required
  *  extensions were returned.
+ * 
+ *  \note If \c window is not NULL, it will be checked against its creation
+ *        flags to ensure that the Vulkan flag is present. This parameter
+ *        will be removed in a future major release.
  *
  *  \note The returned list of extensions will contain \c VK_KHR_surface
  *        and zero or more platform specific extensions
@@ -147,12 +164,13 @@ extern DECLSPEC void SDLCALL SDL_Vulkan_UnloadLibrary(void);
  *  \note The extension names queried here must be enabled when calling
  *        VkCreateInstance, otherwise surface creation will fail.
  *
- *  \note \c window should have been created with the \c SDL_WINDOW_VULKAN flag.
+ *  \note \c window should have been created with the \c SDL_WINDOW_VULKAN flag
+ *        or be \c NULL
  *
  *  \code
  *  unsigned int count;
  *  // get count of required extensions
- *  if(!SDL_Vulkan_GetInstanceExtensions(window, &count, NULL))
+ *  if(!SDL_Vulkan_GetInstanceExtensions(NULL, &count, NULL))
  *      handle_error();
  *
  *  static const char *const additionalExtensions[] =
@@ -166,7 +184,7 @@ extern DECLSPEC void SDLCALL SDL_Vulkan_UnloadLibrary(void);
  *      handle_error();
  *
  *  // get names of required extensions
- *  if(!SDL_Vulkan_GetInstanceExtensions(window, &count, names))
+ *  if(!SDL_Vulkan_GetInstanceExtensions(NULL, &count, names))
  *      handle_error();
  *
  *  // copy additional extensions after required extensions
@@ -240,6 +258,9 @@ extern DECLSPEC SDL_bool SDLCALL SDL_Vulkan_CreateSurface(
  * platform with high-DPI support (Apple calls this "Retina"), and not disabled
  * by the \c SDL_HINT_VIDEO_HIGHDPI_DISABLED hint.
  *
+ *  \note On macOS high-DPI support must be enabled for an application by
+ *        setting NSHighResolutionCapable to true in its Info.plist.
+ *
  *  \sa SDL_GetWindowSize()
  *  \sa SDL_CreateWindow()
  */
diff --git a/libs/SDL2/i686-w64-mingw32/include/SDL2/begin_code.h b/libs/SDL2/i686-w64-mingw32/include/SDL2/begin_code.h
index 5372d6f04..6c2106246 100644
--- a/libs/SDL2/i686-w64-mingw32/include/SDL2/begin_code.h
+++ b/libs/SDL2/i686-w64-mingw32/include/SDL2/begin_code.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/i686-w64-mingw32/include/SDL2/close_code.h b/libs/SDL2/i686-w64-mingw32/include/SDL2/close_code.h
index 2a352dbb9..b3b70a4c8 100644
--- a/libs/SDL2/i686-w64-mingw32/include/SDL2/close_code.h
+++ b/libs/SDL2/i686-w64-mingw32/include/SDL2/close_code.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/i686-w64-mingw32/lib/cmake/SDL2/sdl2-config.cmake b/libs/SDL2/i686-w64-mingw32/lib/cmake/SDL2/sdl2-config.cmake
index 208b7c637..ee347fcb9 100644
--- a/libs/SDL2/i686-w64-mingw32/lib/cmake/SDL2/sdl2-config.cmake
+++ b/libs/SDL2/i686-w64-mingw32/lib/cmake/SDL2/sdl2-config.cmake
@@ -1,11 +1,11 @@
 # sdl2 cmake project-config input for ./configure scripts
 
-set(prefix "/usr/local/i686-w64-mingw32") 
+set(prefix "/opt/local/i686-w64-mingw32") 
 set(exec_prefix "${prefix}")
 set(libdir "${exec_prefix}/lib")
-set(SDL2_PREFIX "/usr/local/i686-w64-mingw32")
-set(SDL2_EXEC_PREFIX "/usr/local/i686-w64-mingw32")
+set(SDL2_PREFIX "/opt/local/i686-w64-mingw32")
+set(SDL2_EXEC_PREFIX "/opt/local/i686-w64-mingw32")
 set(SDL2_LIBDIR "${exec_prefix}/lib")
 set(SDL2_INCLUDE_DIRS "${prefix}/include/SDL2")
-set(SDL2_LIBRARIES "-L${SDL2_LIBDIR}  -lmingw32 -lSDL2main -lSDL2  -mwindows")
+set(SDL2_LIBRARIES "-L${SDL2_LIBDIR}  -lmingw32 -lSDL2main -lSDL2 -mwindows")
 string(STRIP "${SDL2_LIBRARIES}" SDL2_LIBRARIES)
diff --git a/libs/SDL2/i686-w64-mingw32/lib/libSDL2.a b/libs/SDL2/i686-w64-mingw32/lib/libSDL2.a
index 771ee00bd..05489a95a 100644
Binary files a/libs/SDL2/i686-w64-mingw32/lib/libSDL2.a and b/libs/SDL2/i686-w64-mingw32/lib/libSDL2.a differ
diff --git a/libs/SDL2/i686-w64-mingw32/lib/libSDL2.dll.a b/libs/SDL2/i686-w64-mingw32/lib/libSDL2.dll.a
index 59d480738..b20371a13 100755
Binary files a/libs/SDL2/i686-w64-mingw32/lib/libSDL2.dll.a and b/libs/SDL2/i686-w64-mingw32/lib/libSDL2.dll.a differ
diff --git a/libs/SDL2/i686-w64-mingw32/lib/libSDL2.la b/libs/SDL2/i686-w64-mingw32/lib/libSDL2.la
new file mode 100644
index 000000000..3848c7db9
--- /dev/null
+++ b/libs/SDL2/i686-w64-mingw32/lib/libSDL2.la
@@ -0,0 +1,41 @@
+# libSDL2.la - a libtool library file
+# Generated by libtool (GNU libtool) 2.4.2
+#
+# Please DO NOT delete this file!
+# It is necessary for linking the library.
+
+# The name that we can dlopen(3).
+dlname='../bin/SDL2.dll'
+
+# Names of this library.
+library_names='libSDL2.dll.a'
+
+# The name of the static archive.
+old_library='libSDL2.a'
+
+# Linker flags that can not go in dependency_libs.
+inherited_linker_flags=''
+
+# Libraries that this one depends upon.
+dependency_libs=' -ldinput8 -ldxguid -ldxerr8 -luser32 -lgdi32 -lwinmm -limm32 -lole32 -loleaut32 -lshell32 -lsetupapi -lversion -luuid'
+
+# Names of additional weak libraries provided by this library
+weak_library_names=''
+
+# Version information for libSDL2.
+current=9
+age=9
+revision=0
+
+# Is this an already installed library?
+installed=yes
+
+# Should we warn about portability when linking against -modules?
+shouldnotlink=no
+
+# Files to dlopen/dlpreopen
+dlopen=''
+dlpreopen=''
+
+# Directory that this library needs to be installed in:
+libdir='/Users/valve/release/SDL/SDL2-2.0.9/i686-w64-mingw32/lib'
diff --git a/libs/SDL2/i686-w64-mingw32/lib/libSDL2_test.a b/libs/SDL2/i686-w64-mingw32/lib/libSDL2_test.a
index 5f2cfa28f..190f9e072 100644
Binary files a/libs/SDL2/i686-w64-mingw32/lib/libSDL2_test.a and b/libs/SDL2/i686-w64-mingw32/lib/libSDL2_test.a differ
diff --git a/libs/SDL2/i686-w64-mingw32/lib/libSDL2_test.la b/libs/SDL2/i686-w64-mingw32/lib/libSDL2_test.la
new file mode 100644
index 000000000..5f96235bd
--- /dev/null
+++ b/libs/SDL2/i686-w64-mingw32/lib/libSDL2_test.la
@@ -0,0 +1,41 @@
+# libSDL2_test.la - a libtool library file
+# Generated by libtool (GNU libtool) 2.4.2
+#
+# Please DO NOT delete this file!
+# It is necessary for linking the library.
+
+# The name that we can dlopen(3).
+dlname=''
+
+# Names of this library.
+library_names=''
+
+# The name of the static archive.
+old_library='libSDL2_test.a'
+
+# Linker flags that can not go in dependency_libs.
+inherited_linker_flags=''
+
+# Libraries that this one depends upon.
+dependency_libs=''
+
+# Names of additional weak libraries provided by this library
+weak_library_names=''
+
+# Version information for libSDL2_test.
+current=0
+age=0
+revision=0
+
+# Is this an already installed library?
+installed=yes
+
+# Should we warn about portability when linking against -modules?
+shouldnotlink=no
+
+# Files to dlopen/dlpreopen
+dlopen=''
+dlpreopen=''
+
+# Directory that this library needs to be installed in:
+libdir='/Users/valve/release/SDL/SDL2-2.0.9/i686-w64-mingw32/lib'
diff --git a/libs/SDL2/i686-w64-mingw32/lib/libSDL2main.a b/libs/SDL2/i686-w64-mingw32/lib/libSDL2main.a
index 9dddabbfc..df7c95b95 100644
Binary files a/libs/SDL2/i686-w64-mingw32/lib/libSDL2main.a and b/libs/SDL2/i686-w64-mingw32/lib/libSDL2main.a differ
diff --git a/libs/SDL2/i686-w64-mingw32/lib/libSDL2main.la b/libs/SDL2/i686-w64-mingw32/lib/libSDL2main.la
new file mode 100644
index 000000000..d01b8a172
--- /dev/null
+++ b/libs/SDL2/i686-w64-mingw32/lib/libSDL2main.la
@@ -0,0 +1,41 @@
+# libSDL2main.la - a libtool library file
+# Generated by libtool (GNU libtool) 2.4.2
+#
+# Please DO NOT delete this file!
+# It is necessary for linking the library.
+
+# The name that we can dlopen(3).
+dlname=''
+
+# Names of this library.
+library_names=''
+
+# The name of the static archive.
+old_library='libSDL2main.a'
+
+# Linker flags that can not go in dependency_libs.
+inherited_linker_flags=''
+
+# Libraries that this one depends upon.
+dependency_libs=''
+
+# Names of additional weak libraries provided by this library
+weak_library_names=''
+
+# Version information for libSDL2main.
+current=0
+age=0
+revision=0
+
+# Is this an already installed library?
+installed=yes
+
+# Should we warn about portability when linking against -modules?
+shouldnotlink=no
+
+# Files to dlopen/dlpreopen
+dlopen=''
+dlpreopen=''
+
+# Directory that this library needs to be installed in:
+libdir='/Users/valve/release/SDL/SDL2-2.0.9/i686-w64-mingw32/lib'
diff --git a/libs/SDL2/i686-w64-mingw32/lib/pkgconfig/sdl2.pc b/libs/SDL2/i686-w64-mingw32/lib/pkgconfig/sdl2.pc
index 407c95c48..25fc5928e 100644
--- a/libs/SDL2/i686-w64-mingw32/lib/pkgconfig/sdl2.pc
+++ b/libs/SDL2/i686-w64-mingw32/lib/pkgconfig/sdl2.pc
@@ -1,15 +1,15 @@
 # sdl pkg-config source file
 
-prefix=/usr/local/i686-w64-mingw32
+prefix=/opt/local/i686-w64-mingw32
 exec_prefix=${prefix}
 libdir=${exec_prefix}/lib
 includedir=${prefix}/include
 
 Name: sdl2
 Description: Simple DirectMedia Layer is a cross-platform multimedia library designed to provide low level access to audio, keyboard, mouse, joystick, 3D hardware via OpenGL, and 2D video framebuffer.
-Version: 2.0.7
+Version: 2.0.9
 Requires:
 Conflicts:
-Libs: -L${libdir}  -lmingw32 -lSDL2main -lSDL2  -mwindows
-Libs.private: -lmingw32 -lSDL2main -lSDL2  -mwindows  -Wl,--no-undefined -lm -ldinput8 -ldxguid -ldxerr8 -luser32 -lgdi32 -lwinmm -limm32 -lole32 -loleaut32 -lshell32 -lversion -luuid -static-libgcc
+Libs: -L${libdir}  -lmingw32 -lSDL2main -lSDL2 -mwindows
+Libs.private: -lmingw32 -lSDL2main -lSDL2 -mwindows  -Wl,--no-undefined -lm -ldinput8 -ldxguid -ldxerr8 -luser32 -lgdi32 -lwinmm -limm32 -lole32 -loleaut32 -lshell32 -lsetupapi -lversion -luuid -static-libgcc
 Cflags: -I${includedir}/SDL2  -Dmain=SDL_main
diff --git a/libs/SDL2/include/SDL.h b/libs/SDL2/include/SDL.h
old mode 100755
new mode 100644
index 366d50fa3..fc35a419e
--- a/libs/SDL2/include/SDL.h
+++ b/libs/SDL2/include/SDL.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
@@ -51,6 +51,7 @@
 #include "SDL_power.h"
 #include "SDL_render.h"
 #include "SDL_rwops.h"
+#include "SDL_sensor.h"
 #include "SDL_shape.h"
 #include "SDL_system.h"
 #include "SDL_thread.h"
@@ -80,10 +81,11 @@ extern "C" {
 #define SDL_INIT_HAPTIC         0x00001000u
 #define SDL_INIT_GAMECONTROLLER 0x00002000u  /**< SDL_INIT_GAMECONTROLLER implies SDL_INIT_JOYSTICK */
 #define SDL_INIT_EVENTS         0x00004000u
+#define SDL_INIT_SENSOR         0x00008000u
 #define SDL_INIT_NOPARACHUTE    0x00100000u  /**< compatibility; this flag is ignored. */
 #define SDL_INIT_EVERYTHING ( \
                 SDL_INIT_TIMER | SDL_INIT_AUDIO | SDL_INIT_VIDEO | SDL_INIT_EVENTS | \
-                SDL_INIT_JOYSTICK | SDL_INIT_HAPTIC | SDL_INIT_GAMECONTROLLER \
+                SDL_INIT_JOYSTICK | SDL_INIT_HAPTIC | SDL_INIT_GAMECONTROLLER | SDL_INIT_SENSOR \
             )
 /* @} */
 
diff --git a/libs/SDL2/include/SDL_assert.h b/libs/SDL2/include/SDL_assert.h
old mode 100755
new mode 100644
index 90abbe39b..b38f928ae
--- a/libs/SDL2/include/SDL_assert.h
+++ b/libs/SDL2/include/SDL_assert.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/include/SDL_atomic.h b/libs/SDL2/include/SDL_atomic.h
old mode 100755
new mode 100644
index 36e37f3b7..b2287748c
--- a/libs/SDL2/include/SDL_atomic.h
+++ b/libs/SDL2/include/SDL_atomic.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
@@ -158,6 +158,9 @@ extern DECLSPEC void SDLCALL SDL_MemoryBarrierAcquireFunction(void);
 #if defined(__GNUC__) && (defined(__powerpc__) || defined(__ppc__))
 #define SDL_MemoryBarrierRelease()   __asm__ __volatile__ ("lwsync" : : : "memory")
 #define SDL_MemoryBarrierAcquire()   __asm__ __volatile__ ("lwsync" : : : "memory")
+#elif defined(__GNUC__) && defined(__aarch64__)
+#define SDL_MemoryBarrierRelease()   __asm__ __volatile__ ("dmb ish" : : : "memory")
+#define SDL_MemoryBarrierAcquire()   __asm__ __volatile__ ("dmb ish" : : : "memory")
 #elif defined(__GNUC__) && defined(__arm__)
 #if defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7EM__) || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7S__)
 #define SDL_MemoryBarrierRelease()   __asm__ __volatile__ ("dmb ish" : : : "memory")
diff --git a/libs/SDL2/include/SDL_audio.h b/libs/SDL2/include/SDL_audio.h
old mode 100755
new mode 100644
index f119c2b26..d3e1bface
--- a/libs/SDL2/include/SDL_audio.h
+++ b/libs/SDL2/include/SDL_audio.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
@@ -140,7 +140,8 @@ typedef Uint16 SDL_AudioFormat;
 #define SDL_AUDIO_ALLOW_FREQUENCY_CHANGE    0x00000001
 #define SDL_AUDIO_ALLOW_FORMAT_CHANGE       0x00000002
 #define SDL_AUDIO_ALLOW_CHANNELS_CHANGE     0x00000004
-#define SDL_AUDIO_ALLOW_ANY_CHANGE          (SDL_AUDIO_ALLOW_FREQUENCY_CHANGE|SDL_AUDIO_ALLOW_FORMAT_CHANGE|SDL_AUDIO_ALLOW_CHANNELS_CHANGE)
+#define SDL_AUDIO_ALLOW_SAMPLES_CHANGE      0x00000008
+#define SDL_AUDIO_ALLOW_ANY_CHANGE          (SDL_AUDIO_ALLOW_FREQUENCY_CHANGE|SDL_AUDIO_ALLOW_FORMAT_CHANGE|SDL_AUDIO_ALLOW_CHANNELS_CHANGE|SDL_AUDIO_ALLOW_SAMPLES_CHANGE)
 /* @} */
 
 /* @} *//* Audio flags */
@@ -527,7 +528,7 @@ extern DECLSPEC SDL_AudioStream * SDLCALL SDL_NewAudioStream(const SDL_AudioForm
  *
  *  \param stream The stream the audio data is being added to
  *  \param buf A pointer to the audio data to add
- *  \param int The number of bytes to write to the stream
+ *  \param len The number of bytes to write to the stream
  *  \return 0 on success, or -1 on error.
  *
  *  \sa SDL_NewAudioStream
diff --git a/libs/SDL2/include/SDL_bits.h b/libs/SDL2/include/SDL_bits.h
old mode 100755
new mode 100644
index bc2857290..eb8322f0d
--- a/libs/SDL2/include/SDL_bits.h
+++ b/libs/SDL2/include/SDL_bits.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/include/SDL_blendmode.h b/libs/SDL2/include/SDL_blendmode.h
old mode 100755
new mode 100644
index 9abd0bd4c..36a5ea76f
--- a/libs/SDL2/include/SDL_blendmode.h
+++ b/libs/SDL2/include/SDL_blendmode.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/include/SDL_clipboard.h b/libs/SDL2/include/SDL_clipboard.h
old mode 100755
new mode 100644
index 341f4ba42..f28751ebb
--- a/libs/SDL2/include/SDL_clipboard.h
+++ b/libs/SDL2/include/SDL_clipboard.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/include/SDL_config.h b/libs/SDL2/include/SDL_config.h
old mode 100755
new mode 100644
index 1bbb83848..c58be8e72
--- a/libs/SDL2/include/SDL_config.h
+++ b/libs/SDL2/include/SDL_config.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
@@ -82,6 +82,9 @@ typedef unsigned int uintptr_t;
 #define HAVE_DSOUND_H 1
 #define HAVE_DXGI_H 1
 #define HAVE_XINPUT_H 1
+#define HAVE_MMDEVICEAPI_H 1
+#define HAVE_AUDIOCLIENT_H 1
+#define HAVE_ENDPOINTVOLUME_H 1
 
 /* This is disabled by default to avoid C runtime dependencies and manifest requirements */
 #ifdef HAVE_LIBC
@@ -109,13 +112,15 @@ typedef unsigned int uintptr_t;
 #define HAVE_MEMCMP 1
 #define HAVE_STRLEN 1
 #define HAVE__STRREV 1
-#define HAVE__STRUPR 1
-#define HAVE__STRLWR 1
+/* These functions have security warnings, so we won't use them */
+/* #undef HAVE__STRUPR */
+/* #undef HAVE__STRLWR */
 #define HAVE_STRCHR 1
 #define HAVE_STRRCHR 1
 #define HAVE_STRSTR 1
-#define HAVE__LTOA 1
-#define HAVE__ULTOA 1
+/* These functions have security warnings, so we won't use them */
+/* #undef HAVE__LTOA */
+/* #undef HAVE__ULTOA */
 #define HAVE_STRTOL 1
 #define HAVE_STRTOUL 1
 #define HAVE_STRTOD 1
@@ -125,30 +130,45 @@ typedef unsigned int uintptr_t;
 #define HAVE_STRNCMP 1
 #define HAVE__STRICMP 1
 #define HAVE__STRNICMP 1
-#define HAVE_ATAN 1
-#define HAVE_ATAN2 1
-#define HAVE_ACOS  1
-#define HAVE_ASIN  1
-#define HAVE_CEIL 1
-#define HAVE_COS 1
-#define HAVE_COSF 1
-#define HAVE_FABS 1
-#define HAVE_FLOOR 1
-#define HAVE_LOG 1
-#define HAVE_POW 1
-#define HAVE_SIN 1
-#define HAVE_SINF 1
-#define HAVE_SQRT 1
-#define HAVE_SQRTF 1
-#define HAVE_TAN 1
-#define HAVE_TANF 1
-#define HAVE__COPYSIGN 1
+#define HAVE_ACOS   1
+#define HAVE_ACOSF  1
+#define HAVE_ASIN   1
+#define HAVE_ASINF  1
+#define HAVE_ATAN   1
+#define HAVE_ATANF  1
+#define HAVE_ATAN2  1
+#define HAVE_ATAN2F 1
+#define HAVE_CEILF  1
+#define HAVE__COPYSIGN  1
+#define HAVE_COS    1
+#define HAVE_COSF   1
+#define HAVE_EXP    1
+#define HAVE_EXPF   1
+#define HAVE_FABS   1
+#define HAVE_FABSF  1
+#define HAVE_FLOOR  1
+#define HAVE_FLOORF 1
+#define HAVE_FMOD   1
+#define HAVE_FMODF  1
+#define HAVE_LOG    1
+#define HAVE_LOGF   1
+#define HAVE_LOG10  1
+#define HAVE_LOG10F 1
+#define HAVE_POW    1
+#define HAVE_POWF   1
+#define HAVE_SIN    1
+#define HAVE_SINF   1
+#define HAVE_SQRT   1
+#define HAVE_SQRTF  1
+#define HAVE_TAN    1
+#define HAVE_TANF   1
 #if defined(_MSC_VER)
 /* These functions were added with the VC++ 2013 C runtime library */
 #if _MSC_VER >= 1800
 #define HAVE_STRTOLL 1
 #define HAVE_VSSCANF 1
 #define HAVE_SCALBN 1
+#define HAVE_SCALBNF    1
 #endif
 /* This function is available with at least the VC++ 2008 C runtime library */
 #if _MSC_VER >= 1400
@@ -166,7 +186,6 @@ typedef unsigned int uintptr_t;
 /* Enable various audio drivers */
 #define SDL_AUDIO_DRIVER_WASAPI 1
 #define SDL_AUDIO_DRIVER_DSOUND 1
-#define SDL_AUDIO_DRIVER_XAUDIO2    0
 #define SDL_AUDIO_DRIVER_WINMM  1
 #define SDL_AUDIO_DRIVER_DISK   1
 #define SDL_AUDIO_DRIVER_DUMMY  1
@@ -174,9 +193,13 @@ typedef unsigned int uintptr_t;
 /* Enable various input drivers */
 #define SDL_JOYSTICK_DINPUT 1
 #define SDL_JOYSTICK_XINPUT 1
+#define SDL_JOYSTICK_HIDAPI 1
 #define SDL_HAPTIC_DINPUT   1
 #define SDL_HAPTIC_XINPUT   1
 
+/* Enable the dummy sensor driver */
+#define SDL_SENSOR_DUMMY  1
+
 /* Enable various shared object loading systems */
 #define SDL_LOADSO_WINDOWS  1
 
@@ -194,7 +217,7 @@ typedef unsigned int uintptr_t;
 #define SDL_VIDEO_RENDER_D3D    1
 #endif
 #ifndef SDL_VIDEO_RENDER_D3D11
-#define SDL_VIDEO_RENDER_D3D11	0
+#define SDL_VIDEO_RENDER_D3D11  0
 #endif
 
 /* Enable OpenGL support */
diff --git a/libs/SDL2/include/SDL_config.h.cmake b/libs/SDL2/include/SDL_config.h.cmake
old mode 100755
new mode 100644
diff --git a/libs/SDL2/include/SDL_config.h.in b/libs/SDL2/include/SDL_config.h.in
old mode 100755
new mode 100644
diff --git a/libs/SDL2/include/SDL_config_android.h b/libs/SDL2/include/SDL_config_android.h
old mode 100755
new mode 100644
diff --git a/libs/SDL2/include/SDL_config_iphoneos.h b/libs/SDL2/include/SDL_config_iphoneos.h
old mode 100755
new mode 100644
diff --git a/libs/SDL2/include/SDL_config_macosx.h b/libs/SDL2/include/SDL_config_macosx.h
old mode 100755
new mode 100644
diff --git a/libs/SDL2/include/SDL_config_macosx.h.orig b/libs/SDL2/include/SDL_config_macosx.h.orig
old mode 100755
new mode 100644
diff --git a/libs/SDL2/include/SDL_config_minimal.h b/libs/SDL2/include/SDL_config_minimal.h
old mode 100755
new mode 100644
diff --git a/libs/SDL2/include/SDL_config_pandora.h b/libs/SDL2/include/SDL_config_pandora.h
old mode 100755
new mode 100644
diff --git a/libs/SDL2/include/SDL_config_psp.h b/libs/SDL2/include/SDL_config_psp.h
old mode 100755
new mode 100644
diff --git a/libs/SDL2/include/SDL_config_windows.h b/libs/SDL2/include/SDL_config_windows.h
old mode 100755
new mode 100644
diff --git a/libs/SDL2/include/SDL_config_winrt.h b/libs/SDL2/include/SDL_config_winrt.h
old mode 100755
new mode 100644
diff --git a/libs/SDL2/include/SDL_config_wiz.h b/libs/SDL2/include/SDL_config_wiz.h
old mode 100755
new mode 100644
diff --git a/libs/SDL2/include/SDL_copying.h b/libs/SDL2/include/SDL_copying.h
old mode 100755
new mode 100644
diff --git a/libs/SDL2/include/SDL_cpuinfo.h b/libs/SDL2/include/SDL_cpuinfo.h
old mode 100755
new mode 100644
index 94b64b03b..ee3a47e84
--- a/libs/SDL2/include/SDL_cpuinfo.h
+++ b/libs/SDL2/include/SDL_cpuinfo.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
@@ -51,27 +51,35 @@
 #include <intrin.h>
 #else
 #ifdef __ALTIVEC__
-#if HAVE_ALTIVEC_H && !defined(__APPLE_ALTIVEC__)
+#if defined(HAVE_ALTIVEC_H) && !defined(__APPLE_ALTIVEC__) && !defined(SDL_DISABLE_ALTIVEC_H)
 #include <altivec.h>
 #undef pixel
+#undef bool
 #endif
 #endif
-#ifdef __MMX__
-#include <mmintrin.h>
+#if defined(__ARM_NEON__) && !defined(SDL_DISABLE_ARM_NEON_H)
+#include <arm_neon.h>
 #endif
-#ifdef __3dNOW__
+#if defined(__3dNOW__) && !defined(SDL_DISABLE_MM3DNOW_H)
 #include <mm3dnow.h>
 #endif
-#ifdef __SSE__
+#if defined(HAVE_IMMINTRIN_H) && !defined(SDL_DISABLE_IMMINTRIN_H)
+#include <immintrin.h>
+#else
+#if defined(__MMX__) && !defined(SDL_DISABLE_MMINTRIN_H)
+#include <mmintrin.h>
+#endif
+#if defined(__SSE__) && !defined(SDL_DISABLE_XMMINTRIN_H)
 #include <xmmintrin.h>
 #endif
-#ifdef __SSE2__
+#if defined(__SSE2__) && !defined(SDL_DISABLE_EMMINTRIN_H)
 #include <emmintrin.h>
 #endif
-#ifdef __SSE3__
+#if defined(__SSE3__) && !defined(SDL_DISABLE_PMMINTRIN_H)
 #include <pmmintrin.h>
 #endif
-#endif
+#endif /* HAVE_IMMINTRIN_H */
+#endif /* compiler version */
 
 #include "begin_code.h"
 /* Set up for C function definitions, even when using C++ */
@@ -154,6 +162,11 @@ extern DECLSPEC SDL_bool SDLCALL SDL_HasAVX(void);
  */
 extern DECLSPEC SDL_bool SDLCALL SDL_HasAVX2(void);
 
+/**
+ *  This function returns true if the CPU has AVX-512F (foundation) features.
+ */
+extern DECLSPEC SDL_bool SDLCALL SDL_HasAVX512F(void);
+
 /**
  *  This function returns true if the CPU has NEON (ARM SIMD) features.
  */
@@ -164,7 +177,6 @@ extern DECLSPEC SDL_bool SDLCALL SDL_HasNEON(void);
  */
 extern DECLSPEC int SDLCALL SDL_GetSystemRAM(void);
 
-
 /* Ends C function definitions when using C++ */
 #ifdef __cplusplus
 }
diff --git a/libs/SDL2/include/SDL_egl.h b/libs/SDL2/include/SDL_egl.h
old mode 100755
new mode 100644
index e47fbe862..d65ed437c
--- a/libs/SDL2/include/SDL_egl.h
+++ b/libs/SDL2/include/SDL_egl.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
@@ -24,7 +24,7 @@
  *
  *  This is a simple file to encapsulate the EGL API headers.
  */
-#ifndef _MSC_VER
+#if !defined(_MSC_VER) && !defined(__ANDROID__)
 
 #include <EGL/egl.h>
 #include <EGL/eglext.h>
diff --git a/libs/SDL2/include/SDL_endian.h b/libs/SDL2/include/SDL_endian.h
old mode 100755
new mode 100644
index 3eda7f287..ed0bf5ba8
--- a/libs/SDL2/include/SDL_endian.h
+++ b/libs/SDL2/include/SDL_endian.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/include/SDL_error.h b/libs/SDL2/include/SDL_error.h
old mode 100755
new mode 100644
index 49be9827e..c0e46298e
--- a/libs/SDL2/include/SDL_error.h
+++ b/libs/SDL2/include/SDL_error.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/include/SDL_events.h b/libs/SDL2/include/SDL_events.h
old mode 100755
new mode 100644
index 0fc09bc37..af22eb646
--- a/libs/SDL2/include/SDL_events.h
+++ b/libs/SDL2/include/SDL_events.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
@@ -85,6 +85,9 @@ typedef enum
                                      Called on Android in onResume()
                                 */
 
+    /* Display events */
+    SDL_DISPLAYEVENT   = 0x150,  /**< Display state change */
+
     /* Window events */
     SDL_WINDOWEVENT    = 0x200, /**< Window state change */
     SDL_SYSWMEVENT,             /**< System specific event */
@@ -144,6 +147,9 @@ typedef enum
     SDL_AUDIODEVICEADDED = 0x1100, /**< A new audio device is available */
     SDL_AUDIODEVICEREMOVED,        /**< An audio device has been removed. */
 
+    /* Sensor events */
+    SDL_SENSORUPDATE = 0x1200,     /**< A sensor was updated */
+
     /* Render events */
     SDL_RENDER_TARGETS_RESET = 0x2000, /**< The render targets have been reset and their contents need to be updated */
     SDL_RENDER_DEVICE_RESET, /**< The device has been reset and all textures need to be recreated */
@@ -168,6 +174,21 @@ typedef struct SDL_CommonEvent
     Uint32 timestamp;   /**< In milliseconds, populated using SDL_GetTicks() */
 } SDL_CommonEvent;
 
+/**
+ *  \brief Display state change event data (event.display.*)
+ */
+typedef struct SDL_DisplayEvent
+{
+    Uint32 type;        /**< ::SDL_DISPLAYEVENT */
+    Uint32 timestamp;   /**< In milliseconds, populated using SDL_GetTicks() */
+    Uint32 display;     /**< The associated display index */
+    Uint8 event;        /**< ::SDL_DisplayEventID */
+    Uint8 padding1;
+    Uint8 padding2;
+    Uint8 padding3;
+    Sint32 data1;       /**< event dependent data */
+} SDL_DisplayEvent;
+
 /**
  *  \brief Window state change event data (event.window.*)
  */
@@ -471,6 +492,17 @@ typedef struct SDL_DropEvent
 } SDL_DropEvent;
 
 
+/**
+ *  \brief Sensor event structure (event.sensor.*)
+ */
+typedef struct SDL_SensorEvent
+{
+    Uint32 type;        /**< ::SDL_SENSORUPDATE */
+    Uint32 timestamp;   /**< In milliseconds, populated using SDL_GetTicks() */
+    Sint32 which;       /**< The instance ID of the sensor */
+    float data[6];      /**< Up to 6 values from the sensor - additional values can be queried using SDL_SensorGetData() */
+} SDL_SensorEvent;
+
 /**
  *  \brief The "quit requested" event
  */
@@ -526,6 +558,7 @@ typedef union SDL_Event
 {
     Uint32 type;                    /**< Event type, shared with all events */
     SDL_CommonEvent common;         /**< Common event data */
+    SDL_DisplayEvent display;       /**< Window event data */
     SDL_WindowEvent window;         /**< Window event data */
     SDL_KeyboardEvent key;          /**< Keyboard event data */
     SDL_TextEditingEvent edit;      /**< Text editing event data */
@@ -542,6 +575,7 @@ typedef union SDL_Event
     SDL_ControllerButtonEvent cbutton;  /**< Game Controller button event data */
     SDL_ControllerDeviceEvent cdevice;  /**< Game Controller device event data */
     SDL_AudioDeviceEvent adevice;   /**< Audio device event data */
+    SDL_SensorEvent sensor;         /**< Sensor event data */
     SDL_QuitEvent quit;             /**< Quit request event data */
     SDL_UserEvent user;             /**< Custom event data */
     SDL_SysWMEvent syswm;           /**< System dependent window event data */
diff --git a/libs/SDL2/include/SDL_filesystem.h b/libs/SDL2/include/SDL_filesystem.h
old mode 100755
new mode 100644
index a1c846ad0..fa6a1fa6e
--- a/libs/SDL2/include/SDL_filesystem.h
+++ b/libs/SDL2/include/SDL_filesystem.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/include/SDL_gamecontroller.h b/libs/SDL2/include/SDL_gamecontroller.h
old mode 100755
new mode 100644
index c9215132e..6ae9c9542
--- a/libs/SDL2/include/SDL_gamecontroller.h
+++ b/libs/SDL2/include/SDL_gamecontroller.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
@@ -175,6 +175,14 @@ extern DECLSPEC SDL_bool SDLCALL SDL_IsGameController(int joystick_index);
  */
 extern DECLSPEC const char *SDLCALL SDL_GameControllerNameForIndex(int joystick_index);
 
+/**
+ *  Get the mapping of a game controller.
+ *  This can be called before any controllers are opened.
+ *
+ *  \return the mapping string.  Must be freed with SDL_free().  Returns NULL if no mapping is available
+ */
+extern DECLSPEC char *SDLCALL SDL_GameControllerMappingForDeviceIndex(int joystick_index);
+
 /**
  *  Open a game controller for use.
  *  The index passed as an argument refers to the N'th game controller on the system.
@@ -196,6 +204,13 @@ extern DECLSPEC SDL_GameController *SDLCALL SDL_GameControllerFromInstanceID(SDL
  */
 extern DECLSPEC const char *SDLCALL SDL_GameControllerName(SDL_GameController *gamecontroller);
 
+/**
+ *  Get the player index of an opened game controller, or -1 if it's not available
+ *
+ *  For XInput controllers this returns the XInput user index.
+ */
+extern DECLSPEC int SDLCALL SDL_GameControllerGetPlayerIndex(SDL_GameController *gamecontroller);
+
 /**
  *  Get the USB vendor ID of an opened controller, if available.
  *  If the vendor ID isn't available this function returns 0.
@@ -345,6 +360,19 @@ SDL_GameControllerGetBindForButton(SDL_GameController *gamecontroller,
 extern DECLSPEC Uint8 SDLCALL SDL_GameControllerGetButton(SDL_GameController *gamecontroller,
                                                           SDL_GameControllerButton button);
 
+/**
+ *  Trigger a rumble effect
+ *  Each call to this function cancels any previous rumble effect, and calling it with 0 intensity stops any rumbling.
+ *
+ *  \param gamecontroller The controller to vibrate
+ *  \param low_frequency_rumble The intensity of the low frequency (left) rumble motor, from 0 to 0xFFFF
+ *  \param high_frequency_rumble The intensity of the high frequency (right) rumble motor, from 0 to 0xFFFF
+ *  \param duration_ms The duration of the rumble effect, in milliseconds
+ *
+ *  \return 0, or -1 if rumble isn't supported on this joystick
+ */
+extern DECLSPEC int SDLCALL SDL_GameControllerRumble(SDL_GameController *gamecontroller, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble, Uint32 duration_ms);
+
 /**
  *  Close a controller previously opened with SDL_GameControllerOpen().
  */
diff --git a/libs/SDL2/include/SDL_gesture.h b/libs/SDL2/include/SDL_gesture.h
old mode 100755
new mode 100644
index 2bba6a729..b223d80d4
--- a/libs/SDL2/include/SDL_gesture.h
+++ b/libs/SDL2/include/SDL_gesture.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/include/SDL_haptic.h b/libs/SDL2/include/SDL_haptic.h
old mode 100755
new mode 100644
index 60daefaa7..2ea1bfc16
--- a/libs/SDL2/include/SDL_haptic.h
+++ b/libs/SDL2/include/SDL_haptic.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
@@ -117,6 +117,17 @@
 extern "C" {
 #endif /* __cplusplus */
 
+/* FIXME: For SDL 2.1, adjust all the magnitude variables to be Uint16 (0xFFFF).
+ *
+ * At the moment the magnitude variables are mixed between signed/unsigned, and
+ * it is also not made clear that ALL of those variables expect a max of 0x7FFF.
+ *
+ * Some platforms may have higher precision than that (Linux FF, Windows XInput)
+ * so we should fix the inconsistency in favor of higher possible precision,
+ * adjusting for platforms that use different scales.
+ * -flibit
+ */
+
 /**
  *  \typedef SDL_Haptic
  *
@@ -656,8 +667,8 @@ typedef struct SDL_HapticRamp
  * This struct is exclusively for the ::SDL_HAPTIC_LEFTRIGHT effect.
  *
  * The Left/Right effect is used to explicitly control the large and small
- * motors, commonly found in modern game controllers. One motor is high
- * frequency, the other is low frequency.
+ * motors, commonly found in modern game controllers. The small (right) motor
+ * is high frequency, and the large (left) motor is low frequency.
  *
  * \sa SDL_HAPTIC_LEFTRIGHT
  * \sa SDL_HapticEffect
@@ -668,7 +679,7 @@ typedef struct SDL_HapticLeftRight
     Uint16 type;            /**< ::SDL_HAPTIC_LEFTRIGHT */
 
     /* Replay */
-    Uint32 length;          /**< Duration of the effect. */
+    Uint32 length;          /**< Duration of the effect in milliseconds. */
 
     /* Rumble */
     Uint16 large_magnitude; /**< Control of the large controller motor. */
diff --git a/libs/SDL2/include/SDL_hints.h b/libs/SDL2/include/SDL_hints.h
old mode 100755
new mode 100644
index 007a4bee0..4ee72e97d
--- a/libs/SDL2/include/SDL_hints.h
+++ b/libs/SDL2/include/SDL_hints.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
@@ -76,6 +76,7 @@ extern "C" {
  *    "opengl"
  *    "opengles2"
  *    "opengles"
+ *    "metal"
  *    "software"
  *
  *  The default varies by platform, but it's the first one in the list that
@@ -210,6 +211,18 @@ extern "C" {
  */
 #define SDL_HINT_VIDEO_X11_NET_WM_PING      "SDL_VIDEO_X11_NET_WM_PING"
 
+/**
+ * \brief A variable controlling whether the X11 _NET_WM_BYPASS_COMPOSITOR hint should be used.
+ * 
+ * This variable can be set to the following values:
+ * "0" - Disable _NET_WM_BYPASS_COMPOSITOR
+ * "1" - Enable _NET_WM_BYPASS_COMPOSITOR
+ * 
+ * By default SDL will use _NET_WM_BYPASS_COMPOSITOR
+ * 
+ */
+#define SDL_HINT_VIDEO_X11_NET_WM_BYPASS_COMPOSITOR "SDL_VIDEO_X11_NET_WM_BYPASS_COMPOSITOR"
+
 /**
  *  \brief  A variable controlling whether the window frame and title bar are interactive when the cursor is hidden 
  *
@@ -249,6 +262,16 @@ extern "C" {
  */
 #define SDL_HINT_GRAB_KEYBOARD              "SDL_GRAB_KEYBOARD"
 
+/**
+ *  \brief  A variable setting the double click time, in milliseconds.
+ */
+#define SDL_HINT_MOUSE_DOUBLE_CLICK_TIME    "SDL_MOUSE_DOUBLE_CLICK_TIME"
+
+/**
+ *  \brief  A variable setting the double click radius, in pixels.
+ */
+#define SDL_HINT_MOUSE_DOUBLE_CLICK_RADIUS    "SDL_MOUSE_DOUBLE_CLICK_RADIUS"
+
 /**
  *  \brief  A variable setting the speed scale for mouse motion, in floating point, when the mouse is not in relative mode
  */
@@ -316,7 +339,7 @@ extern "C" {
 #define SDL_HINT_IDLE_TIMER_DISABLED "SDL_IOS_IDLE_TIMER_DISABLED"
 
 /**
- *  \brief  A variable controlling which orientations are allowed on iOS.
+ *  \brief  A variable controlling which orientations are allowed on iOS/Android.
  *
  *  In some circumstances it is necessary to be able to explicitly control
  *  which UI orientations are allowed.
@@ -355,16 +378,36 @@ extern "C" {
 #define SDL_HINT_APPLE_TV_REMOTE_ALLOW_ROTATION "SDL_APPLE_TV_REMOTE_ALLOW_ROTATION"
 
 /**
- *  \brief  A variable controlling whether the Android / iOS built-in
- *  accelerometer should be listed as a joystick device, rather than listing
- *  actual joysticks only.
+ * \brief  A variable controlling whether the home indicator bar on iPhone X
+ *         should be hidden.
  *
  *  This variable can be set to the following values:
- *    "0"       - List only real joysticks and accept input from them
- *    "1"       - List real joysticks along with the accelerometer as if it were a 3 axis joystick (the default).
+ *    "0"       - The indicator bar is not hidden (default for windowed applications)
+ *    "1"       - The indicator bar is hidden and is shown when the screen is touched (useful for movie playback applications)
+ *    "2"       - The indicator bar is dim and the first swipe makes it visible and the second swipe performs the "home" action (default for fullscreen applications)
+ */
+#define SDL_HINT_IOS_HIDE_HOME_INDICATOR "SDL_IOS_HIDE_HOME_INDICATOR"
+
+/**
+ *  \brief  A variable controlling whether the Android / iOS built-in
+ *  accelerometer should be listed as a joystick device.
+ *
+ *  This variable can be set to the following values:
+ *    "0"       - The accelerometer is not listed as a joystick
+ *    "1"       - The accelerometer is available as a 3 axis joystick (the default).
  */
 #define SDL_HINT_ACCELEROMETER_AS_JOYSTICK "SDL_ACCELEROMETER_AS_JOYSTICK"
 
+/**
+ *  \brief  A variable controlling whether the Android / tvOS remotes
+ *  should be listed as joystick devices, instead of sending keyboard events.
+ *
+ *  This variable can be set to the following values:
+ *    "0"       - Remotes send enter/escape/arrow key events
+ *    "1"       - Remotes are available as 2 axis, 2 button joysticks (the default).
+ */
+#define SDL_HINT_TV_REMOTE_AS_JOYSTICK "SDL_TV_REMOTE_AS_JOYSTICK"
+
 /**
  *  \brief  A variable that lets you disable the detection and use of Xinput gamepad devices
  *
@@ -432,6 +475,88 @@ extern "C" {
  */
 #define SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS "SDL_JOYSTICK_ALLOW_BACKGROUND_EVENTS"
 
+/**
+ *  \brief  A variable controlling whether the HIDAPI joystick drivers should be used.
+ *
+ *  This variable can be set to the following values:
+ *    "0"       - HIDAPI drivers are not used
+ *    "1"       - HIDAPI drivers are used (the default)
+ *
+ *  This variable is the default for all drivers, but can be overridden by the hints for specific drivers below.
+ */
+#define SDL_HINT_JOYSTICK_HIDAPI "SDL_JOYSTICK_HIDAPI"
+
+/**
+ *  \brief  A variable controlling whether the HIDAPI driver for PS4 controllers should be used.
+ *
+ *  This variable can be set to the following values:
+ *    "0"       - HIDAPI driver is not used
+ *    "1"       - HIDAPI driver is used
+ *
+ *  The default is the value of SDL_HINT_JOYSTICK_HIDAPI
+ */
+#define SDL_HINT_JOYSTICK_HIDAPI_PS4 "SDL_JOYSTICK_HIDAPI_PS4"
+
+/**
+ *  \brief  A variable controlling whether extended input reports should be used for PS4 controllers when using the HIDAPI driver.
+ *
+ *  This variable can be set to the following values:
+ *    "0"       - extended reports are not enabled (the default)
+ *    "1"       - extended reports
+ *
+ *  Extended input reports allow rumble on Bluetooth PS4 controllers, but
+ *  break DirectInput handling for applications that don't use SDL.
+ *
+ *  Once extended reports are enabled, they can not be disabled without
+ *  power cycling the controller.
+ */
+#define SDL_HINT_JOYSTICK_HIDAPI_PS4_RUMBLE "SDL_JOYSTICK_HIDAPI_PS4_RUMBLE"
+
+/**
+ *  \brief  A variable controlling whether the HIDAPI driver for Steam Controllers should be used.
+ *
+ *  This variable can be set to the following values:
+ *    "0"       - HIDAPI driver is not used
+ *    "1"       - HIDAPI driver is used
+ *
+ *  The default is the value of SDL_HINT_JOYSTICK_HIDAPI
+ */
+#define SDL_HINT_JOYSTICK_HIDAPI_STEAM "SDL_JOYSTICK_HIDAPI_STEAM"
+
+/**
+ *  \brief  A variable controlling whether the HIDAPI driver for Nintendo Switch controllers should be used.
+ *
+ *  This variable can be set to the following values:
+ *    "0"       - HIDAPI driver is not used
+ *    "1"       - HIDAPI driver is used
+ *
+ *  The default is the value of SDL_HINT_JOYSTICK_HIDAPI
+ */
+#define SDL_HINT_JOYSTICK_HIDAPI_SWITCH "SDL_JOYSTICK_HIDAPI_SWITCH"
+
+/**
+ *  \brief  A variable controlling whether the HIDAPI driver for XBox controllers should be used.
+ *
+ *  This variable can be set to the following values:
+ *    "0"       - HIDAPI driver is not used
+ *    "1"       - HIDAPI driver is used
+ *
+ *  The default is the value of SDL_HINT_JOYSTICK_HIDAPI
+ */
+#define SDL_HINT_JOYSTICK_HIDAPI_XBOX   "SDL_JOYSTICK_HIDAPI_XBOX"
+
+/**
+ *  \brief  A variable that controls whether Steam Controllers should be exposed using the SDL joystick and game controller APIs
+ *
+ *  The variable can be set to the following values:
+ *    "0"       - Do not scan for Steam Controllers
+ *    "1"       - Scan for Steam Controllers (the default)
+ *
+ *  The default value is "1".  This hint must be set before initializing the joystick subsystem.
+ */
+#define SDL_HINT_ENABLE_STEAM_CONTROLLERS "SDL_ENABLE_STEAM_CONTROLLERS"
+
+
 /**
  *  \brief If set to "0" then never set the top most bit on a SDL Window, even if the video mode expects it.
  *      This is a debugging aid for developers and not expected to be used by end users. The default is "1"
@@ -494,6 +619,10 @@ extern "C" {
 *  This is specially useful if you build SDL against a non glibc libc library (such as musl) which
 *  provides a relatively small default thread stack size (a few kilobytes versus the default 8MB glibc uses).
 *  Support for this hint is currently available only in the pthread, Windows, and PSP backend.
+*
+*  Instead of this hint, in 2.0.9 and later, you can use
+*  SDL_CreateThreadWithStackSize(). This hint only works with the classic
+*  SDL_CreateThread().
 */
 #define SDL_HINT_THREAD_STACK_SIZE              "SDL_THREAD_STACK_SIZE"
 
@@ -719,6 +848,35 @@ extern "C" {
  */
 #define SDL_HINT_ANDROID_SEPARATE_MOUSE_AND_TOUCH "SDL_ANDROID_SEPARATE_MOUSE_AND_TOUCH"
 
+ /**
+ * \brief A variable to control whether we trap the Android back button to handle it manually.
+ *        This is necessary for the right mouse button to work on some Android devices, or
+ *        to be able to trap the back button for use in your code reliably.  If set to true,
+ *        the back button will show up as an SDL_KEYDOWN / SDL_KEYUP pair with a keycode of 
+ *        SDL_SCANCODE_AC_BACK.
+ *
+ * The variable can be set to the following values:
+ *   "0"       - Back button will be handled as usual for system. (default)
+ *   "1"       - Back button will be trapped, allowing you to handle the key press
+ *               manually.  (This will also let right mouse click work on systems 
+ *               where the right mouse button functions as back.)
+ *
+ * The value of this hint is used at runtime, so it can be changed at any time.
+ */
+#define SDL_HINT_ANDROID_TRAP_BACK_BUTTON "SDL_ANDROID_TRAP_BACK_BUTTON"
+
+ /**
+ * \brief A variable to control whether the return key on the soft keyboard
+ *        should hide the soft keyboard on Android and iOS.
+ *
+ * The variable can be set to the following values:
+ *   "0"       - The return key will be handled as a key event. This is the behaviour of SDL <= 2.0.3. (default)
+ *   "1"       - The return key will hide the keyboard.
+ *
+ * The value of this hint is used at runtime, so it can be changed at any time.
+ */
+#define SDL_HINT_RETURN_KEY_HIDES_IME "SDL_RETURN_KEY_HIDES_IME"
+
 /**
  *  \brief override the binding element for keyboard inputs for Emscripten builds
  *
@@ -752,7 +910,7 @@ extern "C" {
  *   "0"       - SDL will generate a window-close event when it sees Alt+F4.
  *   "1"       - SDL will only do normal key handling for Alt+F4.
  */
-#define SDL_HINT_WINDOWS_NO_CLOSE_ON_ALT_F4	"SDL_WINDOWS_NO_CLOSE_ON_ALT_F4"
+#define SDL_HINT_WINDOWS_NO_CLOSE_ON_ALT_F4 "SDL_WINDOWS_NO_CLOSE_ON_ALT_F4"
 
 /**
  *  \brief Prevent SDL from using version 4 of the bitmap header when saving BMPs.
@@ -797,6 +955,24 @@ extern "C" {
  */
 #define SDL_HINT_RPI_VIDEO_LAYER           "SDL_RPI_VIDEO_LAYER"
 
+/**
+ * \brief Tell the video driver that we only want a double buffer.
+ *
+ * By default, most lowlevel 2D APIs will use a triple buffer scheme that 
+ * wastes no CPU time on waiting for vsync after issuing a flip, but
+ * introduces a frame of latency. On the other hand, using a double buffer
+ * scheme instead is recommended for cases where low latency is an important
+ * factor because we save a whole frame of latency.
+ * We do so by waiting for vsync immediately after issuing a flip, usually just
+ * after eglSwapBuffers call in the backend's *_SwapWindow function.
+ *
+ * Since it's driver-specific, it's only supported where possible and
+ * implemented. Currently supported the following drivers:
+ * - KMSDRM (kmsdrm)
+ * - Raspberry Pi (raspberrypi)
+ */
+#define SDL_HINT_VIDEO_DOUBLE_BUFFER      "SDL_VIDEO_DOUBLE_BUFFER"
+
 /**
  *  \brief  A variable controlling what driver to use for OpenGL ES contexts.
  *
diff --git a/libs/SDL2/include/SDL_joystick.h b/libs/SDL2/include/SDL_joystick.h
old mode 100755
new mode 100644
index f598dc828..6e05a9c20
--- a/libs/SDL2/include/SDL_joystick.h
+++ b/libs/SDL2/include/SDL_joystick.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
@@ -97,10 +97,10 @@ typedef enum
 typedef enum
 {
     SDL_JOYSTICK_POWER_UNKNOWN = -1,
-    SDL_JOYSTICK_POWER_EMPTY,
-    SDL_JOYSTICK_POWER_LOW,
-    SDL_JOYSTICK_POWER_MEDIUM,
-    SDL_JOYSTICK_POWER_FULL,
+    SDL_JOYSTICK_POWER_EMPTY,   /* <= 5% */
+    SDL_JOYSTICK_POWER_LOW,     /* <= 20% */
+    SDL_JOYSTICK_POWER_MEDIUM,  /* <= 70% */
+    SDL_JOYSTICK_POWER_FULL,    /* <= 100% */
     SDL_JOYSTICK_POWER_WIRED,
     SDL_JOYSTICK_POWER_MAX
 } SDL_JoystickPowerLevel;
@@ -132,6 +132,12 @@ extern DECLSPEC int SDLCALL SDL_NumJoysticks(void);
  */
 extern DECLSPEC const char *SDLCALL SDL_JoystickNameForIndex(int device_index);
 
+/**
+ *  Get the player index of a joystick, or -1 if it's not available
+ *  This can be called before any joysticks are opened.
+ */
+extern DECLSPEC int SDLCALL SDL_JoystickGetDevicePlayerIndex(int device_index);
+
 /**
  *  Return the GUID for the joystick at this index
  *  This can be called before any joysticks are opened.
@@ -194,6 +200,13 @@ extern DECLSPEC SDL_Joystick *SDLCALL SDL_JoystickFromInstanceID(SDL_JoystickID
  */
 extern DECLSPEC const char *SDLCALL SDL_JoystickName(SDL_Joystick * joystick);
 
+/**
+ *  Get the player index of an opened joystick, or -1 if it's not available
+ *
+ *  For XInput controllers this returns the XInput user index.
+ */
+extern DECLSPEC int SDLCALL SDL_JoystickGetPlayerIndex(SDL_Joystick * joystick);
+
 /**
  *  Return the GUID for this opened joystick
  */
@@ -361,6 +374,19 @@ extern DECLSPEC int SDLCALL SDL_JoystickGetBall(SDL_Joystick * joystick,
 extern DECLSPEC Uint8 SDLCALL SDL_JoystickGetButton(SDL_Joystick * joystick,
                                                     int button);
 
+/**
+ *  Trigger a rumble effect
+ *  Each call to this function cancels any previous rumble effect, and calling it with 0 intensity stops any rumbling.
+ *
+ *  \param joystick The joystick to vibrate
+ *  \param low_frequency_rumble The intensity of the low frequency (left) rumble motor, from 0 to 0xFFFF
+ *  \param high_frequency_rumble The intensity of the high frequency (right) rumble motor, from 0 to 0xFFFF
+ *  \param duration_ms The duration of the rumble effect, in milliseconds
+ *
+ *  \return 0, or -1 if rumble isn't supported on this joystick
+ */
+extern DECLSPEC int SDLCALL SDL_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble, Uint32 duration_ms);
+
 /**
  *  Close a joystick previously opened with SDL_JoystickOpen().
  */
diff --git a/libs/SDL2/include/SDL_keyboard.h b/libs/SDL2/include/SDL_keyboard.h
old mode 100755
new mode 100644
index e78ca4690..874823171
--- a/libs/SDL2/include/SDL_keyboard.h
+++ b/libs/SDL2/include/SDL_keyboard.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/include/SDL_keycode.h b/libs/SDL2/include/SDL_keycode.h
old mode 100755
new mode 100644
index c41e45ff6..d7d5b1dbc
--- a/libs/SDL2/include/SDL_keycode.h
+++ b/libs/SDL2/include/SDL_keycode.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/include/SDL_loadso.h b/libs/SDL2/include/SDL_loadso.h
old mode 100755
new mode 100644
index 6ea256c6a..da56fb452
--- a/libs/SDL2/include/SDL_loadso.h
+++ b/libs/SDL2/include/SDL_loadso.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/include/SDL_log.h b/libs/SDL2/include/SDL_log.h
old mode 100755
new mode 100644
index 356d0e1cf..e12b65886
--- a/libs/SDL2/include/SDL_log.h
+++ b/libs/SDL2/include/SDL_log.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/include/SDL_main.h b/libs/SDL2/include/SDL_main.h
old mode 100755
new mode 100644
index 2af32360f..98558217f
--- a/libs/SDL2/include/SDL_main.h
+++ b/libs/SDL2/include/SDL_main.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
@@ -63,10 +63,13 @@
 /* On Android SDL provides a Java class in SDLActivity.java that is the
    main activity entry point.
 
-   See README-android.md for more details on extending that class.
+   See docs/README-android.md for more details on extending that class.
  */
 #define SDL_MAIN_NEEDED
 
+/* We need to export SDL_main so it can be launched from Java */
+#define SDLMAIN_DECLSPEC    DECLSPEC
+
 #elif defined(__NACL__)
 /* On NACL we use ppapi_simple to set up the application helper code,
    then wait for the first PSE_INSTANCE_DIDCHANGEVIEW event before 
@@ -85,6 +88,10 @@
 #define C_LINKAGE
 #endif /* __cplusplus */
 
+#ifndef SDLMAIN_DECLSPEC
+#define SDLMAIN_DECLSPEC
+#endif
+
 /**
  *  \file SDL_main.h
  *
@@ -107,7 +114,7 @@
 /**
  *  The prototype for the application's main() function
  */
-extern C_LINKAGE DECLSPEC int SDL_main(int argc, char *argv[]);
+extern C_LINKAGE SDLMAIN_DECLSPEC int SDL_main(int argc, char *argv[]);
 
 
 #include "begin_code.h"
diff --git a/libs/SDL2/include/SDL_messagebox.h b/libs/SDL2/include/SDL_messagebox.h
old mode 100755
new mode 100644
index c326d8f01..b7be59d88
--- a/libs/SDL2/include/SDL_messagebox.h
+++ b/libs/SDL2/include/SDL_messagebox.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/include/SDL_mouse.h b/libs/SDL2/include/SDL_mouse.h
old mode 100755
new mode 100644
index 6001bd46c..d3c9f6156
--- a/libs/SDL2/include/SDL_mouse.h
+++ b/libs/SDL2/include/SDL_mouse.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/include/SDL_mutex.h b/libs/SDL2/include/SDL_mutex.h
old mode 100755
new mode 100644
index 0272379e5..ba4247ced
--- a/libs/SDL2/include/SDL_mutex.h
+++ b/libs/SDL2/include/SDL_mutex.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/include/SDL_name.h b/libs/SDL2/include/SDL_name.h
old mode 100755
new mode 100644
index 8095ed3ff..ecd863f4c
--- a/libs/SDL2/include/SDL_name.h
+++ b/libs/SDL2/include/SDL_name.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/include/SDL_opengl.h b/libs/SDL2/include/SDL_opengl.h
old mode 100755
new mode 100644
index 314dd57ed..253d9c93a
--- a/libs/SDL2/include/SDL_opengl.h
+++ b/libs/SDL2/include/SDL_opengl.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/include/SDL_opengl_glext.h b/libs/SDL2/include/SDL_opengl_glext.h
old mode 100755
new mode 100644
diff --git a/libs/SDL2/include/SDL_opengles.h b/libs/SDL2/include/SDL_opengles.h
old mode 100755
new mode 100644
index 800c59307..18dd984b3
--- a/libs/SDL2/include/SDL_opengles.h
+++ b/libs/SDL2/include/SDL_opengles.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/include/SDL_opengles2.h b/libs/SDL2/include/SDL_opengles2.h
old mode 100755
new mode 100644
index 102f2f3fa..6ccecf216
--- a/libs/SDL2/include/SDL_opengles2.h
+++ b/libs/SDL2/include/SDL_opengles2.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/include/SDL_opengles2_gl2.h b/libs/SDL2/include/SDL_opengles2_gl2.h
old mode 100755
new mode 100644
diff --git a/libs/SDL2/include/SDL_opengles2_gl2ext.h b/libs/SDL2/include/SDL_opengles2_gl2ext.h
old mode 100755
new mode 100644
diff --git a/libs/SDL2/include/SDL_opengles2_gl2platform.h b/libs/SDL2/include/SDL_opengles2_gl2platform.h
old mode 100755
new mode 100644
diff --git a/libs/SDL2/include/SDL_opengles2_khrplatform.h b/libs/SDL2/include/SDL_opengles2_khrplatform.h
old mode 100755
new mode 100644
diff --git a/libs/SDL2/include/SDL_pixels.h b/libs/SDL2/include/SDL_pixels.h
old mode 100755
new mode 100644
index 04246689f..0b4364b18
--- a/libs/SDL2/include/SDL_pixels.h
+++ b/libs/SDL2/include/SDL_pixels.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
@@ -287,7 +287,9 @@ enum
     SDL_PIXELFORMAT_NV12 =      /**< Planar mode: Y + U/V interleaved  (2 planes) */
         SDL_DEFINE_PIXELFOURCC('N', 'V', '1', '2'),
     SDL_PIXELFORMAT_NV21 =      /**< Planar mode: Y + V/U interleaved  (2 planes) */
-        SDL_DEFINE_PIXELFOURCC('N', 'V', '2', '1')
+        SDL_DEFINE_PIXELFOURCC('N', 'V', '2', '1'),
+    SDL_PIXELFORMAT_EXTERNAL_OES =      /**< Android video texture format */
+        SDL_DEFINE_PIXELFOURCC('O', 'E', 'S', ' ')
 };
 
 typedef struct SDL_Color
diff --git a/libs/SDL2/include/SDL_platform.h b/libs/SDL2/include/SDL_platform.h
old mode 100755
new mode 100644
index 9dde385fa..7dea4ce94
--- a/libs/SDL2/include/SDL_platform.h
+++ b/libs/SDL2/include/SDL_platform.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
@@ -121,7 +121,12 @@
 #if defined(WIN32) || defined(_WIN32) || defined(__CYGWIN__) || defined(__MINGW32__)
 /* Try to find out if we're compiling for WinRT or non-WinRT */
 #if defined(_MSC_VER) && defined(__has_include)
-#define HAVE_WINAPIFAMILY_H __has_include(<winapifamily.h>)
+#if __has_include(<winapifamily.h>)
+#define HAVE_WINAPIFAMILY_H 1
+#else
+#define HAVE_WINAPIFAMILY_H 0
+#endif
+
 /* If _USING_V110_SDK71_ is defined it means we are using the Windows XP toolset. */
 #elif defined(_MSC_VER) && (_MSC_VER >= 1700 && !_USING_V110_SDK71_)    /* _MSC_VER == 1700 for Visual Studio 2012 */
 #define HAVE_WINAPIFAMILY_H 1
diff --git a/libs/SDL2/include/SDL_power.h b/libs/SDL2/include/SDL_power.h
old mode 100755
new mode 100644
index d48e8a379..a4fe8a935
--- a/libs/SDL2/include/SDL_power.h
+++ b/libs/SDL2/include/SDL_power.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/include/SDL_quit.h b/libs/SDL2/include/SDL_quit.h
old mode 100755
new mode 100644
index 9283c3810..fea56a8d8
--- a/libs/SDL2/include/SDL_quit.h
+++ b/libs/SDL2/include/SDL_quit.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/include/SDL_rect.h b/libs/SDL2/include/SDL_rect.h
old mode 100755
new mode 100644
index c4f6d74b3..543bb6186
--- a/libs/SDL2/include/SDL_rect.h
+++ b/libs/SDL2/include/SDL_rect.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/include/SDL_render.h b/libs/SDL2/include/SDL_render.h
old mode 100755
new mode 100644
index ea6ef9ff6..d33619297
--- a/libs/SDL2/include/SDL_render.h
+++ b/libs/SDL2/include/SDL_render.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
@@ -898,6 +898,27 @@ extern DECLSPEC int SDLCALL SDL_GL_BindTexture(SDL_Texture *texture, float *texw
  */
 extern DECLSPEC int SDLCALL SDL_GL_UnbindTexture(SDL_Texture *texture);
 
+/**
+ *  \brief Get the CAMetalLayer associated with the given Metal renderer
+ *
+ *  \param renderer The renderer to query
+ *
+ *  \return CAMetalLayer* on success, or NULL if the renderer isn't a Metal renderer
+ *
+ *  \sa SDL_RenderGetMetalCommandEncoder()
+ */
+extern DECLSPEC void *SDLCALL SDL_RenderGetMetalLayer(SDL_Renderer * renderer);
+
+/**
+ *  \brief Get the Metal command encoder for the current frame
+ *
+ *  \param renderer The renderer to query
+ *
+ *  \return id<MTLRenderCommandEncoder> on success, or NULL if the renderer isn't a Metal renderer
+ *
+ *  \sa SDL_RenderGetMetalLayer()
+ */
+extern DECLSPEC void *SDLCALL SDL_RenderGetMetalCommandEncoder(SDL_Renderer * renderer);
 
 /* Ends C function definitions when using C++ */
 #ifdef __cplusplus
diff --git a/libs/SDL2/include/SDL_revision.h b/libs/SDL2/include/SDL_revision.h
old mode 100755
new mode 100644
index 9376093ee..92fbe67b1
--- a/libs/SDL2/include/SDL_revision.h
+++ b/libs/SDL2/include/SDL_revision.h
@@ -1,2 +1,2 @@
-#define SDL_REVISION "hg-11645:2088cd828335"
-#define SDL_REVISION_NUMBER 11645
+#define SDL_REVISION "hg-12373:8feb5da6f2fb"
+#define SDL_REVISION_NUMBER 12373
diff --git a/libs/SDL2/include/SDL_rwops.h b/libs/SDL2/include/SDL_rwops.h
old mode 100755
new mode 100644
index 7f0cbdfd5..0960699d4
--- a/libs/SDL2/include/SDL_rwops.h
+++ b/libs/SDL2/include/SDL_rwops.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/include/SDL_scancode.h b/libs/SDL2/include/SDL_scancode.h
old mode 100755
new mode 100644
index 1d5521204..63871aa3b
--- a/libs/SDL2/include/SDL_scancode.h
+++ b/libs/SDL2/include/SDL_scancode.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/include/SDL_sensor.h b/libs/SDL2/include/SDL_sensor.h
new file mode 100644
index 000000000..ac163a8cd
--- /dev/null
+++ b/libs/SDL2/include/SDL_sensor.h
@@ -0,0 +1,251 @@
+/*
+  Simple DirectMedia Layer
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+  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 SDL_sensor.h
+ *
+ *  Include file for SDL sensor event handling
+ *
+ */
+
+#ifndef _SDL_sensor_h
+#define _SDL_sensor_h
+
+#include "SDL_stdinc.h"
+#include "SDL_error.h"
+
+#include "begin_code.h"
+/* Set up for C function definitions, even when using C++ */
+#ifdef __cplusplus
+/* *INDENT-OFF* */
+extern "C" {
+/* *INDENT-ON* */
+#endif
+
+/**
+ *  \brief SDL_sensor.h
+ *
+ *  In order to use these functions, SDL_Init() must have been called
+ *  with the ::SDL_INIT_SENSOR flag.  This causes SDL to scan the system
+ *  for sensors, and load appropriate drivers.
+ */
+
+struct _SDL_Sensor;
+typedef struct _SDL_Sensor SDL_Sensor;
+
+/**
+ * This is a unique ID for a sensor for the time it is connected to the system,
+ * and is never reused for the lifetime of the application.
+ *
+ * The ID value starts at 0 and increments from there. The value -1 is an invalid ID.
+ */
+typedef Sint32 SDL_SensorID;
+
+/* The different sensors defined by SDL
+ *
+ * Additional sensors may be available, using platform dependent semantics.
+ *
+ * Hare are the additional Android sensors:
+ * https://developer.android.com/reference/android/hardware/SensorEvent.html#values
+ */
+typedef enum
+{
+    SDL_SENSOR_INVALID = -1,    /**< Returned for an invalid sensor */
+    SDL_SENSOR_UNKNOWN,         /**< Unknown sensor type */
+    SDL_SENSOR_ACCEL,           /**< Accelerometer */
+    SDL_SENSOR_GYRO             /**< Gyroscope */
+} SDL_SensorType;
+
+/**
+ * Accelerometer sensor
+ *
+ * The accelerometer returns the current acceleration in SI meters per
+ * second squared. This includes gravity, so a device at rest will have
+ * an acceleration of SDL_STANDARD_GRAVITY straight down.
+ *
+ * values[0]: Acceleration on the x axis
+ * values[1]: Acceleration on the y axis
+ * values[2]: Acceleration on the z axis
+ *
+ * For phones held in portrait mode, the axes are defined as follows:
+ * -X ... +X : left ... right
+ * -Y ... +Y : bottom ... top
+ * -Z ... +Z : farther ... closer
+ * 
+ * The axis data is not changed when the phone is rotated.
+ *
+ * \sa SDL_GetDisplayOrientation()
+ */
+#define SDL_STANDARD_GRAVITY    9.80665f
+
+/**
+ * Gyroscope sensor
+ *
+ * The gyroscope returns the current rate of rotation in radians per second.
+ * The rotation is positive in the counter-clockwise direction. That is,
+ * an observer looking from a positive location on one of the axes would
+ * see positive rotation on that axis when it appeared to be rotating
+ * counter-clockwise.
+ *
+ * values[0]: Angular speed around the x axis
+ * values[1]: Angular speed around the y axis
+ * values[2]: Angular speed around the z axis
+ *
+ * For phones held in portrait mode, the axes are defined as follows:
+ * -X ... +X : left ... right
+ * -Y ... +Y : bottom ... top
+ * -Z ... +Z : farther ... closer
+ * 
+ * The axis data is not changed when the phone is rotated.
+ *
+ * \sa SDL_GetDisplayOrientation()
+ */
+
+/* Function prototypes */
+
+/**
+ *  \brief Count the number of sensors attached to the system right now
+ */
+extern DECLSPEC int SDLCALL SDL_NumSensors(void);
+
+/**
+ *  \brief Get the implementation dependent name of a sensor.
+ *
+ *  This can be called before any sensors are opened.
+ * 
+ *  \return The sensor name, or NULL if device_index is out of range.
+ */
+extern DECLSPEC const char *SDLCALL SDL_SensorGetDeviceName(int device_index);
+
+/**
+ *  \brief Get the type of a sensor.
+ *
+ *  This can be called before any sensors are opened.
+ *
+ *  \return The sensor type, or SDL_SENSOR_INVALID if device_index is out of range.
+ */
+extern DECLSPEC SDL_SensorType SDLCALL SDL_SensorGetDeviceType(int device_index);
+
+/**
+ *  \brief Get the platform dependent type of a sensor.
+ *
+ *  This can be called before any sensors are opened.
+ *
+ *  \return The sensor platform dependent type, or -1 if device_index is out of range.
+ */
+extern DECLSPEC int SDLCALL SDL_SensorGetDeviceNonPortableType(int device_index);
+
+/**
+ *  \brief Get the instance ID of a sensor.
+ *
+ *  This can be called before any sensors are opened.
+ *
+ *  \return The sensor instance ID, or -1 if device_index is out of range.
+ */
+extern DECLSPEC SDL_SensorID SDLCALL SDL_SensorGetDeviceInstanceID(int device_index);
+
+/**
+ *  \brief Open a sensor for use.
+ *
+ *  The index passed as an argument refers to the N'th sensor on the system.
+ *
+ *  \return A sensor identifier, or NULL if an error occurred.
+ */
+extern DECLSPEC SDL_Sensor *SDLCALL SDL_SensorOpen(int device_index);
+
+/**
+ * Return the SDL_Sensor associated with an instance id.
+ */
+extern DECLSPEC SDL_Sensor *SDLCALL SDL_SensorFromInstanceID(SDL_SensorID instance_id);
+
+/**
+ *  \brief Get the implementation dependent name of a sensor.
+ *
+ *  \return The sensor name, or NULL if the sensor is NULL.
+ */
+extern DECLSPEC const char *SDLCALL SDL_SensorGetName(SDL_Sensor *sensor);
+
+/**
+ *  \brief Get the type of a sensor.
+ *
+ *  This can be called before any sensors are opened.
+ *
+ *  \return The sensor type, or SDL_SENSOR_INVALID if the sensor is NULL.
+ */
+extern DECLSPEC SDL_SensorType SDLCALL SDL_SensorGetType(SDL_Sensor *sensor);
+
+/**
+ *  \brief Get the platform dependent type of a sensor.
+ *
+ *  This can be called before any sensors are opened.
+ *
+ *  \return The sensor platform dependent type, or -1 if the sensor is NULL.
+ */
+extern DECLSPEC int SDLCALL SDL_SensorGetNonPortableType(SDL_Sensor *sensor);
+
+/**
+ *  \brief Get the instance ID of a sensor.
+ *
+ *  This can be called before any sensors are opened.
+ *
+ *  \return The sensor instance ID, or -1 if the sensor is NULL.
+ */
+extern DECLSPEC SDL_SensorID SDLCALL SDL_SensorGetInstanceID(SDL_Sensor *sensor);
+
+/**
+ *  Get the current state of an opened sensor.
+ *
+ *  The number of values and interpretation of the data is sensor dependent.
+ *
+ *  \param sensor The sensor to query
+ *  \param data A pointer filled with the current sensor state
+ *  \param num_values The number of values to write to data
+ *
+ *  \return 0 or -1 if an error occurred.
+ */
+extern DECLSPEC int SDLCALL SDL_SensorGetData(SDL_Sensor * sensor, float *data, int num_values);
+
+/**
+ *  Close a sensor previously opened with SDL_SensorOpen()
+ */
+extern DECLSPEC void SDLCALL SDL_SensorClose(SDL_Sensor * sensor);
+
+/**
+ *  Update the current state of the open sensors.
+ *
+ *  This is called automatically by the event loop if sensor events are enabled.
+ *
+ *  This needs to be called from the thread that initialized the sensor subsystem.
+ */
+extern DECLSPEC void SDLCALL SDL_SensorUpdate(void);
+
+
+/* Ends C function definitions when using C++ */
+#ifdef __cplusplus
+/* *INDENT-OFF* */
+}
+/* *INDENT-ON* */
+#endif
+#include "close_code.h"
+
+#endif /* _SDL_sensor_h */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/libs/SDL2/include/SDL_shape.h b/libs/SDL2/include/SDL_shape.h
old mode 100755
new mode 100644
index 9e492d93a..40a6baaae
--- a/libs/SDL2/include/SDL_shape.h
+++ b/libs/SDL2/include/SDL_shape.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/include/SDL_stdinc.h b/libs/SDL2/include/SDL_stdinc.h
old mode 100755
new mode 100644
index 72402299f..e373bc380
--- a/libs/SDL2/include/SDL_stdinc.h
+++ b/libs/SDL2/include/SDL_stdinc.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
@@ -86,6 +86,28 @@
 #ifdef HAVE_FLOAT_H
 # include <float.h>
 #endif
+#if defined(HAVE_ALLOCA) && !defined(alloca)
+# if defined(HAVE_ALLOCA_H)
+#  include <alloca.h>
+# elif defined(__GNUC__)
+#  define alloca __builtin_alloca
+# elif defined(_MSC_VER)
+#  include <malloc.h>
+#  define alloca _alloca
+# elif defined(__WATCOMC__)
+#  include <malloc.h>
+# elif defined(__BORLANDC__)
+#  include <malloc.h>
+# elif defined(__DMC__)
+#  include <stdlib.h>
+# elif defined(__AIX__)
+#pragma alloca
+# elif defined(__MRC__)
+void *alloca(unsigned);
+# else
+char *alloca();
+# endif
+#endif
 
 /**
  *  The number of elements in an array.
@@ -328,28 +350,6 @@ SDL_COMPILE_TIME_ASSERT(enum, sizeof(SDL_DUMMY_ENUM) == sizeof(int));
 extern "C" {
 #endif
 
-#if defined(HAVE_ALLOCA) && !defined(alloca)
-# if defined(HAVE_ALLOCA_H)
-#  include <alloca.h>
-# elif defined(__GNUC__)
-#  define alloca __builtin_alloca
-# elif defined(_MSC_VER)
-#  include <malloc.h>
-#  define alloca _alloca
-# elif defined(__WATCOMC__)
-#  include <malloc.h>
-# elif defined(__BORLANDC__)
-#  include <malloc.h>
-# elif defined(__DMC__)
-#  include <stdlib.h>
-# elif defined(__AIX__)
-#pragma alloca
-# elif defined(__MRC__)
-void *alloca(unsigned);
-# else
-char *alloca();
-# endif
-#endif
 #ifdef HAVE_ALLOCA
 #define SDL_stack_alloc(type, count)    (type*)alloca(sizeof(type)*(count))
 #define SDL_stack_free(data)
@@ -445,12 +445,12 @@ SDL_FORCE_INLINE void SDL_memset4(void *dst, Uint32 val, size_t dwords)
 #endif
 }
 
-
 extern DECLSPEC void *SDLCALL SDL_memcpy(SDL_OUT_BYTECAP(len) void *dst, SDL_IN_BYTECAP(len) const void *src, size_t len);
 
 extern DECLSPEC void *SDLCALL SDL_memmove(SDL_OUT_BYTECAP(len) void *dst, SDL_IN_BYTECAP(len) const void *src, size_t len);
 extern DECLSPEC int SDLCALL SDL_memcmp(const void *s1, const void *s2, size_t len);
 
+extern DECLSPEC wchar_t *SDLCALL SDL_wcsdup(const wchar_t *wstr);
 extern DECLSPEC size_t SDLCALL SDL_wcslen(const wchar_t *wstr);
 extern DECLSPEC size_t SDLCALL SDL_wcslcpy(SDL_OUT_Z_CAP(maxlen) wchar_t *dst, const wchar_t *src, size_t maxlen);
 extern DECLSPEC size_t SDLCALL SDL_wcslcat(SDL_INOUT_Z_CAP(maxlen) wchar_t *dst, const wchar_t *src, size_t maxlen);
@@ -501,18 +501,35 @@ extern DECLSPEC int SDLCALL SDL_vsnprintf(SDL_OUT_Z_CAP(maxlen) char *text, size
 #endif
 
 extern DECLSPEC double SDLCALL SDL_acos(double x);
+extern DECLSPEC float SDLCALL SDL_acosf(float x);
 extern DECLSPEC double SDLCALL SDL_asin(double x);
+extern DECLSPEC float SDLCALL SDL_asinf(float x);
 extern DECLSPEC double SDLCALL SDL_atan(double x);
+extern DECLSPEC float SDLCALL SDL_atanf(float x);
 extern DECLSPEC double SDLCALL SDL_atan2(double x, double y);
+extern DECLSPEC float SDLCALL SDL_atan2f(float x, float y);
 extern DECLSPEC double SDLCALL SDL_ceil(double x);
+extern DECLSPEC float SDLCALL SDL_ceilf(float x);
 extern DECLSPEC double SDLCALL SDL_copysign(double x, double y);
+extern DECLSPEC float SDLCALL SDL_copysignf(float x, float y);
 extern DECLSPEC double SDLCALL SDL_cos(double x);
 extern DECLSPEC float SDLCALL SDL_cosf(float x);
+extern DECLSPEC double SDLCALL SDL_exp(double x);
+extern DECLSPEC float SDLCALL SDL_expf(float x);
 extern DECLSPEC double SDLCALL SDL_fabs(double x);
+extern DECLSPEC float SDLCALL SDL_fabsf(float x);
 extern DECLSPEC double SDLCALL SDL_floor(double x);
+extern DECLSPEC float SDLCALL SDL_floorf(float x);
+extern DECLSPEC double SDLCALL SDL_fmod(double x, double y);
+extern DECLSPEC float SDLCALL SDL_fmodf(float x, float y);
 extern DECLSPEC double SDLCALL SDL_log(double x);
+extern DECLSPEC float SDLCALL SDL_logf(float x);
+extern DECLSPEC double SDLCALL SDL_log10(double x);
+extern DECLSPEC float SDLCALL SDL_log10f(float x);
 extern DECLSPEC double SDLCALL SDL_pow(double x, double y);
+extern DECLSPEC float SDLCALL SDL_powf(float x, float y);
 extern DECLSPEC double SDLCALL SDL_scalbn(double x, int n);
+extern DECLSPEC float SDLCALL SDL_scalbnf(float x, int n);
 extern DECLSPEC double SDLCALL SDL_sin(double x);
 extern DECLSPEC float SDLCALL SDL_sinf(float x);
 extern DECLSPEC double SDLCALL SDL_sqrt(double x);
diff --git a/libs/SDL2/include/SDL_surface.h b/libs/SDL2/include/SDL_surface.h
old mode 100755
new mode 100644
index 510690c9c..730d49fc8
--- a/libs/SDL2/include/SDL_surface.h
+++ b/libs/SDL2/include/SDL_surface.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
@@ -97,6 +97,17 @@ typedef struct SDL_Surface
 typedef int (SDLCALL *SDL_blit) (struct SDL_Surface * src, SDL_Rect * srcrect,
                                  struct SDL_Surface * dst, SDL_Rect * dstrect);
 
+/**
+ * \brief The formula used for converting between YUV and RGB
+ */
+typedef enum
+{
+    SDL_YUV_CONVERSION_JPEG,        /**< Full range JPEG */
+    SDL_YUV_CONVERSION_BT601,       /**< BT.601 (the default) */
+    SDL_YUV_CONVERSION_BT709,       /**< BT.709 */
+    SDL_YUV_CONVERSION_AUTOMATIC    /**< BT.601 for SD content, BT.709 for HD content */
+} SDL_YUV_CONVERSION_MODE;
+
 /**
  *  Allocate and free an RGB surface.
  *
@@ -237,6 +248,13 @@ extern DECLSPEC int SDLCALL SDL_SetSurfaceRLE(SDL_Surface * surface,
 extern DECLSPEC int SDLCALL SDL_SetColorKey(SDL_Surface * surface,
                                             int flag, Uint32 key);
 
+/**
+ *  \brief Returns whether the surface has a color key
+ *
+ *  \return SDL_TRUE if the surface has a color key, or SDL_FALSE if the surface is NULL or has no color key
+ */
+extern DECLSPEC SDL_bool SDLCALL SDL_HasColorKey(SDL_Surface * surface);
+
 /**
  *  \brief Gets the color key (transparent pixel) in a blittable surface.
  *
@@ -509,6 +527,20 @@ extern DECLSPEC int SDLCALL SDL_LowerBlitScaled
     (SDL_Surface * src, SDL_Rect * srcrect,
     SDL_Surface * dst, SDL_Rect * dstrect);
 
+/**
+ *  \brief Set the YUV conversion mode
+ */
+extern DECLSPEC void SDLCALL SDL_SetYUVConversionMode(SDL_YUV_CONVERSION_MODE mode);
+
+/**
+ *  \brief Get the YUV conversion mode
+ */
+extern DECLSPEC SDL_YUV_CONVERSION_MODE SDLCALL SDL_GetYUVConversionMode(void);
+
+/**
+ *  \brief Get the YUV conversion mode, returning the correct mode for the resolution when the current conversion mode is SDL_YUV_CONVERSION_AUTOMATIC
+ */
+extern DECLSPEC SDL_YUV_CONVERSION_MODE SDLCALL SDL_GetYUVConversionModeForResolution(int width, int height);
 
 /* Ends C function definitions when using C++ */
 #ifdef __cplusplus
diff --git a/libs/SDL2/include/SDL_system.h b/libs/SDL2/include/SDL_system.h
old mode 100755
new mode 100644
index eb069b33d..4dc372d6b
--- a/libs/SDL2/include/SDL_system.h
+++ b/libs/SDL2/include/SDL_system.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
@@ -76,6 +76,18 @@ extern DECLSPEC SDL_bool SDLCALL SDL_DXGIGetOutputInfo( int displayIndex, int *a
 #endif /* __WIN32__ */
 
 
+/* Platform specific functions for Linux */
+#ifdef __LINUX__
+
+/**
+   \brief Sets the UNIX nice value for a thread, using setpriority() if possible, and RealtimeKit if available.
+
+   \return 0 on success, or -1 on error.
+ */
+extern DECLSPEC int SDLCALL SDL_LinuxSetThreadPriority(Sint64 threadID, int priority);
+ 
+#endif /* __LINUX__ */
+	
 /* Platform specific functions for iOS */
 #if defined(__IPHONEOS__) && __IPHONEOS__
 
@@ -108,6 +120,26 @@ extern DECLSPEC void * SDLCALL SDL_AndroidGetJNIEnv(void);
  */
 extern DECLSPEC void * SDLCALL SDL_AndroidGetActivity(void);
 
+/**
+   \brief Return true if the application is running on Android TV
+ */
+extern DECLSPEC SDL_bool SDLCALL SDL_IsAndroidTV(void);
+
+/**
+   \brief Return true if the application is running on a Chromebook
+ */
+extern DECLSPEC SDL_bool SDLCALL SDL_IsChromebook(void);
+
+/**
+  \brief Return true is the application is running on a Samsung DeX docking station
+ */
+extern DECLSPEC SDL_bool SDLCALL SDL_IsDeXMode(void);
+
+/**
+ \brief Trigger the Android system back button behavior.
+ */
+extern DECLSPEC void SDLCALL SDL_AndroidBackButton(void);
+
 /**
    See the official Android developer guide for more information:
    http://developer.android.com/guide/topics/data/data-storage.html
@@ -169,6 +201,25 @@ typedef enum
 } SDL_WinRT_Path;
 
 
+/**
+ *  \brief WinRT Device Family
+ */
+typedef enum
+{
+    /** \brief Unknown family  */
+    SDL_WINRT_DEVICEFAMILY_UNKNOWN,
+
+    /** \brief Desktop family*/
+    SDL_WINRT_DEVICEFAMILY_DESKTOP,
+
+    /** \brief Mobile family (for example smartphone) */
+    SDL_WINRT_DEVICEFAMILY_MOBILE,
+
+    /** \brief XBox family */
+    SDL_WINRT_DEVICEFAMILY_XBOX,
+} SDL_WinRT_DeviceFamily;
+
+
 /**
  *  \brief Retrieves a WinRT defined path on the local file system
  *
@@ -203,8 +254,20 @@ extern DECLSPEC const wchar_t * SDLCALL SDL_WinRTGetFSPathUNICODE(SDL_WinRT_Path
  */
 extern DECLSPEC const char * SDLCALL SDL_WinRTGetFSPathUTF8(SDL_WinRT_Path pathType);
 
+/**
+ *  \brief Detects the device family of WinRT plattform on runtime
+ *
+ *  \return Device family
+ */
+extern DECLSPEC SDL_WinRT_DeviceFamily SDLCALL SDL_WinRTGetDeviceFamily();
+
 #endif /* __WINRT__ */
 
+/**
+ \brief Return true if the current device is a tablet.
+ */
+extern DECLSPEC SDL_bool SDLCALL SDL_IsTablet(void);
+
 /* Ends C function definitions when using C++ */
 #ifdef __cplusplus
 }
diff --git a/libs/SDL2/include/SDL_syswm.h b/libs/SDL2/include/SDL_syswm.h
old mode 100755
new mode 100644
index 2d18afb6c..f1c4021cc
--- a/libs/SDL2/include/SDL_syswm.h
+++ b/libs/SDL2/include/SDL_syswm.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
@@ -33,12 +33,6 @@
 #include "SDL_video.h"
 #include "SDL_version.h"
 
-#include "begin_code.h"
-/* Set up for C function definitions, even when using C++ */
-#ifdef __cplusplus
-extern "C" {
-#endif
-
 /**
  *  \file SDL_syswm.h
  *
@@ -110,6 +104,12 @@ typedef void *EGLSurface;
 #include "SDL_egl.h"
 #endif
 
+#include "begin_code.h"
+/* Set up for C function definitions, even when using C++ */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 /**
  *  These are the various supported windowing subsystems
  */
diff --git a/libs/SDL2/include/SDL_test.h b/libs/SDL2/include/SDL_test.h
old mode 100755
new mode 100644
index f55afcb02..6cc373bf8
--- a/libs/SDL2/include/SDL_test.h
+++ b/libs/SDL2/include/SDL_test.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/include/SDL_test_assert.h b/libs/SDL2/include/SDL_test_assert.h
old mode 100755
new mode 100644
index 11d836394..1788d7a20
--- a/libs/SDL2/include/SDL_test_assert.h
+++ b/libs/SDL2/include/SDL_test_assert.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/include/SDL_test_common.h b/libs/SDL2/include/SDL_test_common.h
old mode 100755
new mode 100644
index 24eeb32af..be2e6b2aa
--- a/libs/SDL2/include/SDL_test_common.h
+++ b/libs/SDL2/include/SDL_test_common.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/include/SDL_test_compare.h b/libs/SDL2/include/SDL_test_compare.h
old mode 100755
new mode 100644
index 9f4c4587a..c22e447d8
--- a/libs/SDL2/include/SDL_test_compare.h
+++ b/libs/SDL2/include/SDL_test_compare.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/include/SDL_test_crc32.h b/libs/SDL2/include/SDL_test_crc32.h
old mode 100755
new mode 100644
index add480c34..3d235d074
--- a/libs/SDL2/include/SDL_test_crc32.h
+++ b/libs/SDL2/include/SDL_test_crc32.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/include/SDL_test_font.h b/libs/SDL2/include/SDL_test_font.h
old mode 100755
new mode 100644
index 58c9f9d5e..59cbdcad6
--- a/libs/SDL2/include/SDL_test_font.h
+++ b/libs/SDL2/include/SDL_test_font.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/include/SDL_test_fuzzer.h b/libs/SDL2/include/SDL_test_fuzzer.h
old mode 100755
new mode 100644
index 6cf05747a..8fcb9ebbf
--- a/libs/SDL2/include/SDL_test_fuzzer.h
+++ b/libs/SDL2/include/SDL_test_fuzzer.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/include/SDL_test_harness.h b/libs/SDL2/include/SDL_test_harness.h
old mode 100755
new mode 100644
index 68c4bcb7c..8641e0a7e
--- a/libs/SDL2/include/SDL_test_harness.h
+++ b/libs/SDL2/include/SDL_test_harness.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/include/SDL_test_images.h b/libs/SDL2/include/SDL_test_images.h
old mode 100755
new mode 100644
index 683d2f8a6..9c4dd5b82
--- a/libs/SDL2/include/SDL_test_images.h
+++ b/libs/SDL2/include/SDL_test_images.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/include/SDL_test_log.h b/libs/SDL2/include/SDL_test_log.h
old mode 100755
new mode 100644
index 9f993fbbc..ebd44fb50
--- a/libs/SDL2/include/SDL_test_log.h
+++ b/libs/SDL2/include/SDL_test_log.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/include/SDL_test_md5.h b/libs/SDL2/include/SDL_test_md5.h
old mode 100755
new mode 100644
index 67ca7d1de..0e4105768
--- a/libs/SDL2/include/SDL_test_md5.h
+++ b/libs/SDL2/include/SDL_test_md5.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/include/SDL_test_memory.h b/libs/SDL2/include/SDL_test_memory.h
old mode 100755
new mode 100644
index 43b67f521..4827ae6f2
--- a/libs/SDL2/include/SDL_test_memory.h
+++ b/libs/SDL2/include/SDL_test_memory.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/include/SDL_test_random.h b/libs/SDL2/include/SDL_test_random.h
old mode 100755
new mode 100644
index 2b01922c3..0eb414ff2
--- a/libs/SDL2/include/SDL_test_random.h
+++ b/libs/SDL2/include/SDL_test_random.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/include/SDL_thread.h b/libs/SDL2/include/SDL_thread.h
old mode 100755
new mode 100644
index d0f6575cd..554dd0b61
--- a/libs/SDL2/include/SDL_thread.h
+++ b/libs/SDL2/include/SDL_thread.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
@@ -54,12 +54,13 @@ typedef unsigned int SDL_TLSID;
 /**
  *  The SDL thread priority.
  *
- *  \note On many systems you require special privileges to set high priority.
+ *  \note On many systems you require special privileges to set high or time critical priority.
  */
 typedef enum {
     SDL_THREAD_PRIORITY_LOW,
     SDL_THREAD_PRIORITY_NORMAL,
-    SDL_THREAD_PRIORITY_HIGH
+    SDL_THREAD_PRIORITY_HIGH,
+    SDL_THREAD_PRIORITY_TIME_CRITICAL
 } SDL_ThreadPriority;
 
 /**
@@ -105,14 +106,24 @@ SDL_CreateThread(SDL_ThreadFunction fn, const char *name, void *data,
                  pfnSDL_CurrentBeginThread pfnBeginThread,
                  pfnSDL_CurrentEndThread pfnEndThread);
 
+extern DECLSPEC SDL_Thread *SDLCALL
+SDL_CreateThreadWithStackSize(int (SDLCALL * fn) (void *),
+                 const char *name, const size_t stacksize, void *data,
+                 pfnSDL_CurrentBeginThread pfnBeginThread,
+                 pfnSDL_CurrentEndThread pfnEndThread);
+
+
 /**
  *  Create a thread.
  */
 #if defined(SDL_CreateThread) && SDL_DYNAMIC_API
 #undef SDL_CreateThread
 #define SDL_CreateThread(fn, name, data) SDL_CreateThread_REAL(fn, name, data, (pfnSDL_CurrentBeginThread)_beginthreadex, (pfnSDL_CurrentEndThread)_endthreadex)
+#undef SDL_CreateThreadWithStackSize
+#define SDL_CreateThreadWithStackSize(fn, name, stacksize, data) SDL_CreateThreadWithStackSize_REAL(fn, name, stacksize, data, (pfnSDL_CurrentBeginThread)_beginthreadex, (pfnSDL_CurrentEndThread)_endthreadex)
 #else
 #define SDL_CreateThread(fn, name, data) SDL_CreateThread(fn, name, data, (pfnSDL_CurrentBeginThread)_beginthreadex, (pfnSDL_CurrentEndThread)_endthreadex)
+#define SDL_CreateThreadWithStackSize(fn, name, stacksize, data) SDL_CreateThreadWithStackSize(fn, name, data, (pfnSDL_CurrentBeginThread)_beginthreadex, (pfnSDL_CurrentEndThread)_endthreadex)
 #endif
 
 #elif defined(__OS2__)
@@ -132,15 +143,31 @@ extern DECLSPEC SDL_Thread *SDLCALL
 SDL_CreateThread(SDL_ThreadFunction fn, const char *name, void *data,
                  pfnSDL_CurrentBeginThread pfnBeginThread,
                  pfnSDL_CurrentEndThread pfnEndThread);
+extern DECLSPEC SDL_Thread *SDLCALL
+SDL_CreateThreadWithStackSize(SDL_ThreadFunction fn, const char *name, const size_t stacksize, void *data,
+                 pfnSDL_CurrentBeginThread pfnBeginThread,
+                 pfnSDL_CurrentEndThread pfnEndThread);
 #if defined(SDL_CreateThread) && SDL_DYNAMIC_API
 #undef SDL_CreateThread
 #define SDL_CreateThread(fn, name, data) SDL_CreateThread_REAL(fn, name, data, (pfnSDL_CurrentBeginThread)_beginthread, (pfnSDL_CurrentEndThread)_endthread)
+#undef SDL_CreateThreadWithStackSize
+#define SDL_CreateThreadWithStackSize(fn, name, stacksize, data) SDL_CreateThreadWithStackSize_REAL(fn, name, data, (pfnSDL_CurrentBeginThread)_beginthread, (pfnSDL_CurrentEndThread)_endthread)
 #else
 #define SDL_CreateThread(fn, name, data) SDL_CreateThread(fn, name, data, (pfnSDL_CurrentBeginThread)_beginthread, (pfnSDL_CurrentEndThread)_endthread)
+#define SDL_CreateThreadWithStackSize(fn, name, stacksize, data) SDL_CreateThreadWithStackSize(fn, name, stacksize, data, (pfnSDL_CurrentBeginThread)_beginthread, (pfnSDL_CurrentEndThread)_endthread)
 #endif
 
 #else
 
+/**
+ *  Create a thread with a default stack size.
+ *
+ *  This is equivalent to calling:
+ *  SDL_CreateThreadWithStackSize(fn, name, 0, data);
+ */
+extern DECLSPEC SDL_Thread *SDLCALL
+SDL_CreateThread(SDL_ThreadFunction fn, const char *name, void *data);
+
 /**
  *  Create a thread.
  *
@@ -158,9 +185,17 @@ SDL_CreateThread(SDL_ThreadFunction fn, const char *name, void *data,
  *   If a system imposes requirements, SDL will try to munge the string for
  *    it (truncate, etc), but the original string contents will be available
  *    from SDL_GetThreadName().
+ *
+ *   The size (in bytes) of the new stack can be specified. Zero means "use
+ *    the system default" which might be wildly different between platforms
+ *    (x86 Linux generally defaults to eight megabytes, an embedded device
+ *    might be a few kilobytes instead).
+ *
+ *   In SDL 2.1, stacksize will be folded into the original SDL_CreateThread
+ *    function.
  */
 extern DECLSPEC SDL_Thread *SDLCALL
-SDL_CreateThread(SDL_ThreadFunction fn, const char *name, void *data);
+SDL_CreateThreadWithStackSize(SDL_ThreadFunction fn, const char *name, const size_t stacksize, void *data);
 
 #endif
 
diff --git a/libs/SDL2/include/SDL_timer.h b/libs/SDL2/include/SDL_timer.h
old mode 100755
new mode 100644
index 282625d3f..5600618ff
--- a/libs/SDL2/include/SDL_timer.h
+++ b/libs/SDL2/include/SDL_timer.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/include/SDL_touch.h b/libs/SDL2/include/SDL_touch.h
old mode 100755
new mode 100644
index db9e25ebd..f4075e79a
--- a/libs/SDL2/include/SDL_touch.h
+++ b/libs/SDL2/include/SDL_touch.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/include/SDL_types.h b/libs/SDL2/include/SDL_types.h
old mode 100755
new mode 100644
index 06ee80cb3..4ac248c8c
--- a/libs/SDL2/include/SDL_types.h
+++ b/libs/SDL2/include/SDL_types.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/include/SDL_version.h b/libs/SDL2/include/SDL_version.h
old mode 100755
new mode 100644
index 5b4c40248..31443e149
--- a/libs/SDL2/include/SDL_version.h
+++ b/libs/SDL2/include/SDL_version.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
@@ -59,7 +59,7 @@ typedef struct SDL_version
 */
 #define SDL_MAJOR_VERSION   2
 #define SDL_MINOR_VERSION   0
-#define SDL_PATCHLEVEL      7
+#define SDL_PATCHLEVEL      9
 
 /**
  *  \brief Macro to determine SDL version program was compiled against.
diff --git a/libs/SDL2/include/SDL_video.h b/libs/SDL2/include/SDL_video.h
old mode 100755
new mode 100644
index 6f6cda8b1..461f13805
--- a/libs/SDL2/include/SDL_video.h
+++ b/libs/SDL2/include/SDL_video.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
@@ -110,7 +110,9 @@ typedef enum
     SDL_WINDOW_MOUSE_FOCUS = 0x00000400,        /**< window has mouse focus */
     SDL_WINDOW_FULLSCREEN_DESKTOP = ( SDL_WINDOW_FULLSCREEN | 0x00001000 ),
     SDL_WINDOW_FOREIGN = 0x00000800,            /**< window not created by SDL */
-    SDL_WINDOW_ALLOW_HIGHDPI = 0x00002000,      /**< window should be created in high-DPI mode if supported */
+    SDL_WINDOW_ALLOW_HIGHDPI = 0x00002000,      /**< window should be created in high-DPI mode if supported.
+                                                     On macOS NSHighResolutionCapable must be set true in the
+                                                     application's Info.plist for this to have any effect. */
     SDL_WINDOW_MOUSE_CAPTURE = 0x00004000,      /**< window has mouse captured (unrelated to INPUT_GRABBED) */
     SDL_WINDOW_ALWAYS_ON_TOP = 0x00008000,      /**< window should always be above others */
     SDL_WINDOW_SKIP_TASKBAR  = 0x00010000,      /**< window should not be added to the taskbar */
@@ -167,6 +169,24 @@ typedef enum
     SDL_WINDOWEVENT_HIT_TEST        /**< Window had a hit test that wasn't SDL_HITTEST_NORMAL. */
 } SDL_WindowEventID;
 
+/**
+ *  \brief Event subtype for display events
+ */
+typedef enum
+{
+    SDL_DISPLAYEVENT_NONE,          /**< Never used */
+    SDL_DISPLAYEVENT_ORIENTATION    /**< Display orientation has changed to data1 */
+} SDL_DisplayEventID;
+
+typedef enum
+{
+    SDL_ORIENTATION_UNKNOWN,            /**< The display orientation can't be determined */
+    SDL_ORIENTATION_LANDSCAPE,          /**< The display is in landscape mode, with the right side up, relative to portrait mode */
+    SDL_ORIENTATION_LANDSCAPE_FLIPPED,  /**< The display is in landscape mode, with the left side up, relative to portrait mode */
+    SDL_ORIENTATION_PORTRAIT,           /**< The display is in portrait mode */
+    SDL_ORIENTATION_PORTRAIT_FLIPPED    /**< The display is in portrait mode, upside down */
+} SDL_DisplayOrientation;
+
 /**
  *  \brief An opaque handle to an OpenGL context.
  */
@@ -314,18 +334,6 @@ extern DECLSPEC const char * SDLCALL SDL_GetDisplayName(int displayIndex);
  */
 extern DECLSPEC int SDLCALL SDL_GetDisplayBounds(int displayIndex, SDL_Rect * rect);
 
-/**
- *  \brief Get the dots/pixels-per-inch for a display
- *
- *  \note Diagonal, horizontal and vertical DPI can all be optionally
- *        returned if the parameter is non-NULL.
- *
- *  \return 0 on success, or -1 if no DPI information is available or the index is out of range.
- *
- *  \sa SDL_GetNumVideoDisplays()
- */
-extern DECLSPEC int SDLCALL SDL_GetDisplayDPI(int displayIndex, float * ddpi, float * hdpi, float * vdpi);
-
 /**
  *  \brief Get the usable desktop area represented by a display, with the
  *         primary display located at 0,0
@@ -345,6 +353,27 @@ extern DECLSPEC int SDLCALL SDL_GetDisplayDPI(int displayIndex, float * ddpi, fl
  */
 extern DECLSPEC int SDLCALL SDL_GetDisplayUsableBounds(int displayIndex, SDL_Rect * rect);
 
+/**
+ *  \brief Get the dots/pixels-per-inch for a display
+ *
+ *  \note Diagonal, horizontal and vertical DPI can all be optionally
+ *        returned if the parameter is non-NULL.
+ *
+ *  \return 0 on success, or -1 if no DPI information is available or the index is out of range.
+ *
+ *  \sa SDL_GetNumVideoDisplays()
+ */
+extern DECLSPEC int SDLCALL SDL_GetDisplayDPI(int displayIndex, float * ddpi, float * hdpi, float * vdpi);
+
+/**
+ *  \brief Get the orientation of a display
+ *
+ *  \return The orientation of the display, or SDL_ORIENTATION_UNKNOWN if it isn't available.
+ *
+ *  \sa SDL_GetNumVideoDisplays()
+ */
+extern DECLSPEC SDL_DisplayOrientation SDLCALL SDL_GetDisplayOrientation(int displayIndex);
+
 /**
  *  \brief Returns the number of available display modes.
  *
@@ -470,7 +499,7 @@ extern DECLSPEC Uint32 SDLCALL SDL_GetWindowPixelFormat(SDL_Window * window);
  *  If the window is created with any of the SDL_WINDOW_OPENGL or
  *  SDL_WINDOW_VULKAN flags, then the corresponding LoadLibrary function
  *  (SDL_GL_LoadLibrary or SDL_Vulkan_LoadLibrary) is called and the
- *  corrensponding UnloadLibrary function is called by SDL_DestroyWindow().
+ *  corresponding UnloadLibrary function is called by SDL_DestroyWindow().
  *
  *  If SDL_WINDOW_VULKAN is specified and there isn't a working Vulkan driver,
  *  SDL_CreateWindow() will fail because SDL_Vulkan_LoadLibrary() will fail.
diff --git a/libs/SDL2/include/SDL_vulkan.h b/libs/SDL2/include/SDL_vulkan.h
old mode 100755
new mode 100644
index 803b5feef..972cca4d7
--- a/libs/SDL2/include/SDL_vulkan.h
+++ b/libs/SDL2/include/SDL_vulkan.h
@@ -69,30 +69,43 @@ typedef VkSurfaceKHR SDL_vulkanSurface; /* for compatibility with Tizen */
  *  \brief Dynamically load a Vulkan loader library.
  *
  *  \param [in] path The platform dependent Vulkan loader library name, or
- *              \c NULL to open the default Vulkan loader library.
+ *              \c NULL.
  *
  *  \return \c 0 on success, or \c -1 if the library couldn't be loaded.
  *
- *  This should be done after initializing the video driver, but before
+ *  If \a path is NULL SDL will use the value of the environment variable
+ *  \c SDL_VULKAN_LIBRARY, if set, otherwise it loads the default Vulkan
+ *  loader library.
+ *
+ *  This should be called after initializing the video driver, but before
  *  creating any Vulkan windows. If no Vulkan loader library is loaded, the
  *  default library will be loaded upon creation of the first Vulkan window.
  *
- *  \note If you specify a non-NULL \a path, you should retrieve all of the
- *        Vulkan functions used in your program from the dynamic library using
+ *  \note It is fairly common for Vulkan applications to link with \a libvulkan
+ *        instead of explicitly loading it at run time. This will work with
+ *        SDL provided the application links to a dynamic library and both it
+ *        and SDL use the same search path.
+ *
+ *  \note If you specify a non-NULL \c path, an application should retrieve all
+ *        of the Vulkan functions it uses from the dynamic library using
  *        \c SDL_Vulkan_GetVkGetInstanceProcAddr() unless you can guarantee
- *        \a path points to the same vulkan loader library that you linked to.
+ *        \c path points to the same vulkan loader library the application
+ *        linked to.
  *
  *  \note On Apple devices, if \a path is NULL, SDL will attempt to find
  *        the vkGetInstanceProcAddr address within all the mach-o images of
- *        the current process. This is because the currently (v0.17.0)
- *        recommended MoltenVK (Vulkan on Metal) usage is as a static library.
- *        If it is not found then SDL will attempt to load \c libMoltenVK.dylib.
- *        Applications using the dylib alternative therefore do not need to do
- *        anything special when calling SDL.
+ *        the current process. This is because it is fairly common for Vulkan
+ *        applications to link with libvulkan (and historically MoltenVK was
+ *        provided as a static library). If it is not found then, on macOS, SDL
+ *        will attempt to load \c vulkan.framework/vulkan, \c libvulkan.1.dylib,
+ *        \c MoltenVK.framework/MoltenVK and \c libMoltenVK.dylib in that order.
+ *        On iOS SDL will attempt to load \c libMoltenVK.dylib. Applications
+ *        using a dynamic framework or .dylib must ensure it is included in its
+ *        application bundle.
  *
- *  \note On non-Apple devices, SDL requires you to either not link to the
- *        Vulkan loader or link to a dynamic library version. This limitation
- *        may be removed in a future version of SDL.
+ *  \note On non-Apple devices, application linking with a static libvulkan is
+ *        not supported. Either do not link to the Vulkan loader or link to a
+ *        dynamic library version.
  *
  *  \note This function will fail if there are no working Vulkan drivers
  *        installed.
@@ -122,11 +135,11 @@ extern DECLSPEC void SDLCALL SDL_Vulkan_UnloadLibrary(void);
  *  \brief Get the names of the Vulkan instance extensions needed to create
  *         a surface with \c SDL_Vulkan_CreateSurface().
  *
- *  \param [in]     window Window for which the required Vulkan instance
+ *  \param [in]     \c NULL or window Window for which the required Vulkan instance
  *                  extensions should be retrieved
- *  \param [in,out] count pointer to an \c unsigned related to the number of
+ *  \param [in,out] pCount pointer to an \c unsigned related to the number of
  *                  required Vulkan instance extensions
- *  \param [out]    names \c NULL or a pointer to an array to be filled with the
+ *  \param [out]    pNames \c NULL or a pointer to an array to be filled with the
  *                  required Vulkan instance extensions
  *
  *  \return \c SDL_TRUE on success, \c SDL_FALSE on error.
@@ -140,6 +153,10 @@ extern DECLSPEC void SDLCALL SDL_Vulkan_UnloadLibrary(void);
  *  is smaller than the number of required extensions, \c SDL_FALSE will be
  *  returned instead of \c SDL_TRUE, to indicate that not all the required
  *  extensions were returned.
+ * 
+ *  \note If \c window is not NULL, it will be checked against its creation
+ *        flags to ensure that the Vulkan flag is present. This parameter
+ *        will be removed in a future major release.
  *
  *  \note The returned list of extensions will contain \c VK_KHR_surface
  *        and zero or more platform specific extensions
@@ -147,12 +164,13 @@ extern DECLSPEC void SDLCALL SDL_Vulkan_UnloadLibrary(void);
  *  \note The extension names queried here must be enabled when calling
  *        VkCreateInstance, otherwise surface creation will fail.
  *
- *  \note \c window should have been created with the \c SDL_WINDOW_VULKAN flag.
+ *  \note \c window should have been created with the \c SDL_WINDOW_VULKAN flag
+ *        or be \c NULL
  *
  *  \code
  *  unsigned int count;
  *  // get count of required extensions
- *  if(!SDL_Vulkan_GetInstanceExtensions(window, &count, NULL))
+ *  if(!SDL_Vulkan_GetInstanceExtensions(NULL, &count, NULL))
  *      handle_error();
  *
  *  static const char *const additionalExtensions[] =
@@ -166,7 +184,7 @@ extern DECLSPEC void SDLCALL SDL_Vulkan_UnloadLibrary(void);
  *      handle_error();
  *
  *  // get names of required extensions
- *  if(!SDL_Vulkan_GetInstanceExtensions(window, &count, names))
+ *  if(!SDL_Vulkan_GetInstanceExtensions(NULL, &count, names))
  *      handle_error();
  *
  *  // copy additional extensions after required extensions
@@ -240,6 +258,9 @@ extern DECLSPEC SDL_bool SDLCALL SDL_Vulkan_CreateSurface(
  * platform with high-DPI support (Apple calls this "Retina"), and not disabled
  * by the \c SDL_HINT_VIDEO_HIGHDPI_DISABLED hint.
  *
+ *  \note On macOS high-DPI support must be enabled for an application by
+ *        setting NSHighResolutionCapable to true in its Info.plist.
+ *
  *  \sa SDL_GetWindowSize()
  *  \sa SDL_CreateWindow()
  */
diff --git a/libs/SDL2/include/begin_code.h b/libs/SDL2/include/begin_code.h
old mode 100755
new mode 100644
index 5372d6f04..6c2106246
--- a/libs/SDL2/include/begin_code.h
+++ b/libs/SDL2/include/begin_code.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/include/close_code.h b/libs/SDL2/include/close_code.h
old mode 100755
new mode 100644
index 2a352dbb9..b3b70a4c8
--- a/libs/SDL2/include/close_code.h
+++ b/libs/SDL2/include/close_code.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/lib/x64/SDL2.dll b/libs/SDL2/lib/x64/SDL2.dll
old mode 100755
new mode 100644
index 6776cdd89..934f8091c
Binary files a/libs/SDL2/lib/x64/SDL2.dll and b/libs/SDL2/lib/x64/SDL2.dll differ
diff --git a/libs/SDL2/lib/x64/SDL2.lib b/libs/SDL2/lib/x64/SDL2.lib
old mode 100755
new mode 100644
index 42e5ee7d0..f4941ae0e
Binary files a/libs/SDL2/lib/x64/SDL2.lib and b/libs/SDL2/lib/x64/SDL2.lib differ
diff --git a/libs/SDL2/lib/x64/SDL2main.lib b/libs/SDL2/lib/x64/SDL2main.lib
old mode 100755
new mode 100644
index 1f409a249..612994657
Binary files a/libs/SDL2/lib/x64/SDL2main.lib and b/libs/SDL2/lib/x64/SDL2main.lib differ
diff --git a/libs/SDL2/lib/x64/SDL2test.lib b/libs/SDL2/lib/x64/SDL2test.lib
old mode 100755
new mode 100644
index b54347ddc..5b0328280
Binary files a/libs/SDL2/lib/x64/SDL2test.lib and b/libs/SDL2/lib/x64/SDL2test.lib differ
diff --git a/libs/SDL2/lib/x86/SDL2.dll b/libs/SDL2/lib/x86/SDL2.dll
old mode 100755
new mode 100644
index c21f747c2..701779044
Binary files a/libs/SDL2/lib/x86/SDL2.dll and b/libs/SDL2/lib/x86/SDL2.dll differ
diff --git a/libs/SDL2/lib/x86/SDL2.lib b/libs/SDL2/lib/x86/SDL2.lib
old mode 100755
new mode 100644
index a36fab5a3..cef79017c
Binary files a/libs/SDL2/lib/x86/SDL2.lib and b/libs/SDL2/lib/x86/SDL2.lib differ
diff --git a/libs/SDL2/lib/x86/SDL2main.lib b/libs/SDL2/lib/x86/SDL2main.lib
old mode 100755
new mode 100644
index 2080d5db5..55c40c7a0
Binary files a/libs/SDL2/lib/x86/SDL2main.lib and b/libs/SDL2/lib/x86/SDL2main.lib differ
diff --git a/libs/SDL2/lib/x86/SDL2test.lib b/libs/SDL2/lib/x86/SDL2test.lib
old mode 100755
new mode 100644
index c26c50f61..d7a395ff1
Binary files a/libs/SDL2/lib/x86/SDL2test.lib and b/libs/SDL2/lib/x86/SDL2test.lib differ
diff --git a/libs/SDL2/test/CMakeLists.txt b/libs/SDL2/test/CMakeLists.txt
new file mode 100644
index 000000000..3c25c5c7c
--- /dev/null
+++ b/libs/SDL2/test/CMakeLists.txt
@@ -0,0 +1,122 @@
+cmake_minimum_required(VERSION 2.8.11)
+project(SDL2 C)
+
+# Global settings for all of the test targets
+# FIXME: is this wrong?
+remove_definitions(-DUSING_GENERATED_CONFIG_H)
+link_libraries(SDL2_test SDL2-static)
+
+# FIXME: Parent directory CMakeLists.txt only sets these for mingw/cygwin,
+# but we need them for VS as well.
+if(WINDOWS)
+    link_libraries(SDL2main)
+    add_definitions(-Dmain=SDL_main)
+endif()
+
+add_executable(checkkeys checkkeys.c)
+add_executable(loopwave loopwave.c)
+add_executable(loopwavequeue loopwavequeue.c)
+add_executable(testresample testresample.c)
+add_executable(testaudioinfo testaudioinfo.c)
+
+file(GLOB TESTAUTOMATION_SOURCE_FILES testautomation*.c)
+add_executable(testautomation ${TESTAUTOMATION_SOURCE_FILES})
+
+add_executable(testmultiaudio testmultiaudio.c)
+add_executable(testaudiohotplug testaudiohotplug.c)
+add_executable(testaudiocapture testaudiocapture.c)
+add_executable(testatomic testatomic.c)
+add_executable(testintersections testintersections.c)
+add_executable(testrelative testrelative.c)
+add_executable(testhittesting testhittesting.c)
+add_executable(testdraw2 testdraw2.c)
+add_executable(testdrawchessboard testdrawchessboard.c)
+add_executable(testdropfile testdropfile.c)
+add_executable(testerror testerror.c)
+add_executable(testfile testfile.c)
+add_executable(testgamecontroller testgamecontroller.c)
+add_executable(testgesture testgesture.c)
+add_executable(testgl2 testgl2.c)
+add_executable(testgles testgles.c)
+add_executable(testgles2 testgles2.c)
+add_executable(testhaptic testhaptic.c)
+add_executable(testhotplug testhotplug.c)
+add_executable(testrumble testrumble.c)
+add_executable(testthread testthread.c)
+add_executable(testiconv testiconv.c)
+add_executable(testime testime.c)
+add_executable(testjoystick testjoystick.c)
+add_executable(testkeys testkeys.c)
+add_executable(testloadso testloadso.c)
+add_executable(testlock testlock.c)
+
+if(APPLE)
+    add_executable(testnative testnative.c
+                              testnativecocoa.m
+                              testnativex11.c)
+elseif(WINDOWS)
+    add_executable(testnative testnative.c testnativew32.c)
+elseif(UNIX)
+    add_executable(testnative testnative.c testnativex11.c)
+endif()
+
+add_executable(testoverlay2 testoverlay2.c testyuv_cvt.c)
+add_executable(testplatform testplatform.c)
+add_executable(testpower testpower.c)
+add_executable(testfilesystem testfilesystem.c)
+add_executable(testrendertarget testrendertarget.c)
+add_executable(testscale testscale.c)
+add_executable(testsem testsem.c)
+add_executable(testshader testshader.c)
+add_executable(testshape testshape.c)
+add_executable(testsprite2 testsprite2.c)
+add_executable(testspriteminimal testspriteminimal.c)
+add_executable(teststreaming teststreaming.c)
+add_executable(testtimer testtimer.c)
+add_executable(testver testver.c)
+add_executable(testviewport testviewport.c)
+add_executable(testwm2 testwm2.c)
+add_executable(testyuv testyuv.c testyuv_cvt.c)
+add_executable(torturethread torturethread.c)
+add_executable(testrendercopyex testrendercopyex.c)
+add_executable(testmessage testmessage.c)
+add_executable(testdisplayinfo testdisplayinfo.c)
+add_executable(testqsort testqsort.c)
+add_executable(testbounds testbounds.c)
+add_executable(testcustomcursor testcustomcursor.c)
+add_executable(controllermap controllermap.c)
+add_executable(testvulkan testvulkan.c)
+
+# HACK: Dummy target to cause the resource files to be copied to the build directory.
+# Need to make it an executable so we can use the TARGET_FILE_DIR generator expression.
+# This is needed so they get copied to the correct Debug/Release subdirectory in Xcode.
+file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/resources_dummy.c "int main(int argc, const char **argv){ return 1; }\n")
+add_executable(SDL2_test_resoureces ${CMAKE_CURRENT_BINARY_DIR}/resources_dummy.c)
+
+file(GLOB RESOURCE_FILES *.bmp *.wav)
+foreach(RESOURCE_FILE ${RESOURCE_FILES})
+    add_custom_command(TARGET SDL2_test_resoureces POST_BUILD COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${RESOURCE_FILE} $<TARGET_FILE_DIR:SDL2_test_resoureces>)
+endforeach(RESOURCE_FILE)
+
+file(COPY ${RESOURCE_FILES} DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
+
+# TODO: Might be easier to make all targets depend on the resources...?
+add_dependencies(testscale SDL2_test_resoureces)
+add_dependencies(testrendercopyex SDL2_test_resoureces)
+add_dependencies(controllermap SDL2_test_resoureces)
+add_dependencies(testyuv SDL2_test_resoureces)
+add_dependencies(testgamecontroller SDL2_test_resoureces)
+add_dependencies(testshape SDL2_test_resoureces)
+add_dependencies(testshader SDL2_test_resoureces)
+add_dependencies(testnative SDL2_test_resoureces)
+add_dependencies(testspriteminimal SDL2_test_resoureces)
+add_dependencies(testautomation SDL2_test_resoureces)
+add_dependencies(testcustomcursor SDL2_test_resoureces)
+add_dependencies(testrendertarget SDL2_test_resoureces)
+add_dependencies(testsprite2 SDL2_test_resoureces)
+
+add_dependencies(loopwave SDL2_test_resoureces)
+add_dependencies(loopwavequeue SDL2_test_resoureces)
+add_dependencies(testresample SDL2_test_resoureces)
+add_dependencies(testaudiohotplug SDL2_test_resoureces)
+add_dependencies(testmultiaudio SDL2_test_resoureces)
diff --git a/libs/SDL2/test/Makefile.in b/libs/SDL2/test/Makefile.in
index 0ac70e923..9ddd6ffe7 100644
--- a/libs/SDL2/test/Makefile.in
+++ b/libs/SDL2/test/Makefile.in
@@ -9,19 +9,23 @@ LIBS	= @LIBS@
 
 TARGETS = \
 	checkkeys$(EXE) \
+	controllermap$(EXE) \
 	loopwave$(EXE) \
 	loopwavequeue$(EXE) \
 	testatomic$(EXE) \
-	testaudioinfo$(EXE) \
 	testaudiocapture$(EXE) \
+	testaudiohotplug$(EXE) \
+	testaudioinfo$(EXE) \
 	testautomation$(EXE) \
 	testbounds$(EXE) \
 	testcustomcursor$(EXE) \
+	testdisplayinfo$(EXE) \
 	testdraw2$(EXE) \
 	testdrawchessboard$(EXE) \
 	testdropfile$(EXE) \
 	testerror$(EXE) \
 	testfile$(EXE) \
+	testfilesystem$(EXE) \
 	testgamecontroller$(EXE) \
 	testgesture$(EXE) \
 	testgl2$(EXE) \
@@ -29,44 +33,42 @@ TARGETS = \
 	testgles2$(EXE) \
 	testhaptic$(EXE) \
 	testhittesting$(EXE) \
-	testrumble$(EXE) \
 	testhotplug$(EXE) \
-	testthread$(EXE) \
 	testiconv$(EXE) \
 	testime$(EXE) \
 	testintersections$(EXE) \
-	testrelative$(EXE) \
 	testjoystick$(EXE) \
 	testkeys$(EXE) \
 	testloadso$(EXE) \
 	testlock$(EXE) \
+	testmessage$(EXE) \
 	testmultiaudio$(EXE) \
-	testaudiohotplug$(EXE) \
 	testnative$(EXE) \
 	testoverlay2$(EXE) \
 	testplatform$(EXE) \
 	testpower$(EXE) \
-	testfilesystem$(EXE) \
+	testqsort$(EXE) \
+	testrelative$(EXE) \
+	testrendercopyex$(EXE) \
 	testrendertarget$(EXE) \
 	testresample$(EXE) \
+	testrumble$(EXE) \
 	testscale$(EXE) \
 	testsem$(EXE) \
+	testsensor$(EXE) \
 	testshader$(EXE) \
 	testshape$(EXE) \
 	testsprite2$(EXE) \
 	testspriteminimal$(EXE) \
 	teststreaming$(EXE) \
+	testthread$(EXE) \
 	testtimer$(EXE) \
 	testver$(EXE) \
 	testviewport$(EXE) \
-	testwm2$(EXE) \
-	torturethread$(EXE) \
-	testrendercopyex$(EXE) \
-	testmessage$(EXE) \
-	testdisplayinfo$(EXE) \
-	testqsort$(EXE) \
-	controllermap$(EXE) \
 	testvulkan$(EXE) \
+	testwm2$(EXE) \
+	testyuv$(EXE) \
+	torturethread$(EXE) \
 	
 all: Makefile $(TARGETS) copydatafiles
 
@@ -218,7 +220,7 @@ endif
 endif
 endif
 
-testoverlay2$(EXE): $(srcdir)/testoverlay2.c
+testoverlay2$(EXE): $(srcdir)/testoverlay2.c $(srcdir)/testyuv_cvt.c
 	$(CC) -o $@ $^ $(CFLAGS) $(LIBS)
 
 testplatform$(EXE): $(srcdir)/testplatform.c
@@ -239,6 +241,9 @@ testscale$(EXE): $(srcdir)/testscale.c
 testsem$(EXE): $(srcdir)/testsem.c
 	$(CC) -o $@ $^ $(CFLAGS) $(LIBS)
 
+testsensor$(EXE): $(srcdir)/testsensor.c
+	$(CC) -o $@ $^ $(CFLAGS) $(LIBS)
+
 testshader$(EXE): $(srcdir)/testshader.c
 	$(CC) -o $@ $^ $(CFLAGS) $(LIBS) @GLLIB@ @MATHLIB@
 
@@ -266,6 +271,9 @@ testviewport$(EXE): $(srcdir)/testviewport.c
 testwm2$(EXE): $(srcdir)/testwm2.c
 	$(CC) -o $@ $^ $(CFLAGS) $(LIBS)
 
+testyuv$(EXE): $(srcdir)/testyuv.c $(srcdir)/testyuv_cvt.c
+	$(CC) -o $@ $^ $(CFLAGS) $(LIBS)
+
 torturethread$(EXE): $(srcdir)/torturethread.c
 	$(CC) -o $@ $^ $(CFLAGS) $(LIBS)
 
@@ -309,7 +317,10 @@ distclean: clean
 %.wav: $(srcdir)/%.wav
 	cp $< $@
 
-copydatafiles: copybmpfiles copywavfiles
+%.dat: $(srcdir)/%.dat
+	cp $< $@
+
+copydatafiles: copybmpfiles copywavfiles copydatfiles
 .PHONY : copydatafiles
 
 copybmpfiles: $(foreach bmp,$(wildcard $(srcdir)/*.bmp),$(notdir $(bmp)))
@@ -318,3 +329,6 @@ copybmpfiles: $(foreach bmp,$(wildcard $(srcdir)/*.bmp),$(notdir $(bmp)))
 copywavfiles: $(foreach wav,$(wildcard $(srcdir)/*.wav),$(notdir $(wav)))
 .PHONY : copywavfiles
 
+copydatfiles: $(foreach dat,$(wildcard $(srcdir)/*.dat),$(notdir $(dat)))
+.PHONY : copydatfiles
+
diff --git a/libs/SDL2/test/checkkeys.c b/libs/SDL2/test/checkkeys.c
index 066c786d4..4452acaba 100644
--- a/libs/SDL2/test/checkkeys.c
+++ b/libs/SDL2/test/checkkeys.c
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/test/controllermap.c b/libs/SDL2/test/controllermap.c
index c4fe5929c..2ca53518a 100644
--- a/libs/SDL2/test/controllermap.c
+++ b/libs/SDL2/test/controllermap.c
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/test/loopwave.c b/libs/SDL2/test/loopwave.c
index 63e199611..88d8fc871 100644
--- a/libs/SDL2/test/loopwave.c
+++ b/libs/SDL2/test/loopwave.c
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/test/loopwavequeue.c b/libs/SDL2/test/loopwavequeue.c
index 3dc7792f6..3f0a69e15 100644
--- a/libs/SDL2/test/loopwavequeue.c
+++ b/libs/SDL2/test/loopwavequeue.c
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/test/testatomic.c b/libs/SDL2/test/testatomic.c
index f8dca9178..6af9d4bf6 100644
--- a/libs/SDL2/test/testatomic.c
+++ b/libs/SDL2/test/testatomic.c
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/test/testaudiocapture.c b/libs/SDL2/test/testaudiocapture.c
index 3b7ea0b79..a418d123c 100644
--- a/libs/SDL2/test/testaudiocapture.c
+++ b/libs/SDL2/test/testaudiocapture.c
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/test/testaudiohotplug.c b/libs/SDL2/test/testaudiohotplug.c
index a72f91745..374cbb27b 100644
--- a/libs/SDL2/test/testaudiohotplug.c
+++ b/libs/SDL2/test/testaudiohotplug.c
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/test/testaudioinfo.c b/libs/SDL2/test/testaudioinfo.c
index c70b86b5e..adecce9b7 100644
--- a/libs/SDL2/test/testaudioinfo.c
+++ b/libs/SDL2/test/testaudioinfo.c
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/test/testautomation.c b/libs/SDL2/test/testautomation.c
index 9fd22be07..bb799ea43 100644
--- a/libs/SDL2/test/testautomation.c
+++ b/libs/SDL2/test/testautomation.c
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/test/testbounds.c b/libs/SDL2/test/testbounds.c
index bc46cb823..764809446 100644
--- a/libs/SDL2/test/testbounds.c
+++ b/libs/SDL2/test/testbounds.c
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/test/testcustomcursor.c b/libs/SDL2/test/testcustomcursor.c
index 59c6409db..469449818 100644
--- a/libs/SDL2/test/testcustomcursor.c
+++ b/libs/SDL2/test/testcustomcursor.c
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
@@ -73,6 +73,24 @@ init_color_cursor(const char *file)
     SDL_Cursor *cursor = NULL;
     SDL_Surface *surface = SDL_LoadBMP(file);
     if (surface) {
+        if (surface->format->palette) {
+            SDL_SetColorKey(surface, 1, *(Uint8 *) surface->pixels);
+        } else {
+            switch (surface->format->BitsPerPixel) {
+            case 15:
+                SDL_SetColorKey(surface, 1, (*(Uint16 *)surface->pixels) & 0x00007FFF);
+                break;
+            case 16:
+                SDL_SetColorKey(surface, 1, *(Uint16 *)surface->pixels);
+                break;
+            case 24:
+                SDL_SetColorKey(surface, 1, (*(Uint32 *)surface->pixels) & 0x00FFFFFF);
+                break;
+            case 32:
+                SDL_SetColorKey(surface, 1, *(Uint32 *)surface->pixels);
+                break;
+            }
+        }
         cursor = SDL_CreateColorCursor(surface, 0, 0);
         SDL_FreeSurface(surface);
     }
@@ -116,7 +134,9 @@ init_system_cursor(const char *image[])
 
 static SDLTest_CommonState *state;
 int done;
-SDL_Cursor *cursor = NULL;
+static SDL_Cursor *cursors[1+SDL_NUM_SYSTEM_CURSORS];
+static int current_cursor;
+static int show_cursor;
 
 /* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */
 static void
@@ -134,6 +154,18 @@ loop()
     /* Check for events */
     while (SDL_PollEvent(&event)) {
         SDLTest_CommonEvent(state, &event, &done);
+        if (event.type == SDL_MOUSEBUTTONDOWN) {
+            if (event.button.button == SDL_BUTTON_LEFT) {
+                ++current_cursor;
+                if (current_cursor == SDL_arraysize(cursors)) {
+                    current_cursor = 0;
+                }
+                SDL_SetCursor(cursors[current_cursor]);
+            } else {
+                show_cursor = !show_cursor;
+                SDL_ShowCursor(show_cursor);
+            }
+        }
     }
     
     for (i = 0; i < state->num_windows; ++i) {
@@ -188,15 +220,22 @@ main(int argc, char *argv[])
     }
 
     if (color_cursor) {
-        cursor = init_color_cursor(color_cursor);
+        cursors[0] = init_color_cursor(color_cursor);
     } else {
-        cursor = init_system_cursor(arrow);
+        cursors[0] = init_system_cursor(arrow);
     }
-    if (!cursor) {
+    if (!cursors[0]) {
         SDL_Log("Error, couldn't create cursor\n");
         quit(2);
     }
-    SDL_SetCursor(cursor);
+    for (i = 0; i < SDL_NUM_SYSTEM_CURSORS; ++i) {
+        cursors[1+i] = SDL_CreateSystemCursor((SDL_SystemCursor)i);
+        if (!cursors[1+i]) {
+            SDL_Log("Error, couldn't create system cursor %d\n", i);
+            quit(2);
+        }
+    }
+    SDL_SetCursor(cursors[0]);
 
     /* Main render loop */
     done = 0;
@@ -208,9 +247,13 @@ main(int argc, char *argv[])
     }
 #endif
 
-    SDL_FreeCursor(cursor);
+    for (i = 0; i < SDL_arraysize(cursors); ++i) {
+        SDL_FreeCursor(cursors[i]);
+    }
     quit(0);
 
     /* keep the compiler happy ... */
     return(0);
 }
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/libs/SDL2/test/testdisplayinfo.c b/libs/SDL2/test/testdisplayinfo.c
index 51c19b010..0cc5fbdd7 100644
--- a/libs/SDL2/test/testdisplayinfo.c
+++ b/libs/SDL2/test/testdisplayinfo.c
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/test/testdraw2.c b/libs/SDL2/test/testdraw2.c
index 1472a3863..91ee7eea2 100644
--- a/libs/SDL2/test/testdraw2.c
+++ b/libs/SDL2/test/testdraw2.c
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/test/testdrawchessboard.c b/libs/SDL2/test/testdrawchessboard.c
index cef8621fc..3dd78e1ac 100644
--- a/libs/SDL2/test/testdrawchessboard.c
+++ b/libs/SDL2/test/testdrawchessboard.c
@@ -1,5 +1,5 @@
 /*
-   Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+   Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
    This software is provided 'as-is', without any express or implied
    warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/test/testdropfile.c b/libs/SDL2/test/testdropfile.c
index b3cb17d9b..1c2a3f0e6 100644
--- a/libs/SDL2/test/testdropfile.c
+++ b/libs/SDL2/test/testdropfile.c
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/test/testerror.c b/libs/SDL2/test/testerror.c
index 468f8a7fb..87fcab21b 100644
--- a/libs/SDL2/test/testerror.c
+++ b/libs/SDL2/test/testerror.c
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/test/testfile.c b/libs/SDL2/test/testfile.c
index 23215ea27..e563d77be 100644
--- a/libs/SDL2/test/testfile.c
+++ b/libs/SDL2/test/testfile.c
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/test/testfilesystem.c b/libs/SDL2/test/testfilesystem.c
index e8a3b3c36..ada4e864c 100644
--- a/libs/SDL2/test/testfilesystem.c
+++ b/libs/SDL2/test/testfilesystem.c
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/test/testgamecontroller.c b/libs/SDL2/test/testgamecontroller.c
index f586bfe22..c8616d7cd 100644
--- a/libs/SDL2/test/testgamecontroller.c
+++ b/libs/SDL2/test/testgamecontroller.c
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
@@ -114,6 +114,11 @@ loop(void *arg)
         case SDL_CONTROLLERBUTTONDOWN:
         case SDL_CONTROLLERBUTTONUP:
             SDL_Log("Controller button %s %s\n", SDL_GameControllerGetStringForButton((SDL_GameControllerButton)event.cbutton.button), event.cbutton.state ? "pressed" : "released");
+            /* First button triggers a 0.5 second full strength rumble */
+            if (event.type == SDL_CONTROLLERBUTTONDOWN &&
+                event.cbutton.button == SDL_CONTROLLER_BUTTON_A) {
+                SDL_GameControllerRumble(gamecontroller, 0xFFFF, 0xFFFF, 500);
+            }
             break;
         case SDL_KEYDOWN:
             if (event.key.keysym.sym != SDLK_ESCAPE) {
diff --git a/libs/SDL2/test/testgesture.c b/libs/SDL2/test/testgesture.c
index f7db94fbe..f4b254a65 100644
--- a/libs/SDL2/test/testgesture.c
+++ b/libs/SDL2/test/testgesture.c
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/test/testgl2.c b/libs/SDL2/test/testgl2.c
index 114c14105..dd01d0e29 100644
--- a/libs/SDL2/test/testgl2.c
+++ b/libs/SDL2/test/testgl2.c
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/test/testgles.c b/libs/SDL2/test/testgles.c
index cb1da1407..96895da0f 100644
--- a/libs/SDL2/test/testgles.c
+++ b/libs/SDL2/test/testgles.c
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/test/testgles2.c b/libs/SDL2/test/testgles2.c
index 282e0b611..c4578a5cc 100644
--- a/libs/SDL2/test/testgles2.c
+++ b/libs/SDL2/test/testgles2.c
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/test/testhotplug.c b/libs/SDL2/test/testhotplug.c
index 765ce2639..72c90e8d9 100644
--- a/libs/SDL2/test/testhotplug.c
+++ b/libs/SDL2/test/testhotplug.c
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/test/testiconv.c b/libs/SDL2/test/testiconv.c
index ff3b28c93..47e8c377a 100644
--- a/libs/SDL2/test/testiconv.c
+++ b/libs/SDL2/test/testiconv.c
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/test/testime.c b/libs/SDL2/test/testime.c
index 32f80cd6b..77bb86962 100644
--- a/libs/SDL2/test/testime.c
+++ b/libs/SDL2/test/testime.c
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/test/testintersections.c b/libs/SDL2/test/testintersections.c
index dcf1bc172..619df0640 100644
--- a/libs/SDL2/test/testintersections.c
+++ b/libs/SDL2/test/testintersections.c
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/test/testjoystick.c b/libs/SDL2/test/testjoystick.c
index 50e5cc96e..bca749244 100644
--- a/libs/SDL2/test/testjoystick.c
+++ b/libs/SDL2/test/testjoystick.c
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
@@ -90,6 +90,10 @@ loop(void *arg)
             case SDL_JOYBUTTONDOWN:
                 SDL_Log("Joystick %d button %d down\n",
                        event.jbutton.which, event.jbutton.button);
+                /* First button triggers a 0.5 second full strength rumble */
+                if (event.jbutton.button == 0) {
+                    SDL_JoystickRumble(joystick, 0xFFFF, 0xFFFF, 500);
+                }
                 break;
             case SDL_JOYBUTTONUP:
                 SDL_Log("Joystick %d button %d up\n",
diff --git a/libs/SDL2/test/testkeys.c b/libs/SDL2/test/testkeys.c
index 33649d229..73f880e13 100644
--- a/libs/SDL2/test/testkeys.c
+++ b/libs/SDL2/test/testkeys.c
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/test/testloadso.c b/libs/SDL2/test/testloadso.c
index 2dce11d6a..c6fa33106 100644
--- a/libs/SDL2/test/testloadso.c
+++ b/libs/SDL2/test/testloadso.c
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/test/testlock.c b/libs/SDL2/test/testlock.c
index e79fcda96..8299a9a67 100644
--- a/libs/SDL2/test/testlock.c
+++ b/libs/SDL2/test/testlock.c
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/test/testmessage.c b/libs/SDL2/test/testmessage.c
index 07d0b0309..8488d8eda 100644
--- a/libs/SDL2/test/testmessage.c
+++ b/libs/SDL2/test/testmessage.c
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/test/testmultiaudio.c b/libs/SDL2/test/testmultiaudio.c
index 4bae3859c..52a4cac7d 100644
--- a/libs/SDL2/test/testmultiaudio.c
+++ b/libs/SDL2/test/testmultiaudio.c
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/test/testnative.c b/libs/SDL2/test/testnative.c
index 83bc495df..674d9d3b4 100644
--- a/libs/SDL2/test/testnative.c
+++ b/libs/SDL2/test/testnative.c
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/test/testnative.h b/libs/SDL2/test/testnative.h
index b2ee5fa44..29d85fb32 100644
--- a/libs/SDL2/test/testnative.h
+++ b/libs/SDL2/test/testnative.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/test/testnativew32.c b/libs/SDL2/test/testnativew32.c
index 7a27b127a..7e96bc697 100644
--- a/libs/SDL2/test/testnativew32.c
+++ b/libs/SDL2/test/testnativew32.c
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/test/testnativex11.c b/libs/SDL2/test/testnativex11.c
index 8908d22ff..386c25e9e 100644
--- a/libs/SDL2/test/testnativex11.c
+++ b/libs/SDL2/test/testnativex11.c
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/test/testoverlay2.c b/libs/SDL2/test/testoverlay2.c
index 2145c4d36..daf07d3e9 100644
--- a/libs/SDL2/test/testoverlay2.c
+++ b/libs/SDL2/test/testoverlay2.c
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
@@ -16,16 +16,14 @@
  *                                                                              *
  ********************************************************************************/
 
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-
 #ifdef __EMSCRIPTEN__
 #include <emscripten/emscripten.h>
 #endif
 
 #include "SDL.h"
 
+#include "testyuv_cvt.h"
+
 #define MOOSEPIC_W 64
 #define MOOSEPIC_H 88
 
@@ -149,7 +147,6 @@ SDL_Renderer *renderer;
 int paused = 0;
 int i;
 SDL_bool done = SDL_FALSE;
-Uint32 pixel_format = SDL_PIXELFORMAT_YV12;
 static int fpsdelay;
 
 /* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */
@@ -160,91 +157,6 @@ quit(int rc)
     exit(rc);
 }
 
-/* All RGB2YUV conversion code and some other parts of code has been taken from testoverlay.c */
-
-/* NOTE: These RGB conversion functions are not intended for speed,
-         only as examples.
-*/
-
-void
-RGBtoYUV(Uint8 * rgb, int *yuv, int monochrome, int luminance)
-{
-    if (monochrome) {
-#if 1                           /* these are the two formulas that I found on the FourCC site... */
-        yuv[0] = (int)(0.299 * rgb[0] + 0.587 * rgb[1] + 0.114 * rgb[2]);
-        yuv[1] = 128;
-        yuv[2] = 128;
-#else
-        yuv[0] = (int)(0.257 * rgb[0]) + (0.504 * rgb[1]) + (0.098 * rgb[2]) + 16;
-        yuv[1] = 128;
-        yuv[2] = 128;
-#endif
-    } else {
-#if 1                           /* these are the two formulas that I found on the FourCC site... */
-        yuv[0] = (int)(0.299 * rgb[0] + 0.587 * rgb[1] + 0.114 * rgb[2]);
-        yuv[1] = (int)((rgb[2] - yuv[0]) * 0.565 + 128);
-        yuv[2] = (int)((rgb[0] - yuv[0]) * 0.713 + 128);
-#else
-        yuv[0] = (0.257 * rgb[0]) + (0.504 * rgb[1]) + (0.098 * rgb[2]) + 16;
-        yuv[1] = 128 - (0.148 * rgb[0]) - (0.291 * rgb[1]) + (0.439 * rgb[2]);
-        yuv[2] = 128 + (0.439 * rgb[0]) - (0.368 * rgb[1]) - (0.071 * rgb[2]);
-#endif
-    }
-
-    if (luminance != 100) {
-        yuv[0] = yuv[0] * luminance / 100;
-        if (yuv[0] > 255)
-            yuv[0] = 255;
-    }
-}
-
-void
-ConvertRGBtoYV12(Uint8 *rgb, Uint8 *out, int w, int h,
-                 int monochrome, int luminance)
-{
-    int x, y;
-    int yuv[3];
-    Uint8 *op[3];
-
-    op[0] = out;
-    op[1] = op[0] + w*h;
-    op[2] = op[1] + w*h/4;
-    for (y = 0; y < h; ++y) {
-        for (x = 0; x < w; ++x) {
-            RGBtoYUV(rgb, yuv, monochrome, luminance);
-            *(op[0]++) = yuv[0];
-            if (x % 2 == 0 && y % 2 == 0) {
-                *(op[1]++) = yuv[2];
-                *(op[2]++) = yuv[1];
-            }
-            rgb += 3;
-        }
-    }
-}
-
-void
-ConvertRGBtoNV12(Uint8 *rgb, Uint8 *out, int w, int h,
-                 int monochrome, int luminance)
-{
-    int x, y;
-    int yuv[3];
-    Uint8 *op[2];
-
-    op[0] = out;
-    op[1] = op[0] + w*h;
-    for (y = 0; y < h; ++y) {
-        for (x = 0; x < w; ++x) {
-            RGBtoYUV(rgb, yuv, monochrome, luminance);
-            *(op[0]++) = yuv[0];
-            if (x % 2 == 0 && y % 2 == 0) {
-                *(op[1]++) = yuv[1];
-                *(op[1]++) = yuv[2];
-            }
-            rgb += 3;
-        }
-    }
-}
-
 static void
 PrintUsage(char *argv0)
 {
@@ -307,7 +219,7 @@ loop()
     if (!paused) {
         i = (i + 1) % MOOSEFRAMES_COUNT;
 
-        SDL_UpdateTexture(MooseTexture, NULL, MooseFrame[i], MOOSEPIC_W*SDL_BYTESPERPIXEL(pixel_format));
+        SDL_UpdateTexture(MooseTexture, NULL, MooseFrame[i], MOOSEPIC_W);
     }
     SDL_RenderClear(renderer);
     SDL_RenderCopy(renderer, MooseTexture, NULL, &displayrect);
@@ -329,11 +241,6 @@ main(int argc, char **argv)
     int j;
     int fps = 12;
     int nodelay = 0;
-#ifdef TEST_NV12
-    Uint32 pixel_format = SDL_PIXELFORMAT_NV12;
-#else
-    Uint32 pixel_format = SDL_PIXELFORMAT_YV12;
-#endif
     int scale = 5;
 
     /* Enable standard application logging */
@@ -347,7 +254,7 @@ main(int argc, char **argv)
     while (argc > 1) {
         if (strcmp(argv[1], "-fps") == 0) {
             if (argv[2]) {
-                fps = atoi(argv[2]);
+                fps = SDL_atoi(argv[2]);
                 if (fps == 0) {
                     SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
                             "The -fps option requires an argument [from 1 to 1000], default is 12.\n");
@@ -371,7 +278,7 @@ main(int argc, char **argv)
             argc -= 1;
         } else if (strcmp(argv[1], "-scale") == 0) {
             if (argv[2]) {
-                scale = atoi(argv[2]);
+                scale = SDL_atoi(argv[2]);
                 if (scale == 0) {
                     SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
                             "The -scale option requires an argument [from 1 to 50], default is 5.\n");
@@ -439,7 +346,7 @@ main(int argc, char **argv)
         quit(4);
     }
 
-    MooseTexture = SDL_CreateTexture(renderer, pixel_format, SDL_TEXTUREACCESS_STREAMING, MOOSEPIC_W, MOOSEPIC_H);
+    MooseTexture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_YV12, SDL_TEXTUREACCESS_STREAMING, MOOSEPIC_W, MOOSEPIC_H);
     if (!MooseTexture) {
         SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't set create texture: %s\n", SDL_GetError());
         free(RawMooseData);
@@ -461,17 +368,9 @@ main(int argc, char **argv)
             rgb[2] = MooseColors[frame[j]].b;
             rgb += 3;
         }
-        switch (pixel_format) {
-        case SDL_PIXELFORMAT_YV12:
-            ConvertRGBtoYV12(MooseFrameRGB, MooseFrame[i], MOOSEPIC_W, MOOSEPIC_H, 0, 100);
-            break;
-        case SDL_PIXELFORMAT_NV12:
-            ConvertRGBtoNV12(MooseFrameRGB, MooseFrame[i], MOOSEPIC_W, MOOSEPIC_H, 0, 100);
-            break;
-        default:
-            SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Unsupported pixel format\n");
-            break;
-        }
+        ConvertRGBtoYUV(SDL_PIXELFORMAT_YV12, MooseFrameRGB, MOOSEPIC_W*3, MooseFrame[i], MOOSEPIC_W, MOOSEPIC_H,
+            SDL_GetYUVConversionModeForResolution(MOOSEPIC_W, MOOSEPIC_H),
+            0, 100);
     }
 
     free(RawMooseData);
diff --git a/libs/SDL2/test/testplatform.c b/libs/SDL2/test/testplatform.c
index 0cba8fe76..1c1d2dcd8 100644
--- a/libs/SDL2/test/testplatform.c
+++ b/libs/SDL2/test/testplatform.c
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
@@ -380,6 +380,7 @@ TestCPUInfo(SDL_bool verbose)
         SDL_Log("SSE4.2 %s\n", SDL_HasSSE42()? "detected" : "not detected");
         SDL_Log("AVX %s\n", SDL_HasAVX()? "detected" : "not detected");
         SDL_Log("AVX2 %s\n", SDL_HasAVX2()? "detected" : "not detected");
+        SDL_Log("AVX-512F %s\n", SDL_HasAVX512F()? "detected" : "not detected");
         SDL_Log("NEON %s\n", SDL_HasNEON()? "detected" : "not detected");
         SDL_Log("System RAM %d MB\n", SDL_GetSystemRAM());
     }
diff --git a/libs/SDL2/test/testpower.c b/libs/SDL2/test/testpower.c
index 48d64f094..adb58832a 100644
--- a/libs/SDL2/test/testpower.c
+++ b/libs/SDL2/test/testpower.c
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/test/testqsort.c b/libs/SDL2/test/testqsort.c
index 886753936..e83b0731e 100644
--- a/libs/SDL2/test/testqsort.c
+++ b/libs/SDL2/test/testqsort.c
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/test/testrelative.c b/libs/SDL2/test/testrelative.c
index 5d2ab5d93..816329ff5 100644
--- a/libs/SDL2/test/testrelative.c
+++ b/libs/SDL2/test/testrelative.c
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/test/testrendercopyex.c b/libs/SDL2/test/testrendercopyex.c
index 72a54e649..209a35157 100644
--- a/libs/SDL2/test/testrendercopyex.c
+++ b/libs/SDL2/test/testrendercopyex.c
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/test/testrendertarget.c b/libs/SDL2/test/testrendertarget.c
index ec21f2e43..7d24d8aea 100644
--- a/libs/SDL2/test/testrendertarget.c
+++ b/libs/SDL2/test/testrendertarget.c
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/test/testresample.c b/libs/SDL2/test/testresample.c
index a54a47dcb..4234d9e45 100644
--- a/libs/SDL2/test/testresample.c
+++ b/libs/SDL2/test/testresample.c
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
@@ -93,7 +93,7 @@ main(int argc, char **argv)
     SDL_WriteLE32(io, 0x45564157);      /* WAVE */
     SDL_WriteLE32(io, 0x20746D66);      /* fmt */
     SDL_WriteLE32(io, 16);      /* chunk size */
-    SDL_WriteLE16(io, 1);       /* uncompressed */
+    SDL_WriteLE16(io, SDL_AUDIO_ISFLOAT(spec.format) ? 3 : 1);       /* uncompressed */
     SDL_WriteLE16(io, cvtchans);   /* channels */
     SDL_WriteLE32(io, cvtfreq); /* sample rate */
     SDL_WriteLE32(io, avgbytes);        /* average bytes per second */
diff --git a/libs/SDL2/test/testrumble.c b/libs/SDL2/test/testrumble.c
index a22c52ec2..908a6aafb 100644
--- a/libs/SDL2/test/testrumble.c
+++ b/libs/SDL2/test/testrumble.c
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/test/testscale.c b/libs/SDL2/test/testscale.c
index 34451d6fc..e1b46fcc8 100644
--- a/libs/SDL2/test/testscale.c
+++ b/libs/SDL2/test/testscale.c
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/test/testsem.c b/libs/SDL2/test/testsem.c
index 13438b1b6..884763e6a 100644
--- a/libs/SDL2/test/testsem.c
+++ b/libs/SDL2/test/testsem.c
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/test/testsensor.c b/libs/SDL2/test/testsensor.c
new file mode 100644
index 000000000..00bfd137d
--- /dev/null
+++ b/libs/SDL2/test/testsensor.c
@@ -0,0 +1,117 @@
+/*
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+  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.
+*/
+
+/* Simple test of the SDL sensor code */
+
+#include "SDL.h"
+
+static const char *GetSensorTypeString(SDL_SensorType type)
+{
+    static char unknown_type[64];
+
+    switch (type)
+    {
+    case SDL_SENSOR_INVALID:
+        return "SDL_SENSOR_INVALID";
+    case SDL_SENSOR_UNKNOWN:
+        return "SDL_SENSOR_UNKNOWN";
+    case SDL_SENSOR_ACCEL:
+        return "SDL_SENSOR_ACCEL";
+    case SDL_SENSOR_GYRO:
+        return "SDL_SENSOR_GYRO";
+    default:
+        SDL_snprintf(unknown_type, sizeof(unknown_type), "UNKNOWN (%d)", type);
+        return unknown_type;
+    }
+}
+
+static void HandleSensorEvent(SDL_SensorEvent *event)
+{
+    SDL_Sensor *sensor = SDL_SensorFromInstanceID(event->which);
+    if (!sensor) {
+        SDL_Log("Couldn't get sensor for sensor event\n");
+        return;
+    }
+
+    switch (SDL_SensorGetType(sensor)) {
+    case SDL_SENSOR_ACCEL:
+        SDL_Log("Accelerometer update: %.2f, %.2f, %.2f\n", event->data[0], event->data[1], event->data[2]);
+        break;
+    case SDL_SENSOR_GYRO:
+        SDL_Log("Gyro update: %.2f, %.2f, %.2f\n", event->data[0], event->data[1], event->data[2]);
+        break;
+    default:
+        SDL_Log("Sensor update for sensor type %s\n", GetSensorTypeString(SDL_SensorGetType(sensor)));
+        break;
+    }
+}
+
+int
+main(int argc, char **argv)
+{
+    int i;
+    int num_sensors, num_opened;
+
+    /* Load the SDL library */
+    if (SDL_Init(SDL_INIT_SENSOR) < 0) {
+        SDL_Log("Couldn't initialize SDL: %s\n", SDL_GetError());
+        return (1);
+    }
+
+    num_sensors = SDL_NumSensors();
+    num_opened = 0;
+
+    SDL_Log("There are %d sensors available\n", num_sensors);
+    for (i = 0; i < num_sensors; ++i) {
+        SDL_Log("Sensor %d: %s, type %s, platform type %d\n",
+            SDL_SensorGetDeviceInstanceID(i),
+            SDL_SensorGetDeviceName(i),
+            GetSensorTypeString(SDL_SensorGetDeviceType(i)),
+            SDL_SensorGetDeviceNonPortableType(i));
+
+        if (SDL_SensorGetDeviceType(i) != SDL_SENSOR_UNKNOWN) {
+            SDL_Sensor *sensor = SDL_SensorOpen(i);
+            if (sensor == NULL) {
+                SDL_Log("Couldn't open sensor %d: %s\n", SDL_SensorGetDeviceInstanceID(i), SDL_GetError());
+            } else {
+                ++num_opened;
+            }
+        }
+    }
+    SDL_Log("Opened %d sensors\n", num_opened);
+
+    if (num_opened > 0) {
+        SDL_bool done = SDL_FALSE;
+        SDL_Event event;
+
+        SDL_CreateWindow("Sensor Test", 0, 0, 0, 0, SDL_WINDOW_FULLSCREEN_DESKTOP);
+        while (!done) {
+            while (SDL_PollEvent(&event) > 0) {
+                switch (event.type) {
+                case SDL_SENSORUPDATE:
+                    HandleSensorEvent(&event.sensor);
+                    break;
+                case SDL_MOUSEBUTTONUP:
+                case SDL_KEYUP:
+                case SDL_QUIT:
+                    done = SDL_TRUE;
+                    break;
+                default:
+                    break;
+                }
+            }
+        }
+    }
+
+    SDL_Quit();
+    return (0);
+}
diff --git a/libs/SDL2/test/testshader.c b/libs/SDL2/test/testshader.c
index 1700da1cc..ee0ccdad2 100644
--- a/libs/SDL2/test/testshader.c
+++ b/libs/SDL2/test/testshader.c
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/test/testshape.c b/libs/SDL2/test/testshape.c
index d54cc2265..7e451e667 100644
--- a/libs/SDL2/test/testshape.c
+++ b/libs/SDL2/test/testshape.c
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/test/testsprite2.c b/libs/SDL2/test/testsprite2.c
index 14258f74c..b0348f85d 100644
--- a/libs/SDL2/test/testsprite2.c
+++ b/libs/SDL2/test/testsprite2.c
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/test/testspriteminimal.c b/libs/SDL2/test/testspriteminimal.c
index 478c58496..92560002a 100644
--- a/libs/SDL2/test/testspriteminimal.c
+++ b/libs/SDL2/test/testspriteminimal.c
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/test/teststreaming.c b/libs/SDL2/test/teststreaming.c
index 76a9fed18..7ec689106 100644
--- a/libs/SDL2/test/teststreaming.c
+++ b/libs/SDL2/test/teststreaming.c
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/test/testthread.c b/libs/SDL2/test/testthread.c
index 6557b2fc7..4555a1e94 100644
--- a/libs/SDL2/test/testthread.c
+++ b/libs/SDL2/test/testthread.c
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
@@ -20,6 +20,7 @@
 
 static SDL_TLSID tls;
 static int alive = 0;
+static int testprio = 0;
 
 /* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */
 static void
@@ -29,14 +30,37 @@ quit(int rc)
     exit(rc);
 }
 
+static const char *
+getprioritystr(SDL_ThreadPriority priority)
+{
+    switch(priority)
+    {
+    case SDL_THREAD_PRIORITY_LOW: return "SDL_THREAD_PRIORITY_LOW";
+    case SDL_THREAD_PRIORITY_NORMAL: return "SDL_THREAD_PRIORITY_NORMAL";
+    case SDL_THREAD_PRIORITY_HIGH: return "SDL_THREAD_PRIORITY_HIGH";
+    case SDL_THREAD_PRIORITY_TIME_CRITICAL: return "SDL_THREAD_PRIORITY_TIME_CRITICAL";
+    }
+
+    return "???";
+}
+
 int SDLCALL
 ThreadFunc(void *data)
 {
+    SDL_ThreadPriority prio = SDL_THREAD_PRIORITY_NORMAL;
+
     SDL_TLSSet(tls, "baby thread", NULL);
     SDL_Log("Started thread %s: My thread id is %lu, thread data = %s\n",
            (char *) data, SDL_ThreadID(), (const char *)SDL_TLSGet(tls));
     while (alive) {
         SDL_Log("Thread '%s' is alive!\n", (char *) data);
+
+        if (testprio) {
+            SDL_Log("SDL_SetThreadPriority(%s):%d\n", getprioritystr(prio), SDL_SetThreadPriority(prio));
+            if (++prio > SDL_THREAD_PRIORITY_TIME_CRITICAL)
+                prio = SDL_THREAD_PRIORITY_LOW;
+        }
+
         SDL_Delay(1 * 1000);
     }
     SDL_Log("Thread '%s' exiting!\n", (char *) data);
@@ -55,6 +79,7 @@ killed(int sig)
 int
 main(int argc, char *argv[])
 {
+    int arg = 1;
     SDL_Thread *thread;
 
     /* Enable standard application logging */
@@ -66,6 +91,13 @@ main(int argc, char *argv[])
         return (1);
     }
 
+    while (argv[arg] && *argv[arg] == '-') {
+        if (SDL_strcmp(argv[arg], "--prio") == 0) {
+            testprio = 1;
+        }
+        ++arg;
+    }
+
     tls = SDL_TLSCreate();
     SDL_assert(tls);
     SDL_TLSSet(tls, "main thread", NULL);
diff --git a/libs/SDL2/test/testtimer.c b/libs/SDL2/test/testtimer.c
index 261497be7..34764c1c9 100644
--- a/libs/SDL2/test/testtimer.c
+++ b/libs/SDL2/test/testtimer.c
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/test/testver.c b/libs/SDL2/test/testver.c
index 04a7a9010..1ae008345 100644
--- a/libs/SDL2/test/testver.c
+++ b/libs/SDL2/test/testver.c
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/test/testviewport.c b/libs/SDL2/test/testviewport.c
index f9d0bd5aa..4b8d20e76 100644
--- a/libs/SDL2/test/testviewport.c
+++ b/libs/SDL2/test/testviewport.c
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/test/testvulkan.c b/libs/SDL2/test/testvulkan.c
index 95cbec803..cd682af1f 100644
--- a/libs/SDL2/test/testvulkan.c
+++ b/libs/SDL2/test/testvulkan.c
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 1997-2016 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
@@ -255,7 +255,7 @@ static void createInstance(void)
     appInfo.apiVersion = VK_API_VERSION_1_0;
     instanceCreateInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
     instanceCreateInfo.pApplicationInfo = &appInfo;
-    if(!SDL_Vulkan_GetInstanceExtensions(state->windows[0], &extensionCount, NULL))
+    if(!SDL_Vulkan_GetInstanceExtensions(NULL, &extensionCount, NULL))
     {
         SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
                      "SDL_Vulkan_GetInstanceExtensions(): %s\n",
@@ -268,7 +268,7 @@ static void createInstance(void)
         SDL_OutOfMemory();
         quit(2);
     }
-    if(!SDL_Vulkan_GetInstanceExtensions(state->windows[0], &extensionCount, extensions))
+    if(!SDL_Vulkan_GetInstanceExtensions(NULL, &extensionCount, extensions))
     {
         SDL_free((void*)extensions);
         SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
diff --git a/libs/SDL2/test/testwm2.c b/libs/SDL2/test/testwm2.c
index ab3eea2f5..5da387309 100644
--- a/libs/SDL2/test/testwm2.c
+++ b/libs/SDL2/test/testwm2.c
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
@@ -146,6 +146,9 @@ main(int argc, char *argv[])
         quit(2);
     }
 
+    SDL_EventState(SDL_DROPFILE, SDL_ENABLE);
+    SDL_EventState(SDL_DROPTEXT, SDL_ENABLE);
+
     for (i = 0; i < state->num_windows; ++i) {
         SDL_Renderer *renderer = state->renderers[i];
         SDL_SetRenderDrawColor(renderer, 0xA0, 0xA0, 0xA0, 0xFF);
diff --git a/libs/SDL2/test/testyuv.bmp b/libs/SDL2/test/testyuv.bmp
new file mode 100644
index 000000000..af32034b6
Binary files /dev/null and b/libs/SDL2/test/testyuv.bmp differ
diff --git a/libs/SDL2/test/testyuv.c b/libs/SDL2/test/testyuv.c
new file mode 100644
index 000000000..f52ab9f72
--- /dev/null
+++ b/libs/SDL2/test/testyuv.c
@@ -0,0 +1,455 @@
+/*
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+  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.
+*/
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "SDL.h"
+#include "SDL_test_font.h"
+#include "testyuv_cvt.h"
+
+
+/* 422 (YUY2, etc) formats are the largest */
+#define MAX_YUV_SURFACE_SIZE(W, H, P)  (H*4*(W+P+1)/2)
+
+
+/* Return true if the YUV format is packed pixels */
+static SDL_bool is_packed_yuv_format(Uint32 format)
+{
+    return (format == SDL_PIXELFORMAT_YUY2 ||
+            format == SDL_PIXELFORMAT_UYVY ||
+            format == SDL_PIXELFORMAT_YVYU);
+}
+
+/* Create a surface with a good pattern for verifying YUV conversion */
+static SDL_Surface *generate_test_pattern(int pattern_size)
+{
+    SDL_Surface *pattern = SDL_CreateRGBSurfaceWithFormat(0, pattern_size, pattern_size, 0, SDL_PIXELFORMAT_RGB24);
+
+    if (pattern) {
+        int i, x, y;
+        Uint8 *p, c;
+        const int thickness = 2;    /* Important so 2x2 blocks of color are the same, to avoid Cr/Cb interpolation over pixels */
+
+        /* R, G, B in alternating horizontal bands */
+        for (y = 0; y < pattern->h; y += thickness) {
+            for (i = 0; i < thickness; ++i) {
+                p = (Uint8 *)pattern->pixels + (y + i) * pattern->pitch + ((y/thickness) % 3);
+                for (x = 0; x < pattern->w; ++x) {
+                    *p = 0xFF;
+                    p += 3;
+                }
+            }
+        }
+
+        /* Black and white in alternating vertical bands */
+        c = 0xFF;
+        for (x = 1*thickness; x < pattern->w; x += 2*thickness) {
+            for (i = 0; i < thickness; ++i) {
+                p = (Uint8 *)pattern->pixels + (x + i)*3;
+                for (y = 0; y < pattern->h; ++y) {
+                    SDL_memset(p, c, 3);
+                    p += pattern->pitch;
+                }
+            }
+            if (c) {
+                c = 0x00;
+            } else {
+                c = 0xFF;
+            }
+        }
+    }
+    return pattern;
+}
+
+static SDL_bool verify_yuv_data(Uint32 format, const Uint8 *yuv, int yuv_pitch, SDL_Surface *surface)
+{
+    const int tolerance = 20;
+    const int size = (surface->h * surface->pitch);
+    Uint8 *rgb;
+    SDL_bool result = SDL_FALSE;
+
+    rgb = (Uint8 *)SDL_malloc(size);
+    if (!rgb) {
+        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Out of memory");
+        return SDL_FALSE;
+    }
+
+    if (SDL_ConvertPixels(surface->w, surface->h, format, yuv, yuv_pitch, surface->format->format, rgb, surface->pitch) == 0) {
+        int x, y;
+        result = SDL_TRUE;
+        for (y = 0; y < surface->h; ++y) {
+            const Uint8 *actual = rgb + y * surface->pitch;
+            const Uint8 *expected = (const Uint8 *)surface->pixels + y * surface->pitch;
+            for (x = 0; x < surface->w; ++x) {
+                int deltaR = (int)actual[0] - expected[0];
+                int deltaG = (int)actual[1] - expected[1];
+                int deltaB = (int)actual[2] - expected[2];
+                int distance = (deltaR * deltaR + deltaG * deltaG + deltaB * deltaB);
+                if (distance > tolerance) {
+                    SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Pixel at %d,%d was 0x%.2x,0x%.2x,0x%.2x, expected 0x%.2x,0x%.2x,0x%.2x, distance = %d\n", x, y, actual[0], actual[1], actual[2], expected[0], expected[1], expected[2], distance);
+                    result = SDL_FALSE;
+                }
+                actual += 3;
+                expected += 3;
+            }
+        }
+    } else {
+        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't convert %s to %s: %s\n", SDL_GetPixelFormatName(format), SDL_GetPixelFormatName(surface->format->format), SDL_GetError());
+    }
+    SDL_free(rgb);
+
+    return result;
+}
+
+static int run_automated_tests(int pattern_size, int extra_pitch)
+{
+    const Uint32 formats[] = {
+        SDL_PIXELFORMAT_YV12,
+        SDL_PIXELFORMAT_IYUV,
+        SDL_PIXELFORMAT_NV12,
+        SDL_PIXELFORMAT_NV21,
+        SDL_PIXELFORMAT_YUY2,
+        SDL_PIXELFORMAT_UYVY,
+        SDL_PIXELFORMAT_YVYU
+    };
+    int i, j;
+    SDL_Surface *pattern = generate_test_pattern(pattern_size);
+    const int yuv_len = MAX_YUV_SURFACE_SIZE(pattern->w, pattern->h, extra_pitch);
+    Uint8 *yuv1 = (Uint8 *)SDL_malloc(yuv_len);
+    Uint8 *yuv2 = (Uint8 *)SDL_malloc(yuv_len);
+    int yuv1_pitch, yuv2_pitch;
+    int result = -1;
+    
+    if (!pattern || !yuv1 || !yuv2) {
+        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't allocate test surfaces");
+        goto done;
+    }
+
+    /* Verify conversion from YUV formats */
+    for (i = 0; i < SDL_arraysize(formats); ++i) {
+        if (!ConvertRGBtoYUV(formats[i], pattern->pixels, pattern->pitch, yuv1, pattern->w, pattern->h, SDL_GetYUVConversionModeForResolution(pattern->w, pattern->h), 0, 100)) {
+            SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "ConvertRGBtoYUV() doesn't support converting to %s\n", SDL_GetPixelFormatName(formats[i]));
+            goto done;
+        }
+        yuv1_pitch = CalculateYUVPitch(formats[i], pattern->w);
+        if (!verify_yuv_data(formats[i], yuv1, yuv1_pitch, pattern)) {
+            SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed conversion from %s to RGB\n", SDL_GetPixelFormatName(formats[i]));
+            goto done;
+        }
+    }
+
+    /* Verify conversion to YUV formats */
+    for (i = 0; i < SDL_arraysize(formats); ++i) {
+        yuv1_pitch = CalculateYUVPitch(formats[i], pattern->w) + extra_pitch;
+        if (SDL_ConvertPixels(pattern->w, pattern->h, pattern->format->format, pattern->pixels, pattern->pitch, formats[i], yuv1, yuv1_pitch) < 0) {
+            SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't convert %s to %s: %s\n", SDL_GetPixelFormatName(pattern->format->format), SDL_GetPixelFormatName(formats[i]), SDL_GetError());
+            goto done;
+        }
+        if (!verify_yuv_data(formats[i], yuv1, yuv1_pitch, pattern)) {
+            SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed conversion from RGB to %s\n", SDL_GetPixelFormatName(formats[i]));
+            goto done;
+        }
+    }
+
+    /* Verify conversion between YUV formats */
+    for (i = 0; i < SDL_arraysize(formats); ++i) {
+        for (j = 0; j < SDL_arraysize(formats); ++j) {
+            yuv1_pitch = CalculateYUVPitch(formats[i], pattern->w) + extra_pitch;
+            yuv2_pitch = CalculateYUVPitch(formats[j], pattern->w) + extra_pitch;
+            if (SDL_ConvertPixels(pattern->w, pattern->h, pattern->format->format, pattern->pixels, pattern->pitch, formats[i], yuv1, yuv1_pitch) < 0) {
+                SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't convert %s to %s: %s\n", SDL_GetPixelFormatName(pattern->format->format), SDL_GetPixelFormatName(formats[i]), SDL_GetError());
+                goto done;
+            }
+            if (SDL_ConvertPixels(pattern->w, pattern->h, formats[i], yuv1, yuv1_pitch, formats[j], yuv2, yuv2_pitch) < 0) {
+                SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't convert %s to %s: %s\n", SDL_GetPixelFormatName(formats[i]), SDL_GetPixelFormatName(formats[j]), SDL_GetError());
+                goto done;
+            }
+            if (!verify_yuv_data(formats[j], yuv2, yuv2_pitch, pattern)) {
+                SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed conversion from %s to %s\n", SDL_GetPixelFormatName(formats[i]), SDL_GetPixelFormatName(formats[j]));
+                goto done;
+            }
+        }
+    }
+
+    /* Verify conversion between YUV formats in-place */
+    for (i = 0; i < SDL_arraysize(formats); ++i) {
+        for (j = 0; j < SDL_arraysize(formats); ++j) {
+            if (is_packed_yuv_format(formats[i]) != is_packed_yuv_format(formats[j])) {
+                /* Can't change plane vs packed pixel layout in-place */
+                continue;
+            }
+
+            yuv1_pitch = CalculateYUVPitch(formats[i], pattern->w) + extra_pitch;
+            yuv2_pitch = CalculateYUVPitch(formats[j], pattern->w) + extra_pitch;
+            if (SDL_ConvertPixels(pattern->w, pattern->h, pattern->format->format, pattern->pixels, pattern->pitch, formats[i], yuv1, yuv1_pitch) < 0) {
+                SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't convert %s to %s: %s\n", SDL_GetPixelFormatName(pattern->format->format), SDL_GetPixelFormatName(formats[i]), SDL_GetError());
+                goto done;
+            }
+            if (SDL_ConvertPixels(pattern->w, pattern->h, formats[i], yuv1, yuv1_pitch, formats[j], yuv1, yuv2_pitch) < 0) {
+                SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't convert %s to %s: %s\n", SDL_GetPixelFormatName(formats[i]), SDL_GetPixelFormatName(formats[j]), SDL_GetError());
+                goto done;
+            }
+            if (!verify_yuv_data(formats[j], yuv1, yuv2_pitch, pattern)) {
+                SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed conversion from %s to %s\n", SDL_GetPixelFormatName(formats[i]), SDL_GetPixelFormatName(formats[j]));
+                goto done;
+            }
+        }
+    }
+
+
+    result = 0;
+
+done:
+    SDL_free(yuv1);
+    SDL_free(yuv2);
+    SDL_FreeSurface(pattern);
+    return result;
+}
+
+int
+main(int argc, char **argv)
+{
+    struct {
+        SDL_bool enable_intrinsics;
+        int pattern_size;
+        int extra_pitch;
+    } automated_test_params[] = {
+        /* Test: even width and height */
+        { SDL_FALSE, 2, 0 },
+        { SDL_FALSE, 4, 0 },
+        /* Test: odd width and height */
+        { SDL_FALSE, 1, 0 },
+        { SDL_FALSE, 3, 0 },
+        /* Test: even width and height, extra pitch */
+        { SDL_FALSE, 2, 3 },
+        { SDL_FALSE, 4, 3 },
+        /* Test: odd width and height, extra pitch */
+        { SDL_FALSE, 1, 3 },
+        { SDL_FALSE, 3, 3 },
+        /* Test: even width and height with intrinsics */
+        { SDL_TRUE, 32, 0 },
+        /* Test: odd width and height with intrinsics */
+        { SDL_TRUE, 33, 0 },
+        { SDL_TRUE, 37, 0 },
+        /* Test: even width and height with intrinsics, extra pitch */
+        { SDL_TRUE, 32, 3 },
+        /* Test: odd width and height with intrinsics, extra pitch */
+        { SDL_TRUE, 33, 3 },
+        { SDL_TRUE, 37, 3 },
+    };
+    int arg = 1;
+    const char *filename;
+    SDL_Surface *original;
+    SDL_Surface *converted;
+    SDL_Window *window;
+    SDL_Renderer *renderer;
+    SDL_Texture *output[3];
+    const char *titles[3] = { "ORIGINAL", "SOFTWARE", "HARDWARE" };
+    char title[128];
+    const char *yuv_name;
+    const char *yuv_mode;
+    Uint32 rgb_format = SDL_PIXELFORMAT_RGBX8888;
+    Uint32 yuv_format = SDL_PIXELFORMAT_YV12;
+    int current = 0;
+    int pitch;
+    Uint8 *raw_yuv;
+    Uint32 then, now, i, iterations = 100;
+    SDL_bool should_run_automated_tests = SDL_FALSE;
+
+    while (argv[arg] && *argv[arg] == '-') {
+        if (SDL_strcmp(argv[arg], "--jpeg") == 0) {
+            SDL_SetYUVConversionMode(SDL_YUV_CONVERSION_JPEG);
+        } else if (SDL_strcmp(argv[arg], "--bt601") == 0) {
+            SDL_SetYUVConversionMode(SDL_YUV_CONVERSION_BT601);
+        } else if (SDL_strcmp(argv[arg], "--bt709") == 0) {
+            SDL_SetYUVConversionMode(SDL_YUV_CONVERSION_BT709);
+        } else if (SDL_strcmp(argv[arg], "--auto") == 0) {
+            SDL_SetYUVConversionMode(SDL_YUV_CONVERSION_AUTOMATIC);
+        } else if (SDL_strcmp(argv[arg], "--yv12") == 0) {
+            yuv_format = SDL_PIXELFORMAT_YV12;
+        } else if (SDL_strcmp(argv[arg], "--iyuv") == 0) {
+            yuv_format = SDL_PIXELFORMAT_IYUV;
+        } else if (SDL_strcmp(argv[arg], "--yuy2") == 0) {
+            yuv_format = SDL_PIXELFORMAT_YUY2;
+        } else if (SDL_strcmp(argv[arg], "--uyvy") == 0) {
+            yuv_format = SDL_PIXELFORMAT_UYVY;
+        } else if (SDL_strcmp(argv[arg], "--yvyu") == 0) {
+            yuv_format = SDL_PIXELFORMAT_YVYU;
+        } else if (SDL_strcmp(argv[arg], "--nv12") == 0) {
+            yuv_format = SDL_PIXELFORMAT_NV12;
+        } else if (SDL_strcmp(argv[arg], "--nv21") == 0) {
+            yuv_format = SDL_PIXELFORMAT_NV21;
+        } else if (SDL_strcmp(argv[arg], "--rgb555") == 0) {
+            rgb_format = SDL_PIXELFORMAT_RGB555;
+        } else if (SDL_strcmp(argv[arg], "--rgb565") == 0) {
+            rgb_format = SDL_PIXELFORMAT_RGB565;
+        } else if (SDL_strcmp(argv[arg], "--rgb24") == 0) {
+            rgb_format = SDL_PIXELFORMAT_RGB24;
+        } else if (SDL_strcmp(argv[arg], "--argb") == 0) {
+            rgb_format = SDL_PIXELFORMAT_ARGB8888;
+        } else if (SDL_strcmp(argv[arg], "--abgr") == 0) {
+            rgb_format = SDL_PIXELFORMAT_ABGR8888;
+        } else if (SDL_strcmp(argv[arg], "--rgba") == 0) {
+            rgb_format = SDL_PIXELFORMAT_RGBA8888;
+        } else if (SDL_strcmp(argv[arg], "--bgra") == 0) {
+            rgb_format = SDL_PIXELFORMAT_BGRA8888;
+        } else if (SDL_strcmp(argv[arg], "--automated") == 0) {
+            should_run_automated_tests = SDL_TRUE;
+        } else {
+            SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Usage: %s [--jpeg|--bt601|-bt709|--auto] [--yv12|--iyuv|--yuy2|--uyvy|--yvyu|--nv12|--nv21] [--rgb555|--rgb565|--rgb24|--argb|--abgr|--rgba|--bgra] [image_filename]\n", argv[0]);
+            return 1;
+        }
+        ++arg;
+    }
+
+    /* Run automated tests */
+    if (should_run_automated_tests) {
+        for (i = 0; i < SDL_arraysize(automated_test_params); ++i) {
+            SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "Running automated test, pattern size %d, extra pitch %d, intrinsics %s\n", 
+                automated_test_params[i].pattern_size,
+                automated_test_params[i].extra_pitch,
+                automated_test_params[i].enable_intrinsics ? "enabled" : "disabled");
+            if (run_automated_tests(automated_test_params[i].pattern_size, automated_test_params[i].extra_pitch) < 0) {
+                return 2;
+            }
+        }
+        return 0;
+    }
+
+    if (argv[arg]) {
+        filename = argv[arg];
+    } else {
+        filename = "testyuv.bmp";
+    }
+    original = SDL_ConvertSurfaceFormat(SDL_LoadBMP(filename), SDL_PIXELFORMAT_RGB24, 0);
+    if (!original) {
+        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't load %s: %s\n", filename, SDL_GetError());
+        return 3;
+    }
+
+    raw_yuv = SDL_calloc(1, MAX_YUV_SURFACE_SIZE(original->w, original->h, 0));
+    ConvertRGBtoYUV(yuv_format, original->pixels, original->pitch, raw_yuv, original->w, original->h,
+        SDL_GetYUVConversionModeForResolution(original->w, original->h),
+        0, 100);
+    pitch = CalculateYUVPitch(yuv_format, original->w);
+
+    converted = SDL_CreateRGBSurfaceWithFormat(0, original->w, original->h, 0, rgb_format);
+    if (!converted) {
+        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create converted surface: %s\n", SDL_GetError());
+        return 3;
+    }
+
+    then = SDL_GetTicks();
+    for ( i = 0; i < iterations; ++i ) {
+        SDL_ConvertPixels(original->w, original->h, yuv_format, raw_yuv, pitch, rgb_format, converted->pixels, converted->pitch);
+    }
+    now = SDL_GetTicks();
+    SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "%d iterations in %d ms, %.2fms each\n", iterations, (now - then), (float)(now - then)/iterations);
+
+    window = SDL_CreateWindow("YUV test",
+                              SDL_WINDOWPOS_UNDEFINED,
+                              SDL_WINDOWPOS_UNDEFINED,
+                              original->w, original->h,
+                              0);
+    if (!window) {
+        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create window: %s\n", SDL_GetError());
+        return 4;
+    }
+
+    renderer = SDL_CreateRenderer(window, -1, 0);
+    if (!renderer) {
+        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create renderer: %s\n", SDL_GetError());
+        return 4;
+    }
+
+    output[0] = SDL_CreateTextureFromSurface(renderer, original);
+    output[1] = SDL_CreateTextureFromSurface(renderer, converted);
+    output[2] = SDL_CreateTexture(renderer, yuv_format, SDL_TEXTUREACCESS_STREAMING, original->w, original->h);
+    if (!output[0] || !output[1] || !output[2]) {
+        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't set create texture: %s\n", SDL_GetError());
+        return 5;
+    }
+    SDL_UpdateTexture(output[2], NULL, raw_yuv, pitch);
+    
+    yuv_name = SDL_GetPixelFormatName(yuv_format);
+    if (SDL_strncmp(yuv_name, "SDL_PIXELFORMAT_", 16) == 0) {
+        yuv_name += 16;
+    }
+
+    switch (SDL_GetYUVConversionModeForResolution(original->w, original->h)) {
+    case SDL_YUV_CONVERSION_JPEG:
+        yuv_mode = "JPEG";
+        break;
+    case SDL_YUV_CONVERSION_BT601:
+        yuv_mode = "BT.601";
+        break;
+    case SDL_YUV_CONVERSION_BT709:
+        yuv_mode = "BT.709";
+        break;
+    default:
+        yuv_mode = "UNKNOWN";
+        break;
+    }
+
+    { int done = 0;
+        while ( !done )
+        {
+            SDL_Event event;
+            while (SDL_PollEvent(&event) > 0) {
+                if (event.type == SDL_QUIT) {
+                    done = 1;
+                }
+                if (event.type == SDL_KEYDOWN) {
+                    if (event.key.keysym.sym == SDLK_ESCAPE) {
+                        done = 1;
+                    } else if (event.key.keysym.sym == SDLK_LEFT) {
+                        --current;
+                    } else if (event.key.keysym.sym == SDLK_RIGHT) {
+                        ++current;
+                    }
+                }
+                if (event.type == SDL_MOUSEBUTTONDOWN) {
+                    if (event.button.x < (original->w/2)) {
+                        --current;
+                    } else {
+                        ++current;
+                    }
+                }
+            }
+
+            /* Handle wrapping */
+            if (current < 0) {
+                current += SDL_arraysize(output);
+            }
+            if (current >= SDL_arraysize(output)) {
+                current -= SDL_arraysize(output);
+            }
+
+            SDL_RenderClear(renderer);
+            SDL_RenderCopy(renderer, output[current], NULL, NULL);
+            SDL_SetRenderDrawColor(renderer, 0xFF, 0xFF, 0xFF, 0xFF);
+            if (current == 0) {
+                SDLTest_DrawString(renderer, 4, 4, titles[current]);
+            } else {
+                SDL_snprintf(title, sizeof(title), "%s %s %s", titles[current], yuv_name, yuv_mode);
+                SDLTest_DrawString(renderer, 4, 4, title);
+            }
+            SDL_RenderPresent(renderer);
+            SDL_Delay(10);
+        }
+    }
+    SDL_Quit();
+    return 0;
+}
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/libs/SDL2/test/testyuv_cvt.c b/libs/SDL2/test/testyuv_cvt.c
new file mode 100644
index 000000000..553a3fa18
--- /dev/null
+++ b/libs/SDL2/test/testyuv_cvt.c
@@ -0,0 +1,300 @@
+/*
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+  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.
+*/
+
+#include "SDL.h"
+
+#include "testyuv_cvt.h"
+
+
+static float clip3(float x, float y, float z)
+{
+    return ((z < x) ? x : ((z > y) ? y : z));
+}
+
+static void RGBtoYUV(Uint8 * rgb, int *yuv, SDL_YUV_CONVERSION_MODE mode, int monochrome, int luminance)
+{
+    if (mode == SDL_YUV_CONVERSION_JPEG) {
+        /* Full range YUV */
+        yuv[0] = (int)(0.299 * rgb[0] + 0.587 * rgb[1] + 0.114 * rgb[2]);
+        yuv[1] = (int)((rgb[2] - yuv[0]) * 0.565 + 128);
+        yuv[2] = (int)((rgb[0] - yuv[0]) * 0.713 + 128);
+    } else {
+        // This formula is from Microsoft's documentation:
+        // https://msdn.microsoft.com/en-us/library/windows/desktop/dd206750(v=vs.85).aspx
+        // L = Kr * R + Kb * B + (1 - Kr - Kb) * G
+        // Y =                   floor(2^(M-8) * (219*(L-Z)/S + 16) + 0.5);
+        // U = clip3(0, (2^M)-1, floor(2^(M-8) * (112*(B-L) / ((1-Kb)*S) + 128) + 0.5));
+        // V = clip3(0, (2^M)-1, floor(2^(M-8) * (112*(R-L) / ((1-Kr)*S) + 128) + 0.5));
+        float S, Z, R, G, B, L, Kr, Kb, Y, U, V;
+
+        if (mode == SDL_YUV_CONVERSION_BT709) {
+            /* BT.709 */
+            Kr = 0.2126f;
+            Kb = 0.0722f;
+        } else {
+            /* BT.601 */
+            Kr = 0.299f;
+            Kb = 0.114f;
+        }
+
+        S = 255.0f;
+        Z = 0.0f;
+        R = rgb[0];
+        G = rgb[1];
+        B = rgb[2];
+        L = Kr * R + Kb * B + (1 - Kr - Kb) * G;
+        Y = (Uint8)SDL_floorf((219*(L-Z)/S + 16) + 0.5f);
+        U = (Uint8)clip3(0, 255, SDL_floorf((112.0f*(B-L) / ((1.0f-Kb)*S) + 128) + 0.5f));
+        V = (Uint8)clip3(0, 255, SDL_floorf((112.0f*(R-L) / ((1.0f-Kr)*S) + 128) + 0.5f));
+
+        yuv[0] = (Uint8)Y;
+        yuv[1] = (Uint8)U;
+        yuv[2] = (Uint8)V;
+    }
+
+    if (monochrome) {
+        yuv[1] = 128;
+        yuv[2] = 128;
+    }
+
+    if (luminance != 100) {
+        yuv[0] = yuv[0] * luminance / 100;
+        if (yuv[0] > 255)
+            yuv[0] = 255;
+    }
+}
+
+static void ConvertRGBtoPlanar2x2(Uint32 format, Uint8 *src, int pitch, Uint8 *out, int w, int h, SDL_YUV_CONVERSION_MODE mode, int monochrome, int luminance)
+{
+    int x, y;
+    int yuv[4][3];
+    Uint8 *Y1, *Y2, *U, *V;
+    Uint8 *rgb1, *rgb2;
+    int rgb_row_advance = (pitch - w*3) + pitch;
+    int UV_advance;
+
+    rgb1 = src;
+    rgb2 = src + pitch;
+
+    Y1 = out;
+    Y2 = Y1 + w;
+    switch (format) {
+    case SDL_PIXELFORMAT_YV12:
+        V = (Y1 + h * w);
+        U = V + ((h + 1)/2)*((w + 1)/2);
+        UV_advance = 1;
+        break;
+    case SDL_PIXELFORMAT_IYUV:
+        U = (Y1 + h * w);
+        V = U + ((h + 1)/2)*((w + 1)/2);
+        UV_advance = 1;
+        break;
+    case SDL_PIXELFORMAT_NV12:
+        U = (Y1 + h * w);
+        V = U + 1;
+        UV_advance = 2;
+        break;
+    case SDL_PIXELFORMAT_NV21:
+        V = (Y1 + h * w);
+        U = V + 1;
+        UV_advance = 2;
+        break;
+    default:
+        SDL_assert(!"Unsupported planar YUV format");
+        return;
+    }
+
+    for (y = 0; y < (h - 1); y += 2) {
+        for (x = 0; x < (w - 1); x += 2) {
+            RGBtoYUV(rgb1, yuv[0], mode, monochrome, luminance);
+            rgb1 += 3;
+            *Y1++ = (Uint8)yuv[0][0];
+
+            RGBtoYUV(rgb1, yuv[1], mode, monochrome, luminance);
+            rgb1 += 3;
+            *Y1++ = (Uint8)yuv[1][0];
+
+            RGBtoYUV(rgb2, yuv[2], mode, monochrome, luminance);
+            rgb2 += 3;
+            *Y2++ = (Uint8)yuv[2][0];
+
+            RGBtoYUV(rgb2, yuv[3], mode, monochrome, luminance);
+            rgb2 += 3;
+            *Y2++ = (Uint8)yuv[3][0];
+
+            *U = (Uint8)SDL_floorf((yuv[0][1] + yuv[1][1] + yuv[2][1] + yuv[3][1])/4.0f + 0.5f);
+            U += UV_advance;
+
+            *V = (Uint8)SDL_floorf((yuv[0][2] + yuv[1][2] + yuv[2][2] + yuv[3][2])/4.0f + 0.5f);
+            V += UV_advance;
+        }
+        /* Last column */
+        if (x == (w - 1)) {
+            RGBtoYUV(rgb1, yuv[0], mode, monochrome, luminance);
+            rgb1 += 3;
+            *Y1++ = (Uint8)yuv[0][0];
+
+            RGBtoYUV(rgb2, yuv[2], mode, monochrome, luminance);
+            rgb2 += 3;
+            *Y2++ = (Uint8)yuv[2][0];
+
+            *U = (Uint8)SDL_floorf((yuv[0][1] + yuv[2][1])/2.0f + 0.5f);
+            U += UV_advance;
+
+            *V = (Uint8)SDL_floorf((yuv[0][2] + yuv[2][2])/2.0f + 0.5f);
+            V += UV_advance;
+        }
+        Y1 += w;
+        Y2 += w;
+        rgb1 += rgb_row_advance;
+        rgb2 += rgb_row_advance;
+    }
+    /* Last row */
+    if (y == (h - 1)) {
+        for (x = 0; x < (w - 1); x += 2) {
+            RGBtoYUV(rgb1, yuv[0], mode, monochrome, luminance);
+            rgb1 += 3;
+            *Y1++ = (Uint8)yuv[0][0];
+
+            RGBtoYUV(rgb1, yuv[1], mode, monochrome, luminance);
+            rgb1 += 3;
+            *Y1++ = (Uint8)yuv[1][0];
+
+            *U = (Uint8)SDL_floorf((yuv[0][1] + yuv[1][1])/2.0f + 0.5f);
+            U += UV_advance;
+
+            *V = (Uint8)SDL_floorf((yuv[0][2] + yuv[1][2])/2.0f + 0.5f);
+            V += UV_advance;
+        }
+        /* Last column */
+        if (x == (w - 1)) {
+            RGBtoYUV(rgb1, yuv[0], mode, monochrome, luminance);
+            *Y1++ = (Uint8)yuv[0][0];
+
+            *U = (Uint8)yuv[0][1];
+            U += UV_advance;
+
+            *V = (Uint8)yuv[0][2];
+            V += UV_advance;
+        }
+    }
+}
+
+static void ConvertRGBtoPacked4(Uint32 format, Uint8 *src, int pitch, Uint8 *out, int w, int h, SDL_YUV_CONVERSION_MODE mode, int monochrome, int luminance)
+{
+    int x, y;
+    int yuv[2][3];
+    Uint8 *Y1, *Y2, *U, *V;
+    Uint8 *rgb;
+    int rgb_row_advance = (pitch - w*3);
+
+    rgb = src;
+
+    switch (format) {
+    case SDL_PIXELFORMAT_YUY2:
+        Y1 = out;
+        U = out+1;
+        Y2 = out+2;
+        V = out+3;
+        break;
+    case SDL_PIXELFORMAT_UYVY:
+        U = out;
+        Y1 = out+1;
+        V = out+2;
+        Y2 = out+3;
+        break;
+    case SDL_PIXELFORMAT_YVYU:
+        Y1 = out;
+        V = out+1;
+        Y2 = out+2;
+        U = out+3;
+        break;
+    default:
+        SDL_assert(!"Unsupported packed YUV format");
+        return;
+    }
+
+    for (y = 0; y < h; ++y) {
+        for (x = 0; x < (w - 1); x += 2) {
+            RGBtoYUV(rgb, yuv[0], mode, monochrome, luminance);
+            rgb += 3;
+            *Y1 = (Uint8)yuv[0][0];
+            Y1 += 4;
+
+            RGBtoYUV(rgb, yuv[1], mode, monochrome, luminance);
+            rgb += 3;
+            *Y2 = (Uint8)yuv[1][0];
+            Y2 += 4;
+
+            *U = (Uint8)SDL_floorf((yuv[0][1] + yuv[1][1])/2.0f + 0.5f);
+            U += 4;
+
+            *V = (Uint8)SDL_floorf((yuv[0][2] + yuv[1][2])/2.0f + 0.5f);
+            V += 4;
+        }
+        /* Last column */
+        if (x == (w - 1)) {
+            RGBtoYUV(rgb, yuv[0], mode, monochrome, luminance);
+            rgb += 3;
+            *Y2 = *Y1 = (Uint8)yuv[0][0];
+            Y1 += 4;
+            Y2 += 4;
+
+            *U = (Uint8)yuv[0][1];
+            U += 4;
+
+            *V = (Uint8)yuv[0][2];
+            V += 4;
+        }
+        rgb += rgb_row_advance;
+    }
+}
+
+SDL_bool ConvertRGBtoYUV(Uint32 format, Uint8 *src, int pitch, Uint8 *out, int w, int h, SDL_YUV_CONVERSION_MODE mode, int monochrome, int luminance)
+{
+    switch (format)
+    {
+    case SDL_PIXELFORMAT_YV12:
+    case SDL_PIXELFORMAT_IYUV:
+    case SDL_PIXELFORMAT_NV12:
+    case SDL_PIXELFORMAT_NV21:
+        ConvertRGBtoPlanar2x2(format, src, pitch, out, w, h, mode, monochrome, luminance);
+        return SDL_TRUE;
+    case SDL_PIXELFORMAT_YUY2:
+    case SDL_PIXELFORMAT_UYVY:
+    case SDL_PIXELFORMAT_YVYU:
+        ConvertRGBtoPacked4(format, src, pitch, out, w, h, mode, monochrome, luminance);
+        return SDL_TRUE;
+    default:
+        return SDL_FALSE;
+    }
+}
+
+int CalculateYUVPitch(Uint32 format, int width)
+{
+    switch (format)
+    {
+    case SDL_PIXELFORMAT_YV12:
+    case SDL_PIXELFORMAT_IYUV:
+    case SDL_PIXELFORMAT_NV12:
+    case SDL_PIXELFORMAT_NV21:
+        return width;
+    case SDL_PIXELFORMAT_YUY2:
+    case SDL_PIXELFORMAT_UYVY:
+    case SDL_PIXELFORMAT_YVYU:
+        return 4*((width + 1)/2);
+    default:
+        return 0;
+    }
+}
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/libs/SDL2/test/testyuv_cvt.h b/libs/SDL2/test/testyuv_cvt.h
new file mode 100644
index 000000000..bd845878f
--- /dev/null
+++ b/libs/SDL2/test/testyuv_cvt.h
@@ -0,0 +1,16 @@
+/*
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+  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.
+*/
+
+/* These functions are designed for testing correctness, not for speed */
+
+extern SDL_bool ConvertRGBtoYUV(Uint32 format, Uint8 *src, int pitch, Uint8 *out, int w, int h, SDL_YUV_CONVERSION_MODE mode, int monochrome, int luminance);
+extern int CalculateYUVPitch(Uint32 format, int width);
diff --git a/libs/SDL2/test/torturethread.c b/libs/SDL2/test/torturethread.c
index 4c2679b8e..9b1a407ee 100644
--- a/libs/SDL2/test/torturethread.c
+++ b/libs/SDL2/test/torturethread.c
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/x86_64-w64-mingw32/bin/SDL2.dll b/libs/SDL2/x86_64-w64-mingw32/bin/SDL2.dll
index 6776cdd89..934f8091c 100755
Binary files a/libs/SDL2/x86_64-w64-mingw32/bin/SDL2.dll and b/libs/SDL2/x86_64-w64-mingw32/bin/SDL2.dll differ
diff --git a/libs/SDL2/x86_64-w64-mingw32/bin/sdl2-config b/libs/SDL2/x86_64-w64-mingw32/bin/sdl2-config
index 34d3cb877..9809f6002 100755
--- a/libs/SDL2/x86_64-w64-mingw32/bin/sdl2-config
+++ b/libs/SDL2/x86_64-w64-mingw32/bin/sdl2-config
@@ -1,6 +1,6 @@
 #!/bin/sh
 
-prefix=/usr/local/x86_64-w64-mingw32
+prefix=/opt/local/x86_64-w64-mingw32
 exec_prefix=${prefix}
 exec_prefix_set=no
 libdir=${exec_prefix}/lib
@@ -39,17 +39,17 @@ while test $# -gt 0; do
       echo $exec_prefix
       ;;
     --version)
-      echo 2.0.7
+      echo 2.0.9
       ;;
     --cflags)
       echo -I${prefix}/include/SDL2  -Dmain=SDL_main
       ;;
     --libs)
-      echo -L${exec_prefix}/lib  -lmingw32 -lSDL2main -lSDL2  -mwindows
+      echo -L${exec_prefix}/lib  -lmingw32 -lSDL2main -lSDL2 -mwindows
       ;;
     --static-libs)
 #    --libs|--static-libs)
-      echo -L${exec_prefix}/lib  -lmingw32 -lSDL2main -lSDL2  -mwindows  -Wl,--no-undefined -lm -ldinput8 -ldxguid -ldxerr8 -luser32 -lgdi32 -lwinmm -limm32 -lole32 -loleaut32 -lshell32 -lversion -luuid -static-libgcc
+      echo -L${exec_prefix}/lib  -lmingw32 -lSDL2main -lSDL2 -mwindows  -Wl,--no-undefined -lm -ldinput8 -ldxguid -ldxerr8 -luser32 -lgdi32 -lwinmm -limm32 -lole32 -loleaut32 -lshell32 -lsetupapi -lversion -luuid -static-libgcc
       ;;
     *)
       echo "${usage}" 1>&2
diff --git a/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL.h b/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL.h
index 366d50fa3..fc35a419e 100644
--- a/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL.h
+++ b/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
@@ -51,6 +51,7 @@
 #include "SDL_power.h"
 #include "SDL_render.h"
 #include "SDL_rwops.h"
+#include "SDL_sensor.h"
 #include "SDL_shape.h"
 #include "SDL_system.h"
 #include "SDL_thread.h"
@@ -80,10 +81,11 @@ extern "C" {
 #define SDL_INIT_HAPTIC         0x00001000u
 #define SDL_INIT_GAMECONTROLLER 0x00002000u  /**< SDL_INIT_GAMECONTROLLER implies SDL_INIT_JOYSTICK */
 #define SDL_INIT_EVENTS         0x00004000u
+#define SDL_INIT_SENSOR         0x00008000u
 #define SDL_INIT_NOPARACHUTE    0x00100000u  /**< compatibility; this flag is ignored. */
 #define SDL_INIT_EVERYTHING ( \
                 SDL_INIT_TIMER | SDL_INIT_AUDIO | SDL_INIT_VIDEO | SDL_INIT_EVENTS | \
-                SDL_INIT_JOYSTICK | SDL_INIT_HAPTIC | SDL_INIT_GAMECONTROLLER \
+                SDL_INIT_JOYSTICK | SDL_INIT_HAPTIC | SDL_INIT_GAMECONTROLLER | SDL_INIT_SENSOR \
             )
 /* @} */
 
diff --git a/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_assert.h b/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_assert.h
index 90abbe39b..b38f928ae 100644
--- a/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_assert.h
+++ b/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_assert.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_atomic.h b/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_atomic.h
index 36e37f3b7..b2287748c 100644
--- a/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_atomic.h
+++ b/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_atomic.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
@@ -158,6 +158,9 @@ extern DECLSPEC void SDLCALL SDL_MemoryBarrierAcquireFunction(void);
 #if defined(__GNUC__) && (defined(__powerpc__) || defined(__ppc__))
 #define SDL_MemoryBarrierRelease()   __asm__ __volatile__ ("lwsync" : : : "memory")
 #define SDL_MemoryBarrierAcquire()   __asm__ __volatile__ ("lwsync" : : : "memory")
+#elif defined(__GNUC__) && defined(__aarch64__)
+#define SDL_MemoryBarrierRelease()   __asm__ __volatile__ ("dmb ish" : : : "memory")
+#define SDL_MemoryBarrierAcquire()   __asm__ __volatile__ ("dmb ish" : : : "memory")
 #elif defined(__GNUC__) && defined(__arm__)
 #if defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7EM__) || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7S__)
 #define SDL_MemoryBarrierRelease()   __asm__ __volatile__ ("dmb ish" : : : "memory")
diff --git a/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_audio.h b/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_audio.h
index f119c2b26..d3e1bface 100644
--- a/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_audio.h
+++ b/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_audio.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
@@ -140,7 +140,8 @@ typedef Uint16 SDL_AudioFormat;
 #define SDL_AUDIO_ALLOW_FREQUENCY_CHANGE    0x00000001
 #define SDL_AUDIO_ALLOW_FORMAT_CHANGE       0x00000002
 #define SDL_AUDIO_ALLOW_CHANNELS_CHANGE     0x00000004
-#define SDL_AUDIO_ALLOW_ANY_CHANGE          (SDL_AUDIO_ALLOW_FREQUENCY_CHANGE|SDL_AUDIO_ALLOW_FORMAT_CHANGE|SDL_AUDIO_ALLOW_CHANNELS_CHANGE)
+#define SDL_AUDIO_ALLOW_SAMPLES_CHANGE      0x00000008
+#define SDL_AUDIO_ALLOW_ANY_CHANGE          (SDL_AUDIO_ALLOW_FREQUENCY_CHANGE|SDL_AUDIO_ALLOW_FORMAT_CHANGE|SDL_AUDIO_ALLOW_CHANNELS_CHANGE|SDL_AUDIO_ALLOW_SAMPLES_CHANGE)
 /* @} */
 
 /* @} *//* Audio flags */
@@ -527,7 +528,7 @@ extern DECLSPEC SDL_AudioStream * SDLCALL SDL_NewAudioStream(const SDL_AudioForm
  *
  *  \param stream The stream the audio data is being added to
  *  \param buf A pointer to the audio data to add
- *  \param int The number of bytes to write to the stream
+ *  \param len The number of bytes to write to the stream
  *  \return 0 on success, or -1 on error.
  *
  *  \sa SDL_NewAudioStream
diff --git a/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_bits.h b/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_bits.h
index bc2857290..eb8322f0d 100644
--- a/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_bits.h
+++ b/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_bits.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_blendmode.h b/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_blendmode.h
index 9abd0bd4c..36a5ea76f 100644
--- a/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_blendmode.h
+++ b/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_blendmode.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_clipboard.h b/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_clipboard.h
index 341f4ba42..f28751ebb 100644
--- a/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_clipboard.h
+++ b/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_clipboard.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_config.h b/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_config.h
index 1bbb83848..c58be8e72 100644
--- a/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_config.h
+++ b/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_config.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
@@ -82,6 +82,9 @@ typedef unsigned int uintptr_t;
 #define HAVE_DSOUND_H 1
 #define HAVE_DXGI_H 1
 #define HAVE_XINPUT_H 1
+#define HAVE_MMDEVICEAPI_H 1
+#define HAVE_AUDIOCLIENT_H 1
+#define HAVE_ENDPOINTVOLUME_H 1
 
 /* This is disabled by default to avoid C runtime dependencies and manifest requirements */
 #ifdef HAVE_LIBC
@@ -109,13 +112,15 @@ typedef unsigned int uintptr_t;
 #define HAVE_MEMCMP 1
 #define HAVE_STRLEN 1
 #define HAVE__STRREV 1
-#define HAVE__STRUPR 1
-#define HAVE__STRLWR 1
+/* These functions have security warnings, so we won't use them */
+/* #undef HAVE__STRUPR */
+/* #undef HAVE__STRLWR */
 #define HAVE_STRCHR 1
 #define HAVE_STRRCHR 1
 #define HAVE_STRSTR 1
-#define HAVE__LTOA 1
-#define HAVE__ULTOA 1
+/* These functions have security warnings, so we won't use them */
+/* #undef HAVE__LTOA */
+/* #undef HAVE__ULTOA */
 #define HAVE_STRTOL 1
 #define HAVE_STRTOUL 1
 #define HAVE_STRTOD 1
@@ -125,30 +130,45 @@ typedef unsigned int uintptr_t;
 #define HAVE_STRNCMP 1
 #define HAVE__STRICMP 1
 #define HAVE__STRNICMP 1
-#define HAVE_ATAN 1
-#define HAVE_ATAN2 1
-#define HAVE_ACOS  1
-#define HAVE_ASIN  1
-#define HAVE_CEIL 1
-#define HAVE_COS 1
-#define HAVE_COSF 1
-#define HAVE_FABS 1
-#define HAVE_FLOOR 1
-#define HAVE_LOG 1
-#define HAVE_POW 1
-#define HAVE_SIN 1
-#define HAVE_SINF 1
-#define HAVE_SQRT 1
-#define HAVE_SQRTF 1
-#define HAVE_TAN 1
-#define HAVE_TANF 1
-#define HAVE__COPYSIGN 1
+#define HAVE_ACOS   1
+#define HAVE_ACOSF  1
+#define HAVE_ASIN   1
+#define HAVE_ASINF  1
+#define HAVE_ATAN   1
+#define HAVE_ATANF  1
+#define HAVE_ATAN2  1
+#define HAVE_ATAN2F 1
+#define HAVE_CEILF  1
+#define HAVE__COPYSIGN  1
+#define HAVE_COS    1
+#define HAVE_COSF   1
+#define HAVE_EXP    1
+#define HAVE_EXPF   1
+#define HAVE_FABS   1
+#define HAVE_FABSF  1
+#define HAVE_FLOOR  1
+#define HAVE_FLOORF 1
+#define HAVE_FMOD   1
+#define HAVE_FMODF  1
+#define HAVE_LOG    1
+#define HAVE_LOGF   1
+#define HAVE_LOG10  1
+#define HAVE_LOG10F 1
+#define HAVE_POW    1
+#define HAVE_POWF   1
+#define HAVE_SIN    1
+#define HAVE_SINF   1
+#define HAVE_SQRT   1
+#define HAVE_SQRTF  1
+#define HAVE_TAN    1
+#define HAVE_TANF   1
 #if defined(_MSC_VER)
 /* These functions were added with the VC++ 2013 C runtime library */
 #if _MSC_VER >= 1800
 #define HAVE_STRTOLL 1
 #define HAVE_VSSCANF 1
 #define HAVE_SCALBN 1
+#define HAVE_SCALBNF    1
 #endif
 /* This function is available with at least the VC++ 2008 C runtime library */
 #if _MSC_VER >= 1400
@@ -166,7 +186,6 @@ typedef unsigned int uintptr_t;
 /* Enable various audio drivers */
 #define SDL_AUDIO_DRIVER_WASAPI 1
 #define SDL_AUDIO_DRIVER_DSOUND 1
-#define SDL_AUDIO_DRIVER_XAUDIO2    0
 #define SDL_AUDIO_DRIVER_WINMM  1
 #define SDL_AUDIO_DRIVER_DISK   1
 #define SDL_AUDIO_DRIVER_DUMMY  1
@@ -174,9 +193,13 @@ typedef unsigned int uintptr_t;
 /* Enable various input drivers */
 #define SDL_JOYSTICK_DINPUT 1
 #define SDL_JOYSTICK_XINPUT 1
+#define SDL_JOYSTICK_HIDAPI 1
 #define SDL_HAPTIC_DINPUT   1
 #define SDL_HAPTIC_XINPUT   1
 
+/* Enable the dummy sensor driver */
+#define SDL_SENSOR_DUMMY  1
+
 /* Enable various shared object loading systems */
 #define SDL_LOADSO_WINDOWS  1
 
@@ -194,7 +217,7 @@ typedef unsigned int uintptr_t;
 #define SDL_VIDEO_RENDER_D3D    1
 #endif
 #ifndef SDL_VIDEO_RENDER_D3D11
-#define SDL_VIDEO_RENDER_D3D11	0
+#define SDL_VIDEO_RENDER_D3D11  0
 #endif
 
 /* Enable OpenGL support */
diff --git a/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_cpuinfo.h b/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_cpuinfo.h
index 94b64b03b..ee3a47e84 100644
--- a/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_cpuinfo.h
+++ b/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_cpuinfo.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
@@ -51,27 +51,35 @@
 #include <intrin.h>
 #else
 #ifdef __ALTIVEC__
-#if HAVE_ALTIVEC_H && !defined(__APPLE_ALTIVEC__)
+#if defined(HAVE_ALTIVEC_H) && !defined(__APPLE_ALTIVEC__) && !defined(SDL_DISABLE_ALTIVEC_H)
 #include <altivec.h>
 #undef pixel
+#undef bool
 #endif
 #endif
-#ifdef __MMX__
-#include <mmintrin.h>
+#if defined(__ARM_NEON__) && !defined(SDL_DISABLE_ARM_NEON_H)
+#include <arm_neon.h>
 #endif
-#ifdef __3dNOW__
+#if defined(__3dNOW__) && !defined(SDL_DISABLE_MM3DNOW_H)
 #include <mm3dnow.h>
 #endif
-#ifdef __SSE__
+#if defined(HAVE_IMMINTRIN_H) && !defined(SDL_DISABLE_IMMINTRIN_H)
+#include <immintrin.h>
+#else
+#if defined(__MMX__) && !defined(SDL_DISABLE_MMINTRIN_H)
+#include <mmintrin.h>
+#endif
+#if defined(__SSE__) && !defined(SDL_DISABLE_XMMINTRIN_H)
 #include <xmmintrin.h>
 #endif
-#ifdef __SSE2__
+#if defined(__SSE2__) && !defined(SDL_DISABLE_EMMINTRIN_H)
 #include <emmintrin.h>
 #endif
-#ifdef __SSE3__
+#if defined(__SSE3__) && !defined(SDL_DISABLE_PMMINTRIN_H)
 #include <pmmintrin.h>
 #endif
-#endif
+#endif /* HAVE_IMMINTRIN_H */
+#endif /* compiler version */
 
 #include "begin_code.h"
 /* Set up for C function definitions, even when using C++ */
@@ -154,6 +162,11 @@ extern DECLSPEC SDL_bool SDLCALL SDL_HasAVX(void);
  */
 extern DECLSPEC SDL_bool SDLCALL SDL_HasAVX2(void);
 
+/**
+ *  This function returns true if the CPU has AVX-512F (foundation) features.
+ */
+extern DECLSPEC SDL_bool SDLCALL SDL_HasAVX512F(void);
+
 /**
  *  This function returns true if the CPU has NEON (ARM SIMD) features.
  */
@@ -164,7 +177,6 @@ extern DECLSPEC SDL_bool SDLCALL SDL_HasNEON(void);
  */
 extern DECLSPEC int SDLCALL SDL_GetSystemRAM(void);
 
-
 /* Ends C function definitions when using C++ */
 #ifdef __cplusplus
 }
diff --git a/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_egl.h b/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_egl.h
index e47fbe862..d65ed437c 100644
--- a/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_egl.h
+++ b/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_egl.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
@@ -24,7 +24,7 @@
  *
  *  This is a simple file to encapsulate the EGL API headers.
  */
-#ifndef _MSC_VER
+#if !defined(_MSC_VER) && !defined(__ANDROID__)
 
 #include <EGL/egl.h>
 #include <EGL/eglext.h>
diff --git a/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_endian.h b/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_endian.h
index 3eda7f287..ed0bf5ba8 100644
--- a/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_endian.h
+++ b/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_endian.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_error.h b/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_error.h
index 49be9827e..c0e46298e 100644
--- a/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_error.h
+++ b/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_error.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_events.h b/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_events.h
index 0fc09bc37..af22eb646 100644
--- a/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_events.h
+++ b/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_events.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
@@ -85,6 +85,9 @@ typedef enum
                                      Called on Android in onResume()
                                 */
 
+    /* Display events */
+    SDL_DISPLAYEVENT   = 0x150,  /**< Display state change */
+
     /* Window events */
     SDL_WINDOWEVENT    = 0x200, /**< Window state change */
     SDL_SYSWMEVENT,             /**< System specific event */
@@ -144,6 +147,9 @@ typedef enum
     SDL_AUDIODEVICEADDED = 0x1100, /**< A new audio device is available */
     SDL_AUDIODEVICEREMOVED,        /**< An audio device has been removed. */
 
+    /* Sensor events */
+    SDL_SENSORUPDATE = 0x1200,     /**< A sensor was updated */
+
     /* Render events */
     SDL_RENDER_TARGETS_RESET = 0x2000, /**< The render targets have been reset and their contents need to be updated */
     SDL_RENDER_DEVICE_RESET, /**< The device has been reset and all textures need to be recreated */
@@ -168,6 +174,21 @@ typedef struct SDL_CommonEvent
     Uint32 timestamp;   /**< In milliseconds, populated using SDL_GetTicks() */
 } SDL_CommonEvent;
 
+/**
+ *  \brief Display state change event data (event.display.*)
+ */
+typedef struct SDL_DisplayEvent
+{
+    Uint32 type;        /**< ::SDL_DISPLAYEVENT */
+    Uint32 timestamp;   /**< In milliseconds, populated using SDL_GetTicks() */
+    Uint32 display;     /**< The associated display index */
+    Uint8 event;        /**< ::SDL_DisplayEventID */
+    Uint8 padding1;
+    Uint8 padding2;
+    Uint8 padding3;
+    Sint32 data1;       /**< event dependent data */
+} SDL_DisplayEvent;
+
 /**
  *  \brief Window state change event data (event.window.*)
  */
@@ -471,6 +492,17 @@ typedef struct SDL_DropEvent
 } SDL_DropEvent;
 
 
+/**
+ *  \brief Sensor event structure (event.sensor.*)
+ */
+typedef struct SDL_SensorEvent
+{
+    Uint32 type;        /**< ::SDL_SENSORUPDATE */
+    Uint32 timestamp;   /**< In milliseconds, populated using SDL_GetTicks() */
+    Sint32 which;       /**< The instance ID of the sensor */
+    float data[6];      /**< Up to 6 values from the sensor - additional values can be queried using SDL_SensorGetData() */
+} SDL_SensorEvent;
+
 /**
  *  \brief The "quit requested" event
  */
@@ -526,6 +558,7 @@ typedef union SDL_Event
 {
     Uint32 type;                    /**< Event type, shared with all events */
     SDL_CommonEvent common;         /**< Common event data */
+    SDL_DisplayEvent display;       /**< Window event data */
     SDL_WindowEvent window;         /**< Window event data */
     SDL_KeyboardEvent key;          /**< Keyboard event data */
     SDL_TextEditingEvent edit;      /**< Text editing event data */
@@ -542,6 +575,7 @@ typedef union SDL_Event
     SDL_ControllerButtonEvent cbutton;  /**< Game Controller button event data */
     SDL_ControllerDeviceEvent cdevice;  /**< Game Controller device event data */
     SDL_AudioDeviceEvent adevice;   /**< Audio device event data */
+    SDL_SensorEvent sensor;         /**< Sensor event data */
     SDL_QuitEvent quit;             /**< Quit request event data */
     SDL_UserEvent user;             /**< Custom event data */
     SDL_SysWMEvent syswm;           /**< System dependent window event data */
diff --git a/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_filesystem.h b/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_filesystem.h
index a1c846ad0..fa6a1fa6e 100644
--- a/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_filesystem.h
+++ b/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_filesystem.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_gamecontroller.h b/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_gamecontroller.h
index c9215132e..6ae9c9542 100644
--- a/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_gamecontroller.h
+++ b/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_gamecontroller.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
@@ -175,6 +175,14 @@ extern DECLSPEC SDL_bool SDLCALL SDL_IsGameController(int joystick_index);
  */
 extern DECLSPEC const char *SDLCALL SDL_GameControllerNameForIndex(int joystick_index);
 
+/**
+ *  Get the mapping of a game controller.
+ *  This can be called before any controllers are opened.
+ *
+ *  \return the mapping string.  Must be freed with SDL_free().  Returns NULL if no mapping is available
+ */
+extern DECLSPEC char *SDLCALL SDL_GameControllerMappingForDeviceIndex(int joystick_index);
+
 /**
  *  Open a game controller for use.
  *  The index passed as an argument refers to the N'th game controller on the system.
@@ -196,6 +204,13 @@ extern DECLSPEC SDL_GameController *SDLCALL SDL_GameControllerFromInstanceID(SDL
  */
 extern DECLSPEC const char *SDLCALL SDL_GameControllerName(SDL_GameController *gamecontroller);
 
+/**
+ *  Get the player index of an opened game controller, or -1 if it's not available
+ *
+ *  For XInput controllers this returns the XInput user index.
+ */
+extern DECLSPEC int SDLCALL SDL_GameControllerGetPlayerIndex(SDL_GameController *gamecontroller);
+
 /**
  *  Get the USB vendor ID of an opened controller, if available.
  *  If the vendor ID isn't available this function returns 0.
@@ -345,6 +360,19 @@ SDL_GameControllerGetBindForButton(SDL_GameController *gamecontroller,
 extern DECLSPEC Uint8 SDLCALL SDL_GameControllerGetButton(SDL_GameController *gamecontroller,
                                                           SDL_GameControllerButton button);
 
+/**
+ *  Trigger a rumble effect
+ *  Each call to this function cancels any previous rumble effect, and calling it with 0 intensity stops any rumbling.
+ *
+ *  \param gamecontroller The controller to vibrate
+ *  \param low_frequency_rumble The intensity of the low frequency (left) rumble motor, from 0 to 0xFFFF
+ *  \param high_frequency_rumble The intensity of the high frequency (right) rumble motor, from 0 to 0xFFFF
+ *  \param duration_ms The duration of the rumble effect, in milliseconds
+ *
+ *  \return 0, or -1 if rumble isn't supported on this joystick
+ */
+extern DECLSPEC int SDLCALL SDL_GameControllerRumble(SDL_GameController *gamecontroller, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble, Uint32 duration_ms);
+
 /**
  *  Close a controller previously opened with SDL_GameControllerOpen().
  */
diff --git a/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_gesture.h b/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_gesture.h
index 2bba6a729..b223d80d4 100644
--- a/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_gesture.h
+++ b/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_gesture.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_haptic.h b/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_haptic.h
index 60daefaa7..2ea1bfc16 100644
--- a/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_haptic.h
+++ b/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_haptic.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
@@ -117,6 +117,17 @@
 extern "C" {
 #endif /* __cplusplus */
 
+/* FIXME: For SDL 2.1, adjust all the magnitude variables to be Uint16 (0xFFFF).
+ *
+ * At the moment the magnitude variables are mixed between signed/unsigned, and
+ * it is also not made clear that ALL of those variables expect a max of 0x7FFF.
+ *
+ * Some platforms may have higher precision than that (Linux FF, Windows XInput)
+ * so we should fix the inconsistency in favor of higher possible precision,
+ * adjusting for platforms that use different scales.
+ * -flibit
+ */
+
 /**
  *  \typedef SDL_Haptic
  *
@@ -656,8 +667,8 @@ typedef struct SDL_HapticRamp
  * This struct is exclusively for the ::SDL_HAPTIC_LEFTRIGHT effect.
  *
  * The Left/Right effect is used to explicitly control the large and small
- * motors, commonly found in modern game controllers. One motor is high
- * frequency, the other is low frequency.
+ * motors, commonly found in modern game controllers. The small (right) motor
+ * is high frequency, and the large (left) motor is low frequency.
  *
  * \sa SDL_HAPTIC_LEFTRIGHT
  * \sa SDL_HapticEffect
@@ -668,7 +679,7 @@ typedef struct SDL_HapticLeftRight
     Uint16 type;            /**< ::SDL_HAPTIC_LEFTRIGHT */
 
     /* Replay */
-    Uint32 length;          /**< Duration of the effect. */
+    Uint32 length;          /**< Duration of the effect in milliseconds. */
 
     /* Rumble */
     Uint16 large_magnitude; /**< Control of the large controller motor. */
diff --git a/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_hints.h b/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_hints.h
index 007a4bee0..4ee72e97d 100644
--- a/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_hints.h
+++ b/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_hints.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
@@ -76,6 +76,7 @@ extern "C" {
  *    "opengl"
  *    "opengles2"
  *    "opengles"
+ *    "metal"
  *    "software"
  *
  *  The default varies by platform, but it's the first one in the list that
@@ -210,6 +211,18 @@ extern "C" {
  */
 #define SDL_HINT_VIDEO_X11_NET_WM_PING      "SDL_VIDEO_X11_NET_WM_PING"
 
+/**
+ * \brief A variable controlling whether the X11 _NET_WM_BYPASS_COMPOSITOR hint should be used.
+ * 
+ * This variable can be set to the following values:
+ * "0" - Disable _NET_WM_BYPASS_COMPOSITOR
+ * "1" - Enable _NET_WM_BYPASS_COMPOSITOR
+ * 
+ * By default SDL will use _NET_WM_BYPASS_COMPOSITOR
+ * 
+ */
+#define SDL_HINT_VIDEO_X11_NET_WM_BYPASS_COMPOSITOR "SDL_VIDEO_X11_NET_WM_BYPASS_COMPOSITOR"
+
 /**
  *  \brief  A variable controlling whether the window frame and title bar are interactive when the cursor is hidden 
  *
@@ -249,6 +262,16 @@ extern "C" {
  */
 #define SDL_HINT_GRAB_KEYBOARD              "SDL_GRAB_KEYBOARD"
 
+/**
+ *  \brief  A variable setting the double click time, in milliseconds.
+ */
+#define SDL_HINT_MOUSE_DOUBLE_CLICK_TIME    "SDL_MOUSE_DOUBLE_CLICK_TIME"
+
+/**
+ *  \brief  A variable setting the double click radius, in pixels.
+ */
+#define SDL_HINT_MOUSE_DOUBLE_CLICK_RADIUS    "SDL_MOUSE_DOUBLE_CLICK_RADIUS"
+
 /**
  *  \brief  A variable setting the speed scale for mouse motion, in floating point, when the mouse is not in relative mode
  */
@@ -316,7 +339,7 @@ extern "C" {
 #define SDL_HINT_IDLE_TIMER_DISABLED "SDL_IOS_IDLE_TIMER_DISABLED"
 
 /**
- *  \brief  A variable controlling which orientations are allowed on iOS.
+ *  \brief  A variable controlling which orientations are allowed on iOS/Android.
  *
  *  In some circumstances it is necessary to be able to explicitly control
  *  which UI orientations are allowed.
@@ -355,16 +378,36 @@ extern "C" {
 #define SDL_HINT_APPLE_TV_REMOTE_ALLOW_ROTATION "SDL_APPLE_TV_REMOTE_ALLOW_ROTATION"
 
 /**
- *  \brief  A variable controlling whether the Android / iOS built-in
- *  accelerometer should be listed as a joystick device, rather than listing
- *  actual joysticks only.
+ * \brief  A variable controlling whether the home indicator bar on iPhone X
+ *         should be hidden.
  *
  *  This variable can be set to the following values:
- *    "0"       - List only real joysticks and accept input from them
- *    "1"       - List real joysticks along with the accelerometer as if it were a 3 axis joystick (the default).
+ *    "0"       - The indicator bar is not hidden (default for windowed applications)
+ *    "1"       - The indicator bar is hidden and is shown when the screen is touched (useful for movie playback applications)
+ *    "2"       - The indicator bar is dim and the first swipe makes it visible and the second swipe performs the "home" action (default for fullscreen applications)
+ */
+#define SDL_HINT_IOS_HIDE_HOME_INDICATOR "SDL_IOS_HIDE_HOME_INDICATOR"
+
+/**
+ *  \brief  A variable controlling whether the Android / iOS built-in
+ *  accelerometer should be listed as a joystick device.
+ *
+ *  This variable can be set to the following values:
+ *    "0"       - The accelerometer is not listed as a joystick
+ *    "1"       - The accelerometer is available as a 3 axis joystick (the default).
  */
 #define SDL_HINT_ACCELEROMETER_AS_JOYSTICK "SDL_ACCELEROMETER_AS_JOYSTICK"
 
+/**
+ *  \brief  A variable controlling whether the Android / tvOS remotes
+ *  should be listed as joystick devices, instead of sending keyboard events.
+ *
+ *  This variable can be set to the following values:
+ *    "0"       - Remotes send enter/escape/arrow key events
+ *    "1"       - Remotes are available as 2 axis, 2 button joysticks (the default).
+ */
+#define SDL_HINT_TV_REMOTE_AS_JOYSTICK "SDL_TV_REMOTE_AS_JOYSTICK"
+
 /**
  *  \brief  A variable that lets you disable the detection and use of Xinput gamepad devices
  *
@@ -432,6 +475,88 @@ extern "C" {
  */
 #define SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS "SDL_JOYSTICK_ALLOW_BACKGROUND_EVENTS"
 
+/**
+ *  \brief  A variable controlling whether the HIDAPI joystick drivers should be used.
+ *
+ *  This variable can be set to the following values:
+ *    "0"       - HIDAPI drivers are not used
+ *    "1"       - HIDAPI drivers are used (the default)
+ *
+ *  This variable is the default for all drivers, but can be overridden by the hints for specific drivers below.
+ */
+#define SDL_HINT_JOYSTICK_HIDAPI "SDL_JOYSTICK_HIDAPI"
+
+/**
+ *  \brief  A variable controlling whether the HIDAPI driver for PS4 controllers should be used.
+ *
+ *  This variable can be set to the following values:
+ *    "0"       - HIDAPI driver is not used
+ *    "1"       - HIDAPI driver is used
+ *
+ *  The default is the value of SDL_HINT_JOYSTICK_HIDAPI
+ */
+#define SDL_HINT_JOYSTICK_HIDAPI_PS4 "SDL_JOYSTICK_HIDAPI_PS4"
+
+/**
+ *  \brief  A variable controlling whether extended input reports should be used for PS4 controllers when using the HIDAPI driver.
+ *
+ *  This variable can be set to the following values:
+ *    "0"       - extended reports are not enabled (the default)
+ *    "1"       - extended reports
+ *
+ *  Extended input reports allow rumble on Bluetooth PS4 controllers, but
+ *  break DirectInput handling for applications that don't use SDL.
+ *
+ *  Once extended reports are enabled, they can not be disabled without
+ *  power cycling the controller.
+ */
+#define SDL_HINT_JOYSTICK_HIDAPI_PS4_RUMBLE "SDL_JOYSTICK_HIDAPI_PS4_RUMBLE"
+
+/**
+ *  \brief  A variable controlling whether the HIDAPI driver for Steam Controllers should be used.
+ *
+ *  This variable can be set to the following values:
+ *    "0"       - HIDAPI driver is not used
+ *    "1"       - HIDAPI driver is used
+ *
+ *  The default is the value of SDL_HINT_JOYSTICK_HIDAPI
+ */
+#define SDL_HINT_JOYSTICK_HIDAPI_STEAM "SDL_JOYSTICK_HIDAPI_STEAM"
+
+/**
+ *  \brief  A variable controlling whether the HIDAPI driver for Nintendo Switch controllers should be used.
+ *
+ *  This variable can be set to the following values:
+ *    "0"       - HIDAPI driver is not used
+ *    "1"       - HIDAPI driver is used
+ *
+ *  The default is the value of SDL_HINT_JOYSTICK_HIDAPI
+ */
+#define SDL_HINT_JOYSTICK_HIDAPI_SWITCH "SDL_JOYSTICK_HIDAPI_SWITCH"
+
+/**
+ *  \brief  A variable controlling whether the HIDAPI driver for XBox controllers should be used.
+ *
+ *  This variable can be set to the following values:
+ *    "0"       - HIDAPI driver is not used
+ *    "1"       - HIDAPI driver is used
+ *
+ *  The default is the value of SDL_HINT_JOYSTICK_HIDAPI
+ */
+#define SDL_HINT_JOYSTICK_HIDAPI_XBOX   "SDL_JOYSTICK_HIDAPI_XBOX"
+
+/**
+ *  \brief  A variable that controls whether Steam Controllers should be exposed using the SDL joystick and game controller APIs
+ *
+ *  The variable can be set to the following values:
+ *    "0"       - Do not scan for Steam Controllers
+ *    "1"       - Scan for Steam Controllers (the default)
+ *
+ *  The default value is "1".  This hint must be set before initializing the joystick subsystem.
+ */
+#define SDL_HINT_ENABLE_STEAM_CONTROLLERS "SDL_ENABLE_STEAM_CONTROLLERS"
+
+
 /**
  *  \brief If set to "0" then never set the top most bit on a SDL Window, even if the video mode expects it.
  *      This is a debugging aid for developers and not expected to be used by end users. The default is "1"
@@ -494,6 +619,10 @@ extern "C" {
 *  This is specially useful if you build SDL against a non glibc libc library (such as musl) which
 *  provides a relatively small default thread stack size (a few kilobytes versus the default 8MB glibc uses).
 *  Support for this hint is currently available only in the pthread, Windows, and PSP backend.
+*
+*  Instead of this hint, in 2.0.9 and later, you can use
+*  SDL_CreateThreadWithStackSize(). This hint only works with the classic
+*  SDL_CreateThread().
 */
 #define SDL_HINT_THREAD_STACK_SIZE              "SDL_THREAD_STACK_SIZE"
 
@@ -719,6 +848,35 @@ extern "C" {
  */
 #define SDL_HINT_ANDROID_SEPARATE_MOUSE_AND_TOUCH "SDL_ANDROID_SEPARATE_MOUSE_AND_TOUCH"
 
+ /**
+ * \brief A variable to control whether we trap the Android back button to handle it manually.
+ *        This is necessary for the right mouse button to work on some Android devices, or
+ *        to be able to trap the back button for use in your code reliably.  If set to true,
+ *        the back button will show up as an SDL_KEYDOWN / SDL_KEYUP pair with a keycode of 
+ *        SDL_SCANCODE_AC_BACK.
+ *
+ * The variable can be set to the following values:
+ *   "0"       - Back button will be handled as usual for system. (default)
+ *   "1"       - Back button will be trapped, allowing you to handle the key press
+ *               manually.  (This will also let right mouse click work on systems 
+ *               where the right mouse button functions as back.)
+ *
+ * The value of this hint is used at runtime, so it can be changed at any time.
+ */
+#define SDL_HINT_ANDROID_TRAP_BACK_BUTTON "SDL_ANDROID_TRAP_BACK_BUTTON"
+
+ /**
+ * \brief A variable to control whether the return key on the soft keyboard
+ *        should hide the soft keyboard on Android and iOS.
+ *
+ * The variable can be set to the following values:
+ *   "0"       - The return key will be handled as a key event. This is the behaviour of SDL <= 2.0.3. (default)
+ *   "1"       - The return key will hide the keyboard.
+ *
+ * The value of this hint is used at runtime, so it can be changed at any time.
+ */
+#define SDL_HINT_RETURN_KEY_HIDES_IME "SDL_RETURN_KEY_HIDES_IME"
+
 /**
  *  \brief override the binding element for keyboard inputs for Emscripten builds
  *
@@ -752,7 +910,7 @@ extern "C" {
  *   "0"       - SDL will generate a window-close event when it sees Alt+F4.
  *   "1"       - SDL will only do normal key handling for Alt+F4.
  */
-#define SDL_HINT_WINDOWS_NO_CLOSE_ON_ALT_F4	"SDL_WINDOWS_NO_CLOSE_ON_ALT_F4"
+#define SDL_HINT_WINDOWS_NO_CLOSE_ON_ALT_F4 "SDL_WINDOWS_NO_CLOSE_ON_ALT_F4"
 
 /**
  *  \brief Prevent SDL from using version 4 of the bitmap header when saving BMPs.
@@ -797,6 +955,24 @@ extern "C" {
  */
 #define SDL_HINT_RPI_VIDEO_LAYER           "SDL_RPI_VIDEO_LAYER"
 
+/**
+ * \brief Tell the video driver that we only want a double buffer.
+ *
+ * By default, most lowlevel 2D APIs will use a triple buffer scheme that 
+ * wastes no CPU time on waiting for vsync after issuing a flip, but
+ * introduces a frame of latency. On the other hand, using a double buffer
+ * scheme instead is recommended for cases where low latency is an important
+ * factor because we save a whole frame of latency.
+ * We do so by waiting for vsync immediately after issuing a flip, usually just
+ * after eglSwapBuffers call in the backend's *_SwapWindow function.
+ *
+ * Since it's driver-specific, it's only supported where possible and
+ * implemented. Currently supported the following drivers:
+ * - KMSDRM (kmsdrm)
+ * - Raspberry Pi (raspberrypi)
+ */
+#define SDL_HINT_VIDEO_DOUBLE_BUFFER      "SDL_VIDEO_DOUBLE_BUFFER"
+
 /**
  *  \brief  A variable controlling what driver to use for OpenGL ES contexts.
  *
diff --git a/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_joystick.h b/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_joystick.h
index f598dc828..6e05a9c20 100644
--- a/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_joystick.h
+++ b/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_joystick.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
@@ -97,10 +97,10 @@ typedef enum
 typedef enum
 {
     SDL_JOYSTICK_POWER_UNKNOWN = -1,
-    SDL_JOYSTICK_POWER_EMPTY,
-    SDL_JOYSTICK_POWER_LOW,
-    SDL_JOYSTICK_POWER_MEDIUM,
-    SDL_JOYSTICK_POWER_FULL,
+    SDL_JOYSTICK_POWER_EMPTY,   /* <= 5% */
+    SDL_JOYSTICK_POWER_LOW,     /* <= 20% */
+    SDL_JOYSTICK_POWER_MEDIUM,  /* <= 70% */
+    SDL_JOYSTICK_POWER_FULL,    /* <= 100% */
     SDL_JOYSTICK_POWER_WIRED,
     SDL_JOYSTICK_POWER_MAX
 } SDL_JoystickPowerLevel;
@@ -132,6 +132,12 @@ extern DECLSPEC int SDLCALL SDL_NumJoysticks(void);
  */
 extern DECLSPEC const char *SDLCALL SDL_JoystickNameForIndex(int device_index);
 
+/**
+ *  Get the player index of a joystick, or -1 if it's not available
+ *  This can be called before any joysticks are opened.
+ */
+extern DECLSPEC int SDLCALL SDL_JoystickGetDevicePlayerIndex(int device_index);
+
 /**
  *  Return the GUID for the joystick at this index
  *  This can be called before any joysticks are opened.
@@ -194,6 +200,13 @@ extern DECLSPEC SDL_Joystick *SDLCALL SDL_JoystickFromInstanceID(SDL_JoystickID
  */
 extern DECLSPEC const char *SDLCALL SDL_JoystickName(SDL_Joystick * joystick);
 
+/**
+ *  Get the player index of an opened joystick, or -1 if it's not available
+ *
+ *  For XInput controllers this returns the XInput user index.
+ */
+extern DECLSPEC int SDLCALL SDL_JoystickGetPlayerIndex(SDL_Joystick * joystick);
+
 /**
  *  Return the GUID for this opened joystick
  */
@@ -361,6 +374,19 @@ extern DECLSPEC int SDLCALL SDL_JoystickGetBall(SDL_Joystick * joystick,
 extern DECLSPEC Uint8 SDLCALL SDL_JoystickGetButton(SDL_Joystick * joystick,
                                                     int button);
 
+/**
+ *  Trigger a rumble effect
+ *  Each call to this function cancels any previous rumble effect, and calling it with 0 intensity stops any rumbling.
+ *
+ *  \param joystick The joystick to vibrate
+ *  \param low_frequency_rumble The intensity of the low frequency (left) rumble motor, from 0 to 0xFFFF
+ *  \param high_frequency_rumble The intensity of the high frequency (right) rumble motor, from 0 to 0xFFFF
+ *  \param duration_ms The duration of the rumble effect, in milliseconds
+ *
+ *  \return 0, or -1 if rumble isn't supported on this joystick
+ */
+extern DECLSPEC int SDLCALL SDL_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble, Uint32 duration_ms);
+
 /**
  *  Close a joystick previously opened with SDL_JoystickOpen().
  */
diff --git a/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_keyboard.h b/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_keyboard.h
index e78ca4690..874823171 100644
--- a/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_keyboard.h
+++ b/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_keyboard.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_keycode.h b/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_keycode.h
index c41e45ff6..d7d5b1dbc 100644
--- a/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_keycode.h
+++ b/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_keycode.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_loadso.h b/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_loadso.h
index 6ea256c6a..da56fb452 100644
--- a/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_loadso.h
+++ b/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_loadso.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_log.h b/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_log.h
index 356d0e1cf..e12b65886 100644
--- a/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_log.h
+++ b/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_log.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_main.h b/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_main.h
index 2af32360f..98558217f 100644
--- a/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_main.h
+++ b/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_main.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
@@ -63,10 +63,13 @@
 /* On Android SDL provides a Java class in SDLActivity.java that is the
    main activity entry point.
 
-   See README-android.md for more details on extending that class.
+   See docs/README-android.md for more details on extending that class.
  */
 #define SDL_MAIN_NEEDED
 
+/* We need to export SDL_main so it can be launched from Java */
+#define SDLMAIN_DECLSPEC    DECLSPEC
+
 #elif defined(__NACL__)
 /* On NACL we use ppapi_simple to set up the application helper code,
    then wait for the first PSE_INSTANCE_DIDCHANGEVIEW event before 
@@ -85,6 +88,10 @@
 #define C_LINKAGE
 #endif /* __cplusplus */
 
+#ifndef SDLMAIN_DECLSPEC
+#define SDLMAIN_DECLSPEC
+#endif
+
 /**
  *  \file SDL_main.h
  *
@@ -107,7 +114,7 @@
 /**
  *  The prototype for the application's main() function
  */
-extern C_LINKAGE DECLSPEC int SDL_main(int argc, char *argv[]);
+extern C_LINKAGE SDLMAIN_DECLSPEC int SDL_main(int argc, char *argv[]);
 
 
 #include "begin_code.h"
diff --git a/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_messagebox.h b/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_messagebox.h
index c326d8f01..b7be59d88 100644
--- a/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_messagebox.h
+++ b/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_messagebox.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_mouse.h b/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_mouse.h
index 6001bd46c..d3c9f6156 100644
--- a/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_mouse.h
+++ b/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_mouse.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_mutex.h b/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_mutex.h
index 0272379e5..ba4247ced 100644
--- a/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_mutex.h
+++ b/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_mutex.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_name.h b/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_name.h
index 8095ed3ff..ecd863f4c 100644
--- a/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_name.h
+++ b/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_name.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_opengl.h b/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_opengl.h
index 314dd57ed..253d9c93a 100644
--- a/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_opengl.h
+++ b/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_opengl.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_opengles.h b/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_opengles.h
index 800c59307..18dd984b3 100644
--- a/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_opengles.h
+++ b/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_opengles.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_opengles2.h b/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_opengles2.h
index 102f2f3fa..6ccecf216 100644
--- a/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_opengles2.h
+++ b/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_opengles2.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_pixels.h b/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_pixels.h
index 04246689f..0b4364b18 100644
--- a/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_pixels.h
+++ b/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_pixels.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
@@ -287,7 +287,9 @@ enum
     SDL_PIXELFORMAT_NV12 =      /**< Planar mode: Y + U/V interleaved  (2 planes) */
         SDL_DEFINE_PIXELFOURCC('N', 'V', '1', '2'),
     SDL_PIXELFORMAT_NV21 =      /**< Planar mode: Y + V/U interleaved  (2 planes) */
-        SDL_DEFINE_PIXELFOURCC('N', 'V', '2', '1')
+        SDL_DEFINE_PIXELFOURCC('N', 'V', '2', '1'),
+    SDL_PIXELFORMAT_EXTERNAL_OES =      /**< Android video texture format */
+        SDL_DEFINE_PIXELFOURCC('O', 'E', 'S', ' ')
 };
 
 typedef struct SDL_Color
diff --git a/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_platform.h b/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_platform.h
index 9dde385fa..7dea4ce94 100644
--- a/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_platform.h
+++ b/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_platform.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
@@ -121,7 +121,12 @@
 #if defined(WIN32) || defined(_WIN32) || defined(__CYGWIN__) || defined(__MINGW32__)
 /* Try to find out if we're compiling for WinRT or non-WinRT */
 #if defined(_MSC_VER) && defined(__has_include)
-#define HAVE_WINAPIFAMILY_H __has_include(<winapifamily.h>)
+#if __has_include(<winapifamily.h>)
+#define HAVE_WINAPIFAMILY_H 1
+#else
+#define HAVE_WINAPIFAMILY_H 0
+#endif
+
 /* If _USING_V110_SDK71_ is defined it means we are using the Windows XP toolset. */
 #elif defined(_MSC_VER) && (_MSC_VER >= 1700 && !_USING_V110_SDK71_)    /* _MSC_VER == 1700 for Visual Studio 2012 */
 #define HAVE_WINAPIFAMILY_H 1
diff --git a/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_power.h b/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_power.h
index d48e8a379..a4fe8a935 100644
--- a/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_power.h
+++ b/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_power.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_quit.h b/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_quit.h
index 9283c3810..fea56a8d8 100644
--- a/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_quit.h
+++ b/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_quit.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_rect.h b/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_rect.h
index c4f6d74b3..543bb6186 100644
--- a/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_rect.h
+++ b/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_rect.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_render.h b/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_render.h
index ea6ef9ff6..d33619297 100644
--- a/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_render.h
+++ b/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_render.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
@@ -898,6 +898,27 @@ extern DECLSPEC int SDLCALL SDL_GL_BindTexture(SDL_Texture *texture, float *texw
  */
 extern DECLSPEC int SDLCALL SDL_GL_UnbindTexture(SDL_Texture *texture);
 
+/**
+ *  \brief Get the CAMetalLayer associated with the given Metal renderer
+ *
+ *  \param renderer The renderer to query
+ *
+ *  \return CAMetalLayer* on success, or NULL if the renderer isn't a Metal renderer
+ *
+ *  \sa SDL_RenderGetMetalCommandEncoder()
+ */
+extern DECLSPEC void *SDLCALL SDL_RenderGetMetalLayer(SDL_Renderer * renderer);
+
+/**
+ *  \brief Get the Metal command encoder for the current frame
+ *
+ *  \param renderer The renderer to query
+ *
+ *  \return id<MTLRenderCommandEncoder> on success, or NULL if the renderer isn't a Metal renderer
+ *
+ *  \sa SDL_RenderGetMetalLayer()
+ */
+extern DECLSPEC void *SDLCALL SDL_RenderGetMetalCommandEncoder(SDL_Renderer * renderer);
 
 /* Ends C function definitions when using C++ */
 #ifdef __cplusplus
diff --git a/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_revision.h b/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_revision.h
index 9376093ee..92fbe67b1 100644
--- a/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_revision.h
+++ b/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_revision.h
@@ -1,2 +1,2 @@
-#define SDL_REVISION "hg-11645:2088cd828335"
-#define SDL_REVISION_NUMBER 11645
+#define SDL_REVISION "hg-12373:8feb5da6f2fb"
+#define SDL_REVISION_NUMBER 12373
diff --git a/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_rwops.h b/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_rwops.h
index 7f0cbdfd5..0960699d4 100644
--- a/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_rwops.h
+++ b/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_rwops.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_scancode.h b/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_scancode.h
index 1d5521204..63871aa3b 100644
--- a/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_scancode.h
+++ b/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_scancode.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_sensor.h b/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_sensor.h
new file mode 100644
index 000000000..ac163a8cd
--- /dev/null
+++ b/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_sensor.h
@@ -0,0 +1,251 @@
+/*
+  Simple DirectMedia Layer
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+  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 SDL_sensor.h
+ *
+ *  Include file for SDL sensor event handling
+ *
+ */
+
+#ifndef _SDL_sensor_h
+#define _SDL_sensor_h
+
+#include "SDL_stdinc.h"
+#include "SDL_error.h"
+
+#include "begin_code.h"
+/* Set up for C function definitions, even when using C++ */
+#ifdef __cplusplus
+/* *INDENT-OFF* */
+extern "C" {
+/* *INDENT-ON* */
+#endif
+
+/**
+ *  \brief SDL_sensor.h
+ *
+ *  In order to use these functions, SDL_Init() must have been called
+ *  with the ::SDL_INIT_SENSOR flag.  This causes SDL to scan the system
+ *  for sensors, and load appropriate drivers.
+ */
+
+struct _SDL_Sensor;
+typedef struct _SDL_Sensor SDL_Sensor;
+
+/**
+ * This is a unique ID for a sensor for the time it is connected to the system,
+ * and is never reused for the lifetime of the application.
+ *
+ * The ID value starts at 0 and increments from there. The value -1 is an invalid ID.
+ */
+typedef Sint32 SDL_SensorID;
+
+/* The different sensors defined by SDL
+ *
+ * Additional sensors may be available, using platform dependent semantics.
+ *
+ * Hare are the additional Android sensors:
+ * https://developer.android.com/reference/android/hardware/SensorEvent.html#values
+ */
+typedef enum
+{
+    SDL_SENSOR_INVALID = -1,    /**< Returned for an invalid sensor */
+    SDL_SENSOR_UNKNOWN,         /**< Unknown sensor type */
+    SDL_SENSOR_ACCEL,           /**< Accelerometer */
+    SDL_SENSOR_GYRO             /**< Gyroscope */
+} SDL_SensorType;
+
+/**
+ * Accelerometer sensor
+ *
+ * The accelerometer returns the current acceleration in SI meters per
+ * second squared. This includes gravity, so a device at rest will have
+ * an acceleration of SDL_STANDARD_GRAVITY straight down.
+ *
+ * values[0]: Acceleration on the x axis
+ * values[1]: Acceleration on the y axis
+ * values[2]: Acceleration on the z axis
+ *
+ * For phones held in portrait mode, the axes are defined as follows:
+ * -X ... +X : left ... right
+ * -Y ... +Y : bottom ... top
+ * -Z ... +Z : farther ... closer
+ * 
+ * The axis data is not changed when the phone is rotated.
+ *
+ * \sa SDL_GetDisplayOrientation()
+ */
+#define SDL_STANDARD_GRAVITY    9.80665f
+
+/**
+ * Gyroscope sensor
+ *
+ * The gyroscope returns the current rate of rotation in radians per second.
+ * The rotation is positive in the counter-clockwise direction. That is,
+ * an observer looking from a positive location on one of the axes would
+ * see positive rotation on that axis when it appeared to be rotating
+ * counter-clockwise.
+ *
+ * values[0]: Angular speed around the x axis
+ * values[1]: Angular speed around the y axis
+ * values[2]: Angular speed around the z axis
+ *
+ * For phones held in portrait mode, the axes are defined as follows:
+ * -X ... +X : left ... right
+ * -Y ... +Y : bottom ... top
+ * -Z ... +Z : farther ... closer
+ * 
+ * The axis data is not changed when the phone is rotated.
+ *
+ * \sa SDL_GetDisplayOrientation()
+ */
+
+/* Function prototypes */
+
+/**
+ *  \brief Count the number of sensors attached to the system right now
+ */
+extern DECLSPEC int SDLCALL SDL_NumSensors(void);
+
+/**
+ *  \brief Get the implementation dependent name of a sensor.
+ *
+ *  This can be called before any sensors are opened.
+ * 
+ *  \return The sensor name, or NULL if device_index is out of range.
+ */
+extern DECLSPEC const char *SDLCALL SDL_SensorGetDeviceName(int device_index);
+
+/**
+ *  \brief Get the type of a sensor.
+ *
+ *  This can be called before any sensors are opened.
+ *
+ *  \return The sensor type, or SDL_SENSOR_INVALID if device_index is out of range.
+ */
+extern DECLSPEC SDL_SensorType SDLCALL SDL_SensorGetDeviceType(int device_index);
+
+/**
+ *  \brief Get the platform dependent type of a sensor.
+ *
+ *  This can be called before any sensors are opened.
+ *
+ *  \return The sensor platform dependent type, or -1 if device_index is out of range.
+ */
+extern DECLSPEC int SDLCALL SDL_SensorGetDeviceNonPortableType(int device_index);
+
+/**
+ *  \brief Get the instance ID of a sensor.
+ *
+ *  This can be called before any sensors are opened.
+ *
+ *  \return The sensor instance ID, or -1 if device_index is out of range.
+ */
+extern DECLSPEC SDL_SensorID SDLCALL SDL_SensorGetDeviceInstanceID(int device_index);
+
+/**
+ *  \brief Open a sensor for use.
+ *
+ *  The index passed as an argument refers to the N'th sensor on the system.
+ *
+ *  \return A sensor identifier, or NULL if an error occurred.
+ */
+extern DECLSPEC SDL_Sensor *SDLCALL SDL_SensorOpen(int device_index);
+
+/**
+ * Return the SDL_Sensor associated with an instance id.
+ */
+extern DECLSPEC SDL_Sensor *SDLCALL SDL_SensorFromInstanceID(SDL_SensorID instance_id);
+
+/**
+ *  \brief Get the implementation dependent name of a sensor.
+ *
+ *  \return The sensor name, or NULL if the sensor is NULL.
+ */
+extern DECLSPEC const char *SDLCALL SDL_SensorGetName(SDL_Sensor *sensor);
+
+/**
+ *  \brief Get the type of a sensor.
+ *
+ *  This can be called before any sensors are opened.
+ *
+ *  \return The sensor type, or SDL_SENSOR_INVALID if the sensor is NULL.
+ */
+extern DECLSPEC SDL_SensorType SDLCALL SDL_SensorGetType(SDL_Sensor *sensor);
+
+/**
+ *  \brief Get the platform dependent type of a sensor.
+ *
+ *  This can be called before any sensors are opened.
+ *
+ *  \return The sensor platform dependent type, or -1 if the sensor is NULL.
+ */
+extern DECLSPEC int SDLCALL SDL_SensorGetNonPortableType(SDL_Sensor *sensor);
+
+/**
+ *  \brief Get the instance ID of a sensor.
+ *
+ *  This can be called before any sensors are opened.
+ *
+ *  \return The sensor instance ID, or -1 if the sensor is NULL.
+ */
+extern DECLSPEC SDL_SensorID SDLCALL SDL_SensorGetInstanceID(SDL_Sensor *sensor);
+
+/**
+ *  Get the current state of an opened sensor.
+ *
+ *  The number of values and interpretation of the data is sensor dependent.
+ *
+ *  \param sensor The sensor to query
+ *  \param data A pointer filled with the current sensor state
+ *  \param num_values The number of values to write to data
+ *
+ *  \return 0 or -1 if an error occurred.
+ */
+extern DECLSPEC int SDLCALL SDL_SensorGetData(SDL_Sensor * sensor, float *data, int num_values);
+
+/**
+ *  Close a sensor previously opened with SDL_SensorOpen()
+ */
+extern DECLSPEC void SDLCALL SDL_SensorClose(SDL_Sensor * sensor);
+
+/**
+ *  Update the current state of the open sensors.
+ *
+ *  This is called automatically by the event loop if sensor events are enabled.
+ *
+ *  This needs to be called from the thread that initialized the sensor subsystem.
+ */
+extern DECLSPEC void SDLCALL SDL_SensorUpdate(void);
+
+
+/* Ends C function definitions when using C++ */
+#ifdef __cplusplus
+/* *INDENT-OFF* */
+}
+/* *INDENT-ON* */
+#endif
+#include "close_code.h"
+
+#endif /* _SDL_sensor_h */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_shape.h b/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_shape.h
index 9e492d93a..40a6baaae 100644
--- a/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_shape.h
+++ b/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_shape.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_stdinc.h b/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_stdinc.h
index 72402299f..e373bc380 100644
--- a/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_stdinc.h
+++ b/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_stdinc.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
@@ -86,6 +86,28 @@
 #ifdef HAVE_FLOAT_H
 # include <float.h>
 #endif
+#if defined(HAVE_ALLOCA) && !defined(alloca)
+# if defined(HAVE_ALLOCA_H)
+#  include <alloca.h>
+# elif defined(__GNUC__)
+#  define alloca __builtin_alloca
+# elif defined(_MSC_VER)
+#  include <malloc.h>
+#  define alloca _alloca
+# elif defined(__WATCOMC__)
+#  include <malloc.h>
+# elif defined(__BORLANDC__)
+#  include <malloc.h>
+# elif defined(__DMC__)
+#  include <stdlib.h>
+# elif defined(__AIX__)
+#pragma alloca
+# elif defined(__MRC__)
+void *alloca(unsigned);
+# else
+char *alloca();
+# endif
+#endif
 
 /**
  *  The number of elements in an array.
@@ -328,28 +350,6 @@ SDL_COMPILE_TIME_ASSERT(enum, sizeof(SDL_DUMMY_ENUM) == sizeof(int));
 extern "C" {
 #endif
 
-#if defined(HAVE_ALLOCA) && !defined(alloca)
-# if defined(HAVE_ALLOCA_H)
-#  include <alloca.h>
-# elif defined(__GNUC__)
-#  define alloca __builtin_alloca
-# elif defined(_MSC_VER)
-#  include <malloc.h>
-#  define alloca _alloca
-# elif defined(__WATCOMC__)
-#  include <malloc.h>
-# elif defined(__BORLANDC__)
-#  include <malloc.h>
-# elif defined(__DMC__)
-#  include <stdlib.h>
-# elif defined(__AIX__)
-#pragma alloca
-# elif defined(__MRC__)
-void *alloca(unsigned);
-# else
-char *alloca();
-# endif
-#endif
 #ifdef HAVE_ALLOCA
 #define SDL_stack_alloc(type, count)    (type*)alloca(sizeof(type)*(count))
 #define SDL_stack_free(data)
@@ -445,12 +445,12 @@ SDL_FORCE_INLINE void SDL_memset4(void *dst, Uint32 val, size_t dwords)
 #endif
 }
 
-
 extern DECLSPEC void *SDLCALL SDL_memcpy(SDL_OUT_BYTECAP(len) void *dst, SDL_IN_BYTECAP(len) const void *src, size_t len);
 
 extern DECLSPEC void *SDLCALL SDL_memmove(SDL_OUT_BYTECAP(len) void *dst, SDL_IN_BYTECAP(len) const void *src, size_t len);
 extern DECLSPEC int SDLCALL SDL_memcmp(const void *s1, const void *s2, size_t len);
 
+extern DECLSPEC wchar_t *SDLCALL SDL_wcsdup(const wchar_t *wstr);
 extern DECLSPEC size_t SDLCALL SDL_wcslen(const wchar_t *wstr);
 extern DECLSPEC size_t SDLCALL SDL_wcslcpy(SDL_OUT_Z_CAP(maxlen) wchar_t *dst, const wchar_t *src, size_t maxlen);
 extern DECLSPEC size_t SDLCALL SDL_wcslcat(SDL_INOUT_Z_CAP(maxlen) wchar_t *dst, const wchar_t *src, size_t maxlen);
@@ -501,18 +501,35 @@ extern DECLSPEC int SDLCALL SDL_vsnprintf(SDL_OUT_Z_CAP(maxlen) char *text, size
 #endif
 
 extern DECLSPEC double SDLCALL SDL_acos(double x);
+extern DECLSPEC float SDLCALL SDL_acosf(float x);
 extern DECLSPEC double SDLCALL SDL_asin(double x);
+extern DECLSPEC float SDLCALL SDL_asinf(float x);
 extern DECLSPEC double SDLCALL SDL_atan(double x);
+extern DECLSPEC float SDLCALL SDL_atanf(float x);
 extern DECLSPEC double SDLCALL SDL_atan2(double x, double y);
+extern DECLSPEC float SDLCALL SDL_atan2f(float x, float y);
 extern DECLSPEC double SDLCALL SDL_ceil(double x);
+extern DECLSPEC float SDLCALL SDL_ceilf(float x);
 extern DECLSPEC double SDLCALL SDL_copysign(double x, double y);
+extern DECLSPEC float SDLCALL SDL_copysignf(float x, float y);
 extern DECLSPEC double SDLCALL SDL_cos(double x);
 extern DECLSPEC float SDLCALL SDL_cosf(float x);
+extern DECLSPEC double SDLCALL SDL_exp(double x);
+extern DECLSPEC float SDLCALL SDL_expf(float x);
 extern DECLSPEC double SDLCALL SDL_fabs(double x);
+extern DECLSPEC float SDLCALL SDL_fabsf(float x);
 extern DECLSPEC double SDLCALL SDL_floor(double x);
+extern DECLSPEC float SDLCALL SDL_floorf(float x);
+extern DECLSPEC double SDLCALL SDL_fmod(double x, double y);
+extern DECLSPEC float SDLCALL SDL_fmodf(float x, float y);
 extern DECLSPEC double SDLCALL SDL_log(double x);
+extern DECLSPEC float SDLCALL SDL_logf(float x);
+extern DECLSPEC double SDLCALL SDL_log10(double x);
+extern DECLSPEC float SDLCALL SDL_log10f(float x);
 extern DECLSPEC double SDLCALL SDL_pow(double x, double y);
+extern DECLSPEC float SDLCALL SDL_powf(float x, float y);
 extern DECLSPEC double SDLCALL SDL_scalbn(double x, int n);
+extern DECLSPEC float SDLCALL SDL_scalbnf(float x, int n);
 extern DECLSPEC double SDLCALL SDL_sin(double x);
 extern DECLSPEC float SDLCALL SDL_sinf(float x);
 extern DECLSPEC double SDLCALL SDL_sqrt(double x);
diff --git a/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_surface.h b/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_surface.h
index 510690c9c..730d49fc8 100644
--- a/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_surface.h
+++ b/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_surface.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
@@ -97,6 +97,17 @@ typedef struct SDL_Surface
 typedef int (SDLCALL *SDL_blit) (struct SDL_Surface * src, SDL_Rect * srcrect,
                                  struct SDL_Surface * dst, SDL_Rect * dstrect);
 
+/**
+ * \brief The formula used for converting between YUV and RGB
+ */
+typedef enum
+{
+    SDL_YUV_CONVERSION_JPEG,        /**< Full range JPEG */
+    SDL_YUV_CONVERSION_BT601,       /**< BT.601 (the default) */
+    SDL_YUV_CONVERSION_BT709,       /**< BT.709 */
+    SDL_YUV_CONVERSION_AUTOMATIC    /**< BT.601 for SD content, BT.709 for HD content */
+} SDL_YUV_CONVERSION_MODE;
+
 /**
  *  Allocate and free an RGB surface.
  *
@@ -237,6 +248,13 @@ extern DECLSPEC int SDLCALL SDL_SetSurfaceRLE(SDL_Surface * surface,
 extern DECLSPEC int SDLCALL SDL_SetColorKey(SDL_Surface * surface,
                                             int flag, Uint32 key);
 
+/**
+ *  \brief Returns whether the surface has a color key
+ *
+ *  \return SDL_TRUE if the surface has a color key, or SDL_FALSE if the surface is NULL or has no color key
+ */
+extern DECLSPEC SDL_bool SDLCALL SDL_HasColorKey(SDL_Surface * surface);
+
 /**
  *  \brief Gets the color key (transparent pixel) in a blittable surface.
  *
@@ -509,6 +527,20 @@ extern DECLSPEC int SDLCALL SDL_LowerBlitScaled
     (SDL_Surface * src, SDL_Rect * srcrect,
     SDL_Surface * dst, SDL_Rect * dstrect);
 
+/**
+ *  \brief Set the YUV conversion mode
+ */
+extern DECLSPEC void SDLCALL SDL_SetYUVConversionMode(SDL_YUV_CONVERSION_MODE mode);
+
+/**
+ *  \brief Get the YUV conversion mode
+ */
+extern DECLSPEC SDL_YUV_CONVERSION_MODE SDLCALL SDL_GetYUVConversionMode(void);
+
+/**
+ *  \brief Get the YUV conversion mode, returning the correct mode for the resolution when the current conversion mode is SDL_YUV_CONVERSION_AUTOMATIC
+ */
+extern DECLSPEC SDL_YUV_CONVERSION_MODE SDLCALL SDL_GetYUVConversionModeForResolution(int width, int height);
 
 /* Ends C function definitions when using C++ */
 #ifdef __cplusplus
diff --git a/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_system.h b/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_system.h
index eb069b33d..4dc372d6b 100644
--- a/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_system.h
+++ b/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_system.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
@@ -76,6 +76,18 @@ extern DECLSPEC SDL_bool SDLCALL SDL_DXGIGetOutputInfo( int displayIndex, int *a
 #endif /* __WIN32__ */
 
 
+/* Platform specific functions for Linux */
+#ifdef __LINUX__
+
+/**
+   \brief Sets the UNIX nice value for a thread, using setpriority() if possible, and RealtimeKit if available.
+
+   \return 0 on success, or -1 on error.
+ */
+extern DECLSPEC int SDLCALL SDL_LinuxSetThreadPriority(Sint64 threadID, int priority);
+ 
+#endif /* __LINUX__ */
+	
 /* Platform specific functions for iOS */
 #if defined(__IPHONEOS__) && __IPHONEOS__
 
@@ -108,6 +120,26 @@ extern DECLSPEC void * SDLCALL SDL_AndroidGetJNIEnv(void);
  */
 extern DECLSPEC void * SDLCALL SDL_AndroidGetActivity(void);
 
+/**
+   \brief Return true if the application is running on Android TV
+ */
+extern DECLSPEC SDL_bool SDLCALL SDL_IsAndroidTV(void);
+
+/**
+   \brief Return true if the application is running on a Chromebook
+ */
+extern DECLSPEC SDL_bool SDLCALL SDL_IsChromebook(void);
+
+/**
+  \brief Return true is the application is running on a Samsung DeX docking station
+ */
+extern DECLSPEC SDL_bool SDLCALL SDL_IsDeXMode(void);
+
+/**
+ \brief Trigger the Android system back button behavior.
+ */
+extern DECLSPEC void SDLCALL SDL_AndroidBackButton(void);
+
 /**
    See the official Android developer guide for more information:
    http://developer.android.com/guide/topics/data/data-storage.html
@@ -169,6 +201,25 @@ typedef enum
 } SDL_WinRT_Path;
 
 
+/**
+ *  \brief WinRT Device Family
+ */
+typedef enum
+{
+    /** \brief Unknown family  */
+    SDL_WINRT_DEVICEFAMILY_UNKNOWN,
+
+    /** \brief Desktop family*/
+    SDL_WINRT_DEVICEFAMILY_DESKTOP,
+
+    /** \brief Mobile family (for example smartphone) */
+    SDL_WINRT_DEVICEFAMILY_MOBILE,
+
+    /** \brief XBox family */
+    SDL_WINRT_DEVICEFAMILY_XBOX,
+} SDL_WinRT_DeviceFamily;
+
+
 /**
  *  \brief Retrieves a WinRT defined path on the local file system
  *
@@ -203,8 +254,20 @@ extern DECLSPEC const wchar_t * SDLCALL SDL_WinRTGetFSPathUNICODE(SDL_WinRT_Path
  */
 extern DECLSPEC const char * SDLCALL SDL_WinRTGetFSPathUTF8(SDL_WinRT_Path pathType);
 
+/**
+ *  \brief Detects the device family of WinRT plattform on runtime
+ *
+ *  \return Device family
+ */
+extern DECLSPEC SDL_WinRT_DeviceFamily SDLCALL SDL_WinRTGetDeviceFamily();
+
 #endif /* __WINRT__ */
 
+/**
+ \brief Return true if the current device is a tablet.
+ */
+extern DECLSPEC SDL_bool SDLCALL SDL_IsTablet(void);
+
 /* Ends C function definitions when using C++ */
 #ifdef __cplusplus
 }
diff --git a/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_syswm.h b/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_syswm.h
index 2d18afb6c..f1c4021cc 100644
--- a/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_syswm.h
+++ b/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_syswm.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
@@ -33,12 +33,6 @@
 #include "SDL_video.h"
 #include "SDL_version.h"
 
-#include "begin_code.h"
-/* Set up for C function definitions, even when using C++ */
-#ifdef __cplusplus
-extern "C" {
-#endif
-
 /**
  *  \file SDL_syswm.h
  *
@@ -110,6 +104,12 @@ typedef void *EGLSurface;
 #include "SDL_egl.h"
 #endif
 
+#include "begin_code.h"
+/* Set up for C function definitions, even when using C++ */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 /**
  *  These are the various supported windowing subsystems
  */
diff --git a/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_test.h b/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_test.h
index f55afcb02..6cc373bf8 100644
--- a/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_test.h
+++ b/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_test.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_test_assert.h b/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_test_assert.h
index 11d836394..1788d7a20 100644
--- a/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_test_assert.h
+++ b/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_test_assert.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_test_common.h b/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_test_common.h
index 24eeb32af..be2e6b2aa 100644
--- a/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_test_common.h
+++ b/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_test_common.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_test_compare.h b/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_test_compare.h
index 9f4c4587a..c22e447d8 100644
--- a/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_test_compare.h
+++ b/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_test_compare.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_test_crc32.h b/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_test_crc32.h
index add480c34..3d235d074 100644
--- a/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_test_crc32.h
+++ b/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_test_crc32.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_test_font.h b/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_test_font.h
index 58c9f9d5e..59cbdcad6 100644
--- a/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_test_font.h
+++ b/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_test_font.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_test_fuzzer.h b/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_test_fuzzer.h
index 6cf05747a..8fcb9ebbf 100644
--- a/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_test_fuzzer.h
+++ b/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_test_fuzzer.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_test_harness.h b/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_test_harness.h
index 68c4bcb7c..8641e0a7e 100644
--- a/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_test_harness.h
+++ b/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_test_harness.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_test_images.h b/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_test_images.h
index 683d2f8a6..9c4dd5b82 100644
--- a/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_test_images.h
+++ b/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_test_images.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_test_log.h b/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_test_log.h
index 9f993fbbc..ebd44fb50 100644
--- a/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_test_log.h
+++ b/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_test_log.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_test_md5.h b/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_test_md5.h
index 67ca7d1de..0e4105768 100644
--- a/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_test_md5.h
+++ b/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_test_md5.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_test_memory.h b/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_test_memory.h
index 43b67f521..4827ae6f2 100644
--- a/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_test_memory.h
+++ b/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_test_memory.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_test_random.h b/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_test_random.h
index 2b01922c3..0eb414ff2 100644
--- a/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_test_random.h
+++ b/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_test_random.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_thread.h b/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_thread.h
index d0f6575cd..554dd0b61 100644
--- a/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_thread.h
+++ b/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_thread.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
@@ -54,12 +54,13 @@ typedef unsigned int SDL_TLSID;
 /**
  *  The SDL thread priority.
  *
- *  \note On many systems you require special privileges to set high priority.
+ *  \note On many systems you require special privileges to set high or time critical priority.
  */
 typedef enum {
     SDL_THREAD_PRIORITY_LOW,
     SDL_THREAD_PRIORITY_NORMAL,
-    SDL_THREAD_PRIORITY_HIGH
+    SDL_THREAD_PRIORITY_HIGH,
+    SDL_THREAD_PRIORITY_TIME_CRITICAL
 } SDL_ThreadPriority;
 
 /**
@@ -105,14 +106,24 @@ SDL_CreateThread(SDL_ThreadFunction fn, const char *name, void *data,
                  pfnSDL_CurrentBeginThread pfnBeginThread,
                  pfnSDL_CurrentEndThread pfnEndThread);
 
+extern DECLSPEC SDL_Thread *SDLCALL
+SDL_CreateThreadWithStackSize(int (SDLCALL * fn) (void *),
+                 const char *name, const size_t stacksize, void *data,
+                 pfnSDL_CurrentBeginThread pfnBeginThread,
+                 pfnSDL_CurrentEndThread pfnEndThread);
+
+
 /**
  *  Create a thread.
  */
 #if defined(SDL_CreateThread) && SDL_DYNAMIC_API
 #undef SDL_CreateThread
 #define SDL_CreateThread(fn, name, data) SDL_CreateThread_REAL(fn, name, data, (pfnSDL_CurrentBeginThread)_beginthreadex, (pfnSDL_CurrentEndThread)_endthreadex)
+#undef SDL_CreateThreadWithStackSize
+#define SDL_CreateThreadWithStackSize(fn, name, stacksize, data) SDL_CreateThreadWithStackSize_REAL(fn, name, stacksize, data, (pfnSDL_CurrentBeginThread)_beginthreadex, (pfnSDL_CurrentEndThread)_endthreadex)
 #else
 #define SDL_CreateThread(fn, name, data) SDL_CreateThread(fn, name, data, (pfnSDL_CurrentBeginThread)_beginthreadex, (pfnSDL_CurrentEndThread)_endthreadex)
+#define SDL_CreateThreadWithStackSize(fn, name, stacksize, data) SDL_CreateThreadWithStackSize(fn, name, data, (pfnSDL_CurrentBeginThread)_beginthreadex, (pfnSDL_CurrentEndThread)_endthreadex)
 #endif
 
 #elif defined(__OS2__)
@@ -132,15 +143,31 @@ extern DECLSPEC SDL_Thread *SDLCALL
 SDL_CreateThread(SDL_ThreadFunction fn, const char *name, void *data,
                  pfnSDL_CurrentBeginThread pfnBeginThread,
                  pfnSDL_CurrentEndThread pfnEndThread);
+extern DECLSPEC SDL_Thread *SDLCALL
+SDL_CreateThreadWithStackSize(SDL_ThreadFunction fn, const char *name, const size_t stacksize, void *data,
+                 pfnSDL_CurrentBeginThread pfnBeginThread,
+                 pfnSDL_CurrentEndThread pfnEndThread);
 #if defined(SDL_CreateThread) && SDL_DYNAMIC_API
 #undef SDL_CreateThread
 #define SDL_CreateThread(fn, name, data) SDL_CreateThread_REAL(fn, name, data, (pfnSDL_CurrentBeginThread)_beginthread, (pfnSDL_CurrentEndThread)_endthread)
+#undef SDL_CreateThreadWithStackSize
+#define SDL_CreateThreadWithStackSize(fn, name, stacksize, data) SDL_CreateThreadWithStackSize_REAL(fn, name, data, (pfnSDL_CurrentBeginThread)_beginthread, (pfnSDL_CurrentEndThread)_endthread)
 #else
 #define SDL_CreateThread(fn, name, data) SDL_CreateThread(fn, name, data, (pfnSDL_CurrentBeginThread)_beginthread, (pfnSDL_CurrentEndThread)_endthread)
+#define SDL_CreateThreadWithStackSize(fn, name, stacksize, data) SDL_CreateThreadWithStackSize(fn, name, stacksize, data, (pfnSDL_CurrentBeginThread)_beginthread, (pfnSDL_CurrentEndThread)_endthread)
 #endif
 
 #else
 
+/**
+ *  Create a thread with a default stack size.
+ *
+ *  This is equivalent to calling:
+ *  SDL_CreateThreadWithStackSize(fn, name, 0, data);
+ */
+extern DECLSPEC SDL_Thread *SDLCALL
+SDL_CreateThread(SDL_ThreadFunction fn, const char *name, void *data);
+
 /**
  *  Create a thread.
  *
@@ -158,9 +185,17 @@ SDL_CreateThread(SDL_ThreadFunction fn, const char *name, void *data,
  *   If a system imposes requirements, SDL will try to munge the string for
  *    it (truncate, etc), but the original string contents will be available
  *    from SDL_GetThreadName().
+ *
+ *   The size (in bytes) of the new stack can be specified. Zero means "use
+ *    the system default" which might be wildly different between platforms
+ *    (x86 Linux generally defaults to eight megabytes, an embedded device
+ *    might be a few kilobytes instead).
+ *
+ *   In SDL 2.1, stacksize will be folded into the original SDL_CreateThread
+ *    function.
  */
 extern DECLSPEC SDL_Thread *SDLCALL
-SDL_CreateThread(SDL_ThreadFunction fn, const char *name, void *data);
+SDL_CreateThreadWithStackSize(SDL_ThreadFunction fn, const char *name, const size_t stacksize, void *data);
 
 #endif
 
diff --git a/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_timer.h b/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_timer.h
index 282625d3f..5600618ff 100644
--- a/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_timer.h
+++ b/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_timer.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_touch.h b/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_touch.h
index db9e25ebd..f4075e79a 100644
--- a/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_touch.h
+++ b/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_touch.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_types.h b/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_types.h
index 06ee80cb3..4ac248c8c 100644
--- a/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_types.h
+++ b/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_types.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_version.h b/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_version.h
index 5b4c40248..31443e149 100644
--- a/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_version.h
+++ b/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_version.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
@@ -59,7 +59,7 @@ typedef struct SDL_version
 */
 #define SDL_MAJOR_VERSION   2
 #define SDL_MINOR_VERSION   0
-#define SDL_PATCHLEVEL      7
+#define SDL_PATCHLEVEL      9
 
 /**
  *  \brief Macro to determine SDL version program was compiled against.
diff --git a/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_video.h b/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_video.h
index 6f6cda8b1..461f13805 100644
--- a/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_video.h
+++ b/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_video.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
@@ -110,7 +110,9 @@ typedef enum
     SDL_WINDOW_MOUSE_FOCUS = 0x00000400,        /**< window has mouse focus */
     SDL_WINDOW_FULLSCREEN_DESKTOP = ( SDL_WINDOW_FULLSCREEN | 0x00001000 ),
     SDL_WINDOW_FOREIGN = 0x00000800,            /**< window not created by SDL */
-    SDL_WINDOW_ALLOW_HIGHDPI = 0x00002000,      /**< window should be created in high-DPI mode if supported */
+    SDL_WINDOW_ALLOW_HIGHDPI = 0x00002000,      /**< window should be created in high-DPI mode if supported.
+                                                     On macOS NSHighResolutionCapable must be set true in the
+                                                     application's Info.plist for this to have any effect. */
     SDL_WINDOW_MOUSE_CAPTURE = 0x00004000,      /**< window has mouse captured (unrelated to INPUT_GRABBED) */
     SDL_WINDOW_ALWAYS_ON_TOP = 0x00008000,      /**< window should always be above others */
     SDL_WINDOW_SKIP_TASKBAR  = 0x00010000,      /**< window should not be added to the taskbar */
@@ -167,6 +169,24 @@ typedef enum
     SDL_WINDOWEVENT_HIT_TEST        /**< Window had a hit test that wasn't SDL_HITTEST_NORMAL. */
 } SDL_WindowEventID;
 
+/**
+ *  \brief Event subtype for display events
+ */
+typedef enum
+{
+    SDL_DISPLAYEVENT_NONE,          /**< Never used */
+    SDL_DISPLAYEVENT_ORIENTATION    /**< Display orientation has changed to data1 */
+} SDL_DisplayEventID;
+
+typedef enum
+{
+    SDL_ORIENTATION_UNKNOWN,            /**< The display orientation can't be determined */
+    SDL_ORIENTATION_LANDSCAPE,          /**< The display is in landscape mode, with the right side up, relative to portrait mode */
+    SDL_ORIENTATION_LANDSCAPE_FLIPPED,  /**< The display is in landscape mode, with the left side up, relative to portrait mode */
+    SDL_ORIENTATION_PORTRAIT,           /**< The display is in portrait mode */
+    SDL_ORIENTATION_PORTRAIT_FLIPPED    /**< The display is in portrait mode, upside down */
+} SDL_DisplayOrientation;
+
 /**
  *  \brief An opaque handle to an OpenGL context.
  */
@@ -314,18 +334,6 @@ extern DECLSPEC const char * SDLCALL SDL_GetDisplayName(int displayIndex);
  */
 extern DECLSPEC int SDLCALL SDL_GetDisplayBounds(int displayIndex, SDL_Rect * rect);
 
-/**
- *  \brief Get the dots/pixels-per-inch for a display
- *
- *  \note Diagonal, horizontal and vertical DPI can all be optionally
- *        returned if the parameter is non-NULL.
- *
- *  \return 0 on success, or -1 if no DPI information is available or the index is out of range.
- *
- *  \sa SDL_GetNumVideoDisplays()
- */
-extern DECLSPEC int SDLCALL SDL_GetDisplayDPI(int displayIndex, float * ddpi, float * hdpi, float * vdpi);
-
 /**
  *  \brief Get the usable desktop area represented by a display, with the
  *         primary display located at 0,0
@@ -345,6 +353,27 @@ extern DECLSPEC int SDLCALL SDL_GetDisplayDPI(int displayIndex, float * ddpi, fl
  */
 extern DECLSPEC int SDLCALL SDL_GetDisplayUsableBounds(int displayIndex, SDL_Rect * rect);
 
+/**
+ *  \brief Get the dots/pixels-per-inch for a display
+ *
+ *  \note Diagonal, horizontal and vertical DPI can all be optionally
+ *        returned if the parameter is non-NULL.
+ *
+ *  \return 0 on success, or -1 if no DPI information is available or the index is out of range.
+ *
+ *  \sa SDL_GetNumVideoDisplays()
+ */
+extern DECLSPEC int SDLCALL SDL_GetDisplayDPI(int displayIndex, float * ddpi, float * hdpi, float * vdpi);
+
+/**
+ *  \brief Get the orientation of a display
+ *
+ *  \return The orientation of the display, or SDL_ORIENTATION_UNKNOWN if it isn't available.
+ *
+ *  \sa SDL_GetNumVideoDisplays()
+ */
+extern DECLSPEC SDL_DisplayOrientation SDLCALL SDL_GetDisplayOrientation(int displayIndex);
+
 /**
  *  \brief Returns the number of available display modes.
  *
@@ -470,7 +499,7 @@ extern DECLSPEC Uint32 SDLCALL SDL_GetWindowPixelFormat(SDL_Window * window);
  *  If the window is created with any of the SDL_WINDOW_OPENGL or
  *  SDL_WINDOW_VULKAN flags, then the corresponding LoadLibrary function
  *  (SDL_GL_LoadLibrary or SDL_Vulkan_LoadLibrary) is called and the
- *  corrensponding UnloadLibrary function is called by SDL_DestroyWindow().
+ *  corresponding UnloadLibrary function is called by SDL_DestroyWindow().
  *
  *  If SDL_WINDOW_VULKAN is specified and there isn't a working Vulkan driver,
  *  SDL_CreateWindow() will fail because SDL_Vulkan_LoadLibrary() will fail.
diff --git a/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_vulkan.h b/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_vulkan.h
index 803b5feef..972cca4d7 100644
--- a/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_vulkan.h
+++ b/libs/SDL2/x86_64-w64-mingw32/include/SDL2/SDL_vulkan.h
@@ -69,30 +69,43 @@ typedef VkSurfaceKHR SDL_vulkanSurface; /* for compatibility with Tizen */
  *  \brief Dynamically load a Vulkan loader library.
  *
  *  \param [in] path The platform dependent Vulkan loader library name, or
- *              \c NULL to open the default Vulkan loader library.
+ *              \c NULL.
  *
  *  \return \c 0 on success, or \c -1 if the library couldn't be loaded.
  *
- *  This should be done after initializing the video driver, but before
+ *  If \a path is NULL SDL will use the value of the environment variable
+ *  \c SDL_VULKAN_LIBRARY, if set, otherwise it loads the default Vulkan
+ *  loader library.
+ *
+ *  This should be called after initializing the video driver, but before
  *  creating any Vulkan windows. If no Vulkan loader library is loaded, the
  *  default library will be loaded upon creation of the first Vulkan window.
  *
- *  \note If you specify a non-NULL \a path, you should retrieve all of the
- *        Vulkan functions used in your program from the dynamic library using
+ *  \note It is fairly common for Vulkan applications to link with \a libvulkan
+ *        instead of explicitly loading it at run time. This will work with
+ *        SDL provided the application links to a dynamic library and both it
+ *        and SDL use the same search path.
+ *
+ *  \note If you specify a non-NULL \c path, an application should retrieve all
+ *        of the Vulkan functions it uses from the dynamic library using
  *        \c SDL_Vulkan_GetVkGetInstanceProcAddr() unless you can guarantee
- *        \a path points to the same vulkan loader library that you linked to.
+ *        \c path points to the same vulkan loader library the application
+ *        linked to.
  *
  *  \note On Apple devices, if \a path is NULL, SDL will attempt to find
  *        the vkGetInstanceProcAddr address within all the mach-o images of
- *        the current process. This is because the currently (v0.17.0)
- *        recommended MoltenVK (Vulkan on Metal) usage is as a static library.
- *        If it is not found then SDL will attempt to load \c libMoltenVK.dylib.
- *        Applications using the dylib alternative therefore do not need to do
- *        anything special when calling SDL.
+ *        the current process. This is because it is fairly common for Vulkan
+ *        applications to link with libvulkan (and historically MoltenVK was
+ *        provided as a static library). If it is not found then, on macOS, SDL
+ *        will attempt to load \c vulkan.framework/vulkan, \c libvulkan.1.dylib,
+ *        \c MoltenVK.framework/MoltenVK and \c libMoltenVK.dylib in that order.
+ *        On iOS SDL will attempt to load \c libMoltenVK.dylib. Applications
+ *        using a dynamic framework or .dylib must ensure it is included in its
+ *        application bundle.
  *
- *  \note On non-Apple devices, SDL requires you to either not link to the
- *        Vulkan loader or link to a dynamic library version. This limitation
- *        may be removed in a future version of SDL.
+ *  \note On non-Apple devices, application linking with a static libvulkan is
+ *        not supported. Either do not link to the Vulkan loader or link to a
+ *        dynamic library version.
  *
  *  \note This function will fail if there are no working Vulkan drivers
  *        installed.
@@ -122,11 +135,11 @@ extern DECLSPEC void SDLCALL SDL_Vulkan_UnloadLibrary(void);
  *  \brief Get the names of the Vulkan instance extensions needed to create
  *         a surface with \c SDL_Vulkan_CreateSurface().
  *
- *  \param [in]     window Window for which the required Vulkan instance
+ *  \param [in]     \c NULL or window Window for which the required Vulkan instance
  *                  extensions should be retrieved
- *  \param [in,out] count pointer to an \c unsigned related to the number of
+ *  \param [in,out] pCount pointer to an \c unsigned related to the number of
  *                  required Vulkan instance extensions
- *  \param [out]    names \c NULL or a pointer to an array to be filled with the
+ *  \param [out]    pNames \c NULL or a pointer to an array to be filled with the
  *                  required Vulkan instance extensions
  *
  *  \return \c SDL_TRUE on success, \c SDL_FALSE on error.
@@ -140,6 +153,10 @@ extern DECLSPEC void SDLCALL SDL_Vulkan_UnloadLibrary(void);
  *  is smaller than the number of required extensions, \c SDL_FALSE will be
  *  returned instead of \c SDL_TRUE, to indicate that not all the required
  *  extensions were returned.
+ * 
+ *  \note If \c window is not NULL, it will be checked against its creation
+ *        flags to ensure that the Vulkan flag is present. This parameter
+ *        will be removed in a future major release.
  *
  *  \note The returned list of extensions will contain \c VK_KHR_surface
  *        and zero or more platform specific extensions
@@ -147,12 +164,13 @@ extern DECLSPEC void SDLCALL SDL_Vulkan_UnloadLibrary(void);
  *  \note The extension names queried here must be enabled when calling
  *        VkCreateInstance, otherwise surface creation will fail.
  *
- *  \note \c window should have been created with the \c SDL_WINDOW_VULKAN flag.
+ *  \note \c window should have been created with the \c SDL_WINDOW_VULKAN flag
+ *        or be \c NULL
  *
  *  \code
  *  unsigned int count;
  *  // get count of required extensions
- *  if(!SDL_Vulkan_GetInstanceExtensions(window, &count, NULL))
+ *  if(!SDL_Vulkan_GetInstanceExtensions(NULL, &count, NULL))
  *      handle_error();
  *
  *  static const char *const additionalExtensions[] =
@@ -166,7 +184,7 @@ extern DECLSPEC void SDLCALL SDL_Vulkan_UnloadLibrary(void);
  *      handle_error();
  *
  *  // get names of required extensions
- *  if(!SDL_Vulkan_GetInstanceExtensions(window, &count, names))
+ *  if(!SDL_Vulkan_GetInstanceExtensions(NULL, &count, names))
  *      handle_error();
  *
  *  // copy additional extensions after required extensions
@@ -240,6 +258,9 @@ extern DECLSPEC SDL_bool SDLCALL SDL_Vulkan_CreateSurface(
  * platform with high-DPI support (Apple calls this "Retina"), and not disabled
  * by the \c SDL_HINT_VIDEO_HIGHDPI_DISABLED hint.
  *
+ *  \note On macOS high-DPI support must be enabled for an application by
+ *        setting NSHighResolutionCapable to true in its Info.plist.
+ *
  *  \sa SDL_GetWindowSize()
  *  \sa SDL_CreateWindow()
  */
diff --git a/libs/SDL2/x86_64-w64-mingw32/include/SDL2/begin_code.h b/libs/SDL2/x86_64-w64-mingw32/include/SDL2/begin_code.h
index 5372d6f04..6c2106246 100644
--- a/libs/SDL2/x86_64-w64-mingw32/include/SDL2/begin_code.h
+++ b/libs/SDL2/x86_64-w64-mingw32/include/SDL2/begin_code.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/x86_64-w64-mingw32/include/SDL2/close_code.h b/libs/SDL2/x86_64-w64-mingw32/include/SDL2/close_code.h
index 2a352dbb9..b3b70a4c8 100644
--- a/libs/SDL2/x86_64-w64-mingw32/include/SDL2/close_code.h
+++ b/libs/SDL2/x86_64-w64-mingw32/include/SDL2/close_code.h
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2/x86_64-w64-mingw32/lib/cmake/SDL2/sdl2-config.cmake b/libs/SDL2/x86_64-w64-mingw32/lib/cmake/SDL2/sdl2-config.cmake
index f5bfc3b79..455d8ed55 100644
--- a/libs/SDL2/x86_64-w64-mingw32/lib/cmake/SDL2/sdl2-config.cmake
+++ b/libs/SDL2/x86_64-w64-mingw32/lib/cmake/SDL2/sdl2-config.cmake
@@ -1,11 +1,11 @@
 # sdl2 cmake project-config input for ./configure scripts
 
-set(prefix "/usr/local/x86_64-w64-mingw32") 
+set(prefix "/opt/local/x86_64-w64-mingw32") 
 set(exec_prefix "${prefix}")
 set(libdir "${exec_prefix}/lib")
-set(SDL2_PREFIX "/usr/local/x86_64-w64-mingw32")
-set(SDL2_EXEC_PREFIX "/usr/local/x86_64-w64-mingw32")
+set(SDL2_PREFIX "/opt/local/x86_64-w64-mingw32")
+set(SDL2_EXEC_PREFIX "/opt/local/x86_64-w64-mingw32")
 set(SDL2_LIBDIR "${exec_prefix}/lib")
 set(SDL2_INCLUDE_DIRS "${prefix}/include/SDL2")
-set(SDL2_LIBRARIES "-L${SDL2_LIBDIR}  -lmingw32 -lSDL2main -lSDL2  -mwindows")
+set(SDL2_LIBRARIES "-L${SDL2_LIBDIR}  -lmingw32 -lSDL2main -lSDL2 -mwindows")
 string(STRIP "${SDL2_LIBRARIES}" SDL2_LIBRARIES)
diff --git a/libs/SDL2/x86_64-w64-mingw32/lib/libSDL2.a b/libs/SDL2/x86_64-w64-mingw32/lib/libSDL2.a
index d81a9cbcf..827950682 100644
Binary files a/libs/SDL2/x86_64-w64-mingw32/lib/libSDL2.a and b/libs/SDL2/x86_64-w64-mingw32/lib/libSDL2.a differ
diff --git a/libs/SDL2/x86_64-w64-mingw32/lib/libSDL2.dll.a b/libs/SDL2/x86_64-w64-mingw32/lib/libSDL2.dll.a
index 65648749c..669b6a637 100755
Binary files a/libs/SDL2/x86_64-w64-mingw32/lib/libSDL2.dll.a and b/libs/SDL2/x86_64-w64-mingw32/lib/libSDL2.dll.a differ
diff --git a/libs/SDL2/x86_64-w64-mingw32/lib/libSDL2.la b/libs/SDL2/x86_64-w64-mingw32/lib/libSDL2.la
new file mode 100644
index 000000000..d5295eec8
--- /dev/null
+++ b/libs/SDL2/x86_64-w64-mingw32/lib/libSDL2.la
@@ -0,0 +1,41 @@
+# libSDL2.la - a libtool library file
+# Generated by libtool (GNU libtool) 2.4.2
+#
+# Please DO NOT delete this file!
+# It is necessary for linking the library.
+
+# The name that we can dlopen(3).
+dlname='../bin/SDL2.dll'
+
+# Names of this library.
+library_names='libSDL2.dll.a'
+
+# The name of the static archive.
+old_library='libSDL2.a'
+
+# Linker flags that can not go in dependency_libs.
+inherited_linker_flags=''
+
+# Libraries that this one depends upon.
+dependency_libs=' -ldinput8 -ldxguid -ldxerr8 -luser32 -lgdi32 -lwinmm -limm32 -lole32 -loleaut32 -lshell32 -lsetupapi -lversion -luuid'
+
+# Names of additional weak libraries provided by this library
+weak_library_names=''
+
+# Version information for libSDL2.
+current=9
+age=9
+revision=0
+
+# Is this an already installed library?
+installed=yes
+
+# Should we warn about portability when linking against -modules?
+shouldnotlink=no
+
+# Files to dlopen/dlpreopen
+dlopen=''
+dlpreopen=''
+
+# Directory that this library needs to be installed in:
+libdir='/Users/valve/release/SDL/SDL2-2.0.9/x86_64-w64-mingw32/lib'
diff --git a/libs/SDL2/x86_64-w64-mingw32/lib/libSDL2_test.a b/libs/SDL2/x86_64-w64-mingw32/lib/libSDL2_test.a
index af32f8689..fcbdbbf76 100644
Binary files a/libs/SDL2/x86_64-w64-mingw32/lib/libSDL2_test.a and b/libs/SDL2/x86_64-w64-mingw32/lib/libSDL2_test.a differ
diff --git a/libs/SDL2/x86_64-w64-mingw32/lib/libSDL2_test.la b/libs/SDL2/x86_64-w64-mingw32/lib/libSDL2_test.la
new file mode 100644
index 000000000..76ad43f0f
--- /dev/null
+++ b/libs/SDL2/x86_64-w64-mingw32/lib/libSDL2_test.la
@@ -0,0 +1,41 @@
+# libSDL2_test.la - a libtool library file
+# Generated by libtool (GNU libtool) 2.4.2
+#
+# Please DO NOT delete this file!
+# It is necessary for linking the library.
+
+# The name that we can dlopen(3).
+dlname=''
+
+# Names of this library.
+library_names=''
+
+# The name of the static archive.
+old_library='libSDL2_test.a'
+
+# Linker flags that can not go in dependency_libs.
+inherited_linker_flags=''
+
+# Libraries that this one depends upon.
+dependency_libs=''
+
+# Names of additional weak libraries provided by this library
+weak_library_names=''
+
+# Version information for libSDL2_test.
+current=0
+age=0
+revision=0
+
+# Is this an already installed library?
+installed=yes
+
+# Should we warn about portability when linking against -modules?
+shouldnotlink=no
+
+# Files to dlopen/dlpreopen
+dlopen=''
+dlpreopen=''
+
+# Directory that this library needs to be installed in:
+libdir='/Users/valve/release/SDL/SDL2-2.0.9/x86_64-w64-mingw32/lib'
diff --git a/libs/SDL2/x86_64-w64-mingw32/lib/libSDL2main.a b/libs/SDL2/x86_64-w64-mingw32/lib/libSDL2main.a
index decdd5a0f..3a26e430d 100644
Binary files a/libs/SDL2/x86_64-w64-mingw32/lib/libSDL2main.a and b/libs/SDL2/x86_64-w64-mingw32/lib/libSDL2main.a differ
diff --git a/libs/SDL2/x86_64-w64-mingw32/lib/libSDL2main.la b/libs/SDL2/x86_64-w64-mingw32/lib/libSDL2main.la
new file mode 100644
index 000000000..5aa469333
--- /dev/null
+++ b/libs/SDL2/x86_64-w64-mingw32/lib/libSDL2main.la
@@ -0,0 +1,41 @@
+# libSDL2main.la - a libtool library file
+# Generated by libtool (GNU libtool) 2.4.2
+#
+# Please DO NOT delete this file!
+# It is necessary for linking the library.
+
+# The name that we can dlopen(3).
+dlname=''
+
+# Names of this library.
+library_names=''
+
+# The name of the static archive.
+old_library='libSDL2main.a'
+
+# Linker flags that can not go in dependency_libs.
+inherited_linker_flags=''
+
+# Libraries that this one depends upon.
+dependency_libs=''
+
+# Names of additional weak libraries provided by this library
+weak_library_names=''
+
+# Version information for libSDL2main.
+current=0
+age=0
+revision=0
+
+# Is this an already installed library?
+installed=yes
+
+# Should we warn about portability when linking against -modules?
+shouldnotlink=no
+
+# Files to dlopen/dlpreopen
+dlopen=''
+dlpreopen=''
+
+# Directory that this library needs to be installed in:
+libdir='/Users/valve/release/SDL/SDL2-2.0.9/x86_64-w64-mingw32/lib'
diff --git a/libs/SDL2/x86_64-w64-mingw32/lib/pkgconfig/sdl2.pc b/libs/SDL2/x86_64-w64-mingw32/lib/pkgconfig/sdl2.pc
index d06fc29cd..ae83be160 100644
--- a/libs/SDL2/x86_64-w64-mingw32/lib/pkgconfig/sdl2.pc
+++ b/libs/SDL2/x86_64-w64-mingw32/lib/pkgconfig/sdl2.pc
@@ -1,15 +1,15 @@
 # sdl pkg-config source file
 
-prefix=/usr/local/x86_64-w64-mingw32
+prefix=/opt/local/x86_64-w64-mingw32
 exec_prefix=${prefix}
 libdir=${exec_prefix}/lib
 includedir=${prefix}/include
 
 Name: sdl2
 Description: Simple DirectMedia Layer is a cross-platform multimedia library designed to provide low level access to audio, keyboard, mouse, joystick, 3D hardware via OpenGL, and 2D video framebuffer.
-Version: 2.0.7
+Version: 2.0.9
 Requires:
 Conflicts:
-Libs: -L${libdir}  -lmingw32 -lSDL2main -lSDL2  -mwindows
-Libs.private: -lmingw32 -lSDL2main -lSDL2  -mwindows  -Wl,--no-undefined -lm -ldinput8 -ldxguid -ldxerr8 -luser32 -lgdi32 -lwinmm -limm32 -lole32 -loleaut32 -lshell32 -lversion -luuid -static-libgcc
+Libs: -L${libdir}  -lmingw32 -lSDL2main -lSDL2 -mwindows
+Libs.private: -lmingw32 -lSDL2main -lSDL2 -mwindows  -Wl,--no-undefined -lm -ldinput8 -ldxguid -ldxerr8 -luser32 -lgdi32 -lwinmm -limm32 -lole32 -loleaut32 -lshell32 -lsetupapi -lversion -luuid -static-libgcc
 Cflags: -I${includedir}/SDL2  -Dmain=SDL_main
diff --git a/libs/SDL2_mixer/CHANGES.txt b/libs/SDL2_mixer/CHANGES.txt
index 1c99deb8e..7760ddfe3 100644
--- a/libs/SDL2_mixer/CHANGES.txt
+++ b/libs/SDL2_mixer/CHANGES.txt
@@ -1,3 +1,15 @@
+2.0.4:
+Ozkan Sezer - Wed, 10 Oct 2018 14:56:10
+ * Removed smpeg support for mp3 music, now that it's replaced by libmpg123
+Ozkan Sezer - Sun, 07 Oct 2018 08:50:02
+ * Fixed mp3 mad decoder to skip tags, which otherwise would lead to crashes
+Ozkan Sezer - Fri, 15 Jun 2018 05:32:56
+ * Added support for Opus music playback using opusfile library
+
+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
diff --git a/libs/SDL2_mixer/COPYING.txt b/libs/SDL2_mixer/COPYING.txt
index 056d0f352..234a5a5ef 100644
--- a/libs/SDL2_mixer/COPYING.txt
+++ b/libs/SDL2_mixer/COPYING.txt
@@ -1,6 +1,6 @@
 /*
   SDL_mixer:  An audio mixer library based on the SDL library
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
diff --git a/libs/SDL2_mixer/README.txt b/libs/SDL2_mixer/README.txt
index 14de6e002..a639c37bc 100644
--- a/libs/SDL2_mixer/README.txt
+++ b/libs/SDL2_mixer/README.txt
@@ -14,7 +14,7 @@ for documentation on this mixer library.
 The mixer can currently load Microsoft WAVE files and Creative Labs VOC
 files as audio samples, it can load FLAC files with libFLAC, it can load
 Ogg Vorbis files with Ogg Vorbis or Tremor libraries, it can load MP3 files
-using mpg123, SMPEG or libmad, and it can load MIDI files with Timidity,
+using mpg123 or libmad, and it can load MIDI files with Timidity,
 FluidSynth, and natively on Windows, Mac OSX, and Linux, and finally it can
 load the following file formats via ModPlug or MikMod: .MOD .S3M .IT .XM.
 
diff --git a/libs/SDL2_mixer/SRB2NOTE.txt b/libs/SDL2_mixer/SRB2NOTE.txt
new file mode 100644
index 000000000..7053c44f6
--- /dev/null
+++ b/libs/SDL2_mixer/SRB2NOTE.txt
@@ -0,0 +1,15 @@
+# SDL Mixer Development Libaries
+
+Download both the VC and MinGW packages and extract them here.
+
+https://www.libsdl.org/projects/SDL_mixer/
+
+## VC Package
+
+* include
+* lib
+
+## MinGW Package
+
+* i686-w64-mingw32
+* x86_64-w64-mingw32
diff --git a/libs/SDL2_mixer/i686-w64-mingw32/bin/LICENSE.FLAC.txt b/libs/SDL2_mixer/i686-w64-mingw32/bin/LICENSE.FLAC.txt
index 94fd3aa69..2e67b77cb 100644
--- a/libs/SDL2_mixer/i686-w64-mingw32/bin/LICENSE.FLAC.txt
+++ b/libs/SDL2_mixer/i686-w64-mingw32/bin/LICENSE.FLAC.txt
@@ -1,5 +1,5 @@
 The source code to this library used with SDL_mixer can be found here:
-http://www.libsdl.org/projects/SDL_mixer/libs/
+https://hg.libsdl.org/SDL_mixer/file/default/external
 ---
 
 Copyright (C) 2000,2001,2002,2003,2004,2005,2006,2007  Josh Coalson
diff --git a/libs/SDL2_mixer/i686-w64-mingw32/bin/LICENSE.modplug.txt b/libs/SDL2_mixer/i686-w64-mingw32/bin/LICENSE.modplug.txt
index 59fbf826c..a89532db8 100644
--- a/libs/SDL2_mixer/i686-w64-mingw32/bin/LICENSE.modplug.txt
+++ b/libs/SDL2_mixer/i686-w64-mingw32/bin/LICENSE.modplug.txt
@@ -1 +1,5 @@
+The source code to this library used with SDL_mixer can be found here:
+https://hg.libsdl.org/SDL_mixer/file/default/external
+---
+
 ModPlug-XMMS and libmodplug are now in the public domain.
diff --git a/libs/SDL2_mixer/i686-w64-mingw32/bin/LICENSE.mpg123.txt b/libs/SDL2_mixer/i686-w64-mingw32/bin/LICENSE.mpg123.txt
index d7bb85fc3..2111cd79f 100644
--- a/libs/SDL2_mixer/i686-w64-mingw32/bin/LICENSE.mpg123.txt
+++ b/libs/SDL2_mixer/i686-w64-mingw32/bin/LICENSE.mpg123.txt
@@ -1,3 +1,7 @@
+The source code to this library used with SDL_mixer can be found here:
+https://hg.libsdl.org/SDL_mixer/file/default/external
+---
+
 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:
diff --git a/libs/SDL2_mixer/i686-w64-mingw32/bin/LICENSE.ogg-vorbis.txt b/libs/SDL2_mixer/i686-w64-mingw32/bin/LICENSE.ogg-vorbis.txt
index c2cb6d56e..6456dc4ed 100644
--- a/libs/SDL2_mixer/i686-w64-mingw32/bin/LICENSE.ogg-vorbis.txt
+++ b/libs/SDL2_mixer/i686-w64-mingw32/bin/LICENSE.ogg-vorbis.txt
@@ -1,5 +1,5 @@
 The source code to this library used with SDL_mixer can be found here:
-http://www.libsdl.org/projects/SDL_mixer/libs/
+https://hg.libsdl.org/SDL_image/file/default/external
 ---
 
 Copyright (c) 2002-2008 Xiph.org Foundation
diff --git a/libs/SDL2_mixer/i686-w64-mingw32/bin/LICENSE.opus.txt b/libs/SDL2_mixer/i686-w64-mingw32/bin/LICENSE.opus.txt
new file mode 100644
index 000000000..adb56a854
--- /dev/null
+++ b/libs/SDL2_mixer/i686-w64-mingw32/bin/LICENSE.opus.txt
@@ -0,0 +1,48 @@
+The source code to this library used with SDL_mixer can be found here:
+https://hg.libsdl.org/SDL_mixer/file/default/external
+---
+
+Copyright 2001-2011 Xiph.Org, Skype Limited, Octasic,
+                    Jean-Marc Valin, Timothy B. Terriberry,
+                    CSIRO, Gregory Maxwell, Mark Borgerding,
+                    Erik de Castro Lopo
+
+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 Internet Society, IETF or IETF Trust, nor the 
+names of specific 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 COPYRIGHT OWNER
+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.
+
+Opus is subject to the royalty-free patent licenses which are
+specified at:
+
+Xiph.Org Foundation:
+https://datatracker.ietf.org/ipr/1524/
+
+Microsoft Corporation:
+https://datatracker.ietf.org/ipr/1914/
+
+Broadcom Corporation:
+https://datatracker.ietf.org/ipr/1526/
diff --git a/libs/SDL2_mixer/i686-w64-mingw32/bin/LICENSE.opusfile.txt b/libs/SDL2_mixer/i686-w64-mingw32/bin/LICENSE.opusfile.txt
new file mode 100644
index 000000000..dfc9681fc
--- /dev/null
+++ b/libs/SDL2_mixer/i686-w64-mingw32/bin/LICENSE.opusfile.txt
@@ -0,0 +1,32 @@
+The source code to this library used with SDL_mixer can be found here:
+https://hg.libsdl.org/SDL_mixer/file/default/external
+---
+
+Copyright (c) 1994-2013 Xiph.Org Foundation and contributors
+
+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/SDL2_mixer/i686-w64-mingw32/bin/SDL2_mixer.dll b/libs/SDL2_mixer/i686-w64-mingw32/bin/SDL2_mixer.dll
index 54ebbb1d4..96abfa1ab 100755
Binary files a/libs/SDL2_mixer/i686-w64-mingw32/bin/SDL2_mixer.dll and b/libs/SDL2_mixer/i686-w64-mingw32/bin/SDL2_mixer.dll differ
diff --git a/libs/SDL2_mixer/i686-w64-mingw32/bin/libFLAC-8.dll b/libs/SDL2_mixer/i686-w64-mingw32/bin/libFLAC-8.dll
index 1c55ad496..b56ea2a8c 100755
Binary files a/libs/SDL2_mixer/i686-w64-mingw32/bin/libFLAC-8.dll and b/libs/SDL2_mixer/i686-w64-mingw32/bin/libFLAC-8.dll differ
diff --git a/libs/SDL2_mixer/i686-w64-mingw32/bin/libmodplug-1.dll b/libs/SDL2_mixer/i686-w64-mingw32/bin/libmodplug-1.dll
index a2cba0d6b..d66a317dd 100755
Binary files a/libs/SDL2_mixer/i686-w64-mingw32/bin/libmodplug-1.dll and b/libs/SDL2_mixer/i686-w64-mingw32/bin/libmodplug-1.dll differ
diff --git a/libs/SDL2_mixer/i686-w64-mingw32/bin/libmpg123-0.dll b/libs/SDL2_mixer/i686-w64-mingw32/bin/libmpg123-0.dll
index ca7de300d..240298bbf 100755
Binary files a/libs/SDL2_mixer/i686-w64-mingw32/bin/libmpg123-0.dll and b/libs/SDL2_mixer/i686-w64-mingw32/bin/libmpg123-0.dll differ
diff --git a/libs/SDL2_mixer/i686-w64-mingw32/bin/libogg-0.dll b/libs/SDL2_mixer/i686-w64-mingw32/bin/libogg-0.dll
index 3abe6ebfc..233c0f42a 100755
Binary files a/libs/SDL2_mixer/i686-w64-mingw32/bin/libogg-0.dll and b/libs/SDL2_mixer/i686-w64-mingw32/bin/libogg-0.dll differ
diff --git a/libs/SDL2_mixer/i686-w64-mingw32/bin/libopus-0.dll b/libs/SDL2_mixer/i686-w64-mingw32/bin/libopus-0.dll
new file mode 100644
index 000000000..94ea541d2
Binary files /dev/null and b/libs/SDL2_mixer/i686-w64-mingw32/bin/libopus-0.dll differ
diff --git a/libs/SDL2_mixer/i686-w64-mingw32/bin/libopusfile-0.dll b/libs/SDL2_mixer/i686-w64-mingw32/bin/libopusfile-0.dll
new file mode 100644
index 000000000..260796b6a
Binary files /dev/null and b/libs/SDL2_mixer/i686-w64-mingw32/bin/libopusfile-0.dll differ
diff --git a/libs/SDL2_mixer/i686-w64-mingw32/bin/libvorbis-0.dll b/libs/SDL2_mixer/i686-w64-mingw32/bin/libvorbis-0.dll
index 4e44ef088..4e4aaa543 100755
Binary files a/libs/SDL2_mixer/i686-w64-mingw32/bin/libvorbis-0.dll and b/libs/SDL2_mixer/i686-w64-mingw32/bin/libvorbis-0.dll differ
diff --git a/libs/SDL2_mixer/i686-w64-mingw32/bin/libvorbisfile-3.dll b/libs/SDL2_mixer/i686-w64-mingw32/bin/libvorbisfile-3.dll
index e757eb6de..5d90a235c 100755
Binary files a/libs/SDL2_mixer/i686-w64-mingw32/bin/libvorbisfile-3.dll and b/libs/SDL2_mixer/i686-w64-mingw32/bin/libvorbisfile-3.dll differ
diff --git a/libs/SDL2_mixer/i686-w64-mingw32/include/SDL2/SDL_mixer.h b/libs/SDL2_mixer/i686-w64-mingw32/include/SDL2/SDL_mixer.h
index cbb8ae6b6..009d8a2da 100644
--- a/libs/SDL2_mixer/i686-w64-mingw32/include/SDL2/SDL_mixer.h
+++ b/libs/SDL2_mixer/i686-w64-mingw32/include/SDL2/SDL_mixer.h
@@ -1,6 +1,6 @@
 /*
   SDL_mixer:  An audio mixer library based on the SDL library
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
@@ -38,7 +38,7 @@ extern "C" {
 */
 #define SDL_MIXER_MAJOR_VERSION 2
 #define SDL_MIXER_MINOR_VERSION 0
-#define SDL_MIXER_PATCHLEVEL    2
+#define SDL_MIXER_PATCHLEVEL    4
 
 /* This macro can be used to fill a version structure with the compile-time
  * version of the SDL_mixer library.
@@ -80,7 +80,8 @@ typedef enum
     MIX_INIT_MOD    = 0x00000002,
     MIX_INIT_MP3    = 0x00000008,
     MIX_INIT_OGG    = 0x00000010,
-    MIX_INIT_MID    = 0x00000020
+    MIX_INIT_MID    = 0x00000020,
+    MIX_INIT_OPUS   = 0x00000040
 } MIX_InitFlags;
 
 /* Loads dynamic libraries and prepares them for use.  Flags should be
@@ -134,7 +135,8 @@ typedef enum {
     MUS_MP3,
     MUS_MP3_MAD_UNUSED,
     MUS_FLAC,
-    MUS_MODPLUG_UNUSED
+    MUS_MODPLUG_UNUSED,
+    MUS_OPUS
 } Mix_MusicType;
 
 /* The internal format for a music chunk interpreted via mikmod */
diff --git a/libs/SDL2_mixer/i686-w64-mingw32/lib/libSDL2_mixer.a b/libs/SDL2_mixer/i686-w64-mingw32/lib/libSDL2_mixer.a
index 9cc3ed19c..5c780be51 100644
Binary files a/libs/SDL2_mixer/i686-w64-mingw32/lib/libSDL2_mixer.a and b/libs/SDL2_mixer/i686-w64-mingw32/lib/libSDL2_mixer.a differ
diff --git a/libs/SDL2_mixer/i686-w64-mingw32/lib/libSDL2_mixer.dll.a b/libs/SDL2_mixer/i686-w64-mingw32/lib/libSDL2_mixer.dll.a
index 6b63de0ee..ac90388f2 100755
Binary files a/libs/SDL2_mixer/i686-w64-mingw32/lib/libSDL2_mixer.dll.a and b/libs/SDL2_mixer/i686-w64-mingw32/lib/libSDL2_mixer.dll.a differ
diff --git a/libs/SDL2_mixer/i686-w64-mingw32/lib/libSDL2_mixer.la b/libs/SDL2_mixer/i686-w64-mingw32/lib/libSDL2_mixer.la
new file mode 100644
index 000000000..f8179ea8c
--- /dev/null
+++ b/libs/SDL2_mixer/i686-w64-mingw32/lib/libSDL2_mixer.la
@@ -0,0 +1,41 @@
+# libSDL2_mixer.la - a libtool library file
+# Generated by ltmain.sh (GNU libtool) 2.2.6
+#
+# Please DO NOT delete this file!
+# It is necessary for linking the library.
+
+# The name that we can dlopen(3).
+dlname='../bin/SDL2_mixer.dll'
+
+# Names of this library.
+library_names='libSDL2_mixer.dll.a'
+
+# The name of the static archive.
+old_library='libSDL2_mixer.a'
+
+# Linker flags that can not go in dependency_libs.
+inherited_linker_flags=''
+
+# Libraries that this one depends upon.
+dependency_libs=' -L/opt/local/i686-w64-mingw32/lib -lmingw32 /opt/local/i686-w64-mingw32/lib/libSDL2.la -ldinput8 -ldxguid -ldxerr8 -luser32 -lgdi32 -limm32 -lole32 -loleaut32 -lshell32 -lsetupapi -lversion -luuid -lwinmm'
+
+# Names of additional weak libraries provided by this library
+weak_library_names=''
+
+# Version information for libSDL2_mixer.
+current=2
+age=2
+revision=2
+
+# Is this an already installed library?
+installed=yes
+
+# Should we warn about portability when linking against -modules?
+shouldnotlink=no
+
+# Files to dlopen/dlpreopen
+dlopen=''
+dlpreopen=''
+
+# Directory that this library needs to be installed in:
+libdir='/Users/valve/release/SDL_mixer/SDL2_mixer-2.0.4/i686-w64-mingw32/lib'
diff --git a/libs/SDL2_mixer/i686-w64-mingw32/lib/pkgconfig/SDL2_mixer.pc b/libs/SDL2_mixer/i686-w64-mingw32/lib/pkgconfig/SDL2_mixer.pc
index 76ba57fab..0b8410993 100644
--- a/libs/SDL2_mixer/i686-w64-mingw32/lib/pkgconfig/SDL2_mixer.pc
+++ b/libs/SDL2_mixer/i686-w64-mingw32/lib/pkgconfig/SDL2_mixer.pc
@@ -1,11 +1,11 @@
-prefix=/usr/local/i686-w64-mingw32
+prefix=/opt/local/i686-w64-mingw32
 exec_prefix=${prefix}
 libdir=${exec_prefix}/lib
 includedir=${prefix}/include
 
 Name: SDL2_mixer
 Description: mixer library for Simple DirectMedia Layer
-Version: 2.0.2
+Version: 2.0.4
 Requires: sdl2 >= 2.0.7
 Libs: -L${libdir} -lSDL2_mixer
 Cflags: -I${includedir}/SDL2
diff --git a/libs/SDL2_mixer/include/SDL_mixer.h b/libs/SDL2_mixer/include/SDL_mixer.h
index cbb8ae6b6..009d8a2da 100644
--- a/libs/SDL2_mixer/include/SDL_mixer.h
+++ b/libs/SDL2_mixer/include/SDL_mixer.h
@@ -1,6 +1,6 @@
 /*
   SDL_mixer:  An audio mixer library based on the SDL library
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
@@ -38,7 +38,7 @@ extern "C" {
 */
 #define SDL_MIXER_MAJOR_VERSION 2
 #define SDL_MIXER_MINOR_VERSION 0
-#define SDL_MIXER_PATCHLEVEL    2
+#define SDL_MIXER_PATCHLEVEL    4
 
 /* This macro can be used to fill a version structure with the compile-time
  * version of the SDL_mixer library.
@@ -80,7 +80,8 @@ typedef enum
     MIX_INIT_MOD    = 0x00000002,
     MIX_INIT_MP3    = 0x00000008,
     MIX_INIT_OGG    = 0x00000010,
-    MIX_INIT_MID    = 0x00000020
+    MIX_INIT_MID    = 0x00000020,
+    MIX_INIT_OPUS   = 0x00000040
 } MIX_InitFlags;
 
 /* Loads dynamic libraries and prepares them for use.  Flags should be
@@ -134,7 +135,8 @@ typedef enum {
     MUS_MP3,
     MUS_MP3_MAD_UNUSED,
     MUS_FLAC,
-    MUS_MODPLUG_UNUSED
+    MUS_MODPLUG_UNUSED,
+    MUS_OPUS
 } Mix_MusicType;
 
 /* The internal format for a music chunk interpreted via mikmod */
diff --git a/libs/SDL2_mixer/lib/x64/LICENSE.FLAC.txt b/libs/SDL2_mixer/lib/x64/LICENSE.FLAC.txt
index 94fd3aa69..2e67b77cb 100644
--- a/libs/SDL2_mixer/lib/x64/LICENSE.FLAC.txt
+++ b/libs/SDL2_mixer/lib/x64/LICENSE.FLAC.txt
@@ -1,5 +1,5 @@
 The source code to this library used with SDL_mixer can be found here:
-http://www.libsdl.org/projects/SDL_mixer/libs/
+https://hg.libsdl.org/SDL_mixer/file/default/external
 ---
 
 Copyright (C) 2000,2001,2002,2003,2004,2005,2006,2007  Josh Coalson
diff --git a/libs/SDL2_mixer/lib/x64/LICENSE.modplug.txt b/libs/SDL2_mixer/lib/x64/LICENSE.modplug.txt
index 59fbf826c..a89532db8 100644
--- a/libs/SDL2_mixer/lib/x64/LICENSE.modplug.txt
+++ b/libs/SDL2_mixer/lib/x64/LICENSE.modplug.txt
@@ -1 +1,5 @@
+The source code to this library used with SDL_mixer can be found here:
+https://hg.libsdl.org/SDL_mixer/file/default/external
+---
+
 ModPlug-XMMS and libmodplug are now in the public domain.
diff --git a/libs/SDL2_mixer/lib/x64/LICENSE.mpg123.txt b/libs/SDL2_mixer/lib/x64/LICENSE.mpg123.txt
index d7bb85fc3..2111cd79f 100644
--- a/libs/SDL2_mixer/lib/x64/LICENSE.mpg123.txt
+++ b/libs/SDL2_mixer/lib/x64/LICENSE.mpg123.txt
@@ -1,3 +1,7 @@
+The source code to this library used with SDL_mixer can be found here:
+https://hg.libsdl.org/SDL_mixer/file/default/external
+---
+
 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:
diff --git a/libs/SDL2_mixer/lib/x64/LICENSE.ogg-vorbis.txt b/libs/SDL2_mixer/lib/x64/LICENSE.ogg-vorbis.txt
index c2cb6d56e..6456dc4ed 100644
--- a/libs/SDL2_mixer/lib/x64/LICENSE.ogg-vorbis.txt
+++ b/libs/SDL2_mixer/lib/x64/LICENSE.ogg-vorbis.txt
@@ -1,5 +1,5 @@
 The source code to this library used with SDL_mixer can be found here:
-http://www.libsdl.org/projects/SDL_mixer/libs/
+https://hg.libsdl.org/SDL_image/file/default/external
 ---
 
 Copyright (c) 2002-2008 Xiph.org Foundation
diff --git a/libs/SDL2_mixer/lib/x64/LICENSE.opus.txt b/libs/SDL2_mixer/lib/x64/LICENSE.opus.txt
new file mode 100644
index 000000000..adb56a854
--- /dev/null
+++ b/libs/SDL2_mixer/lib/x64/LICENSE.opus.txt
@@ -0,0 +1,48 @@
+The source code to this library used with SDL_mixer can be found here:
+https://hg.libsdl.org/SDL_mixer/file/default/external
+---
+
+Copyright 2001-2011 Xiph.Org, Skype Limited, Octasic,
+                    Jean-Marc Valin, Timothy B. Terriberry,
+                    CSIRO, Gregory Maxwell, Mark Borgerding,
+                    Erik de Castro Lopo
+
+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 Internet Society, IETF or IETF Trust, nor the 
+names of specific 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 COPYRIGHT OWNER
+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.
+
+Opus is subject to the royalty-free patent licenses which are
+specified at:
+
+Xiph.Org Foundation:
+https://datatracker.ietf.org/ipr/1524/
+
+Microsoft Corporation:
+https://datatracker.ietf.org/ipr/1914/
+
+Broadcom Corporation:
+https://datatracker.ietf.org/ipr/1526/
diff --git a/libs/SDL2_mixer/lib/x64/LICENSE.opusfile.txt b/libs/SDL2_mixer/lib/x64/LICENSE.opusfile.txt
new file mode 100644
index 000000000..dfc9681fc
--- /dev/null
+++ b/libs/SDL2_mixer/lib/x64/LICENSE.opusfile.txt
@@ -0,0 +1,32 @@
+The source code to this library used with SDL_mixer can be found here:
+https://hg.libsdl.org/SDL_mixer/file/default/external
+---
+
+Copyright (c) 1994-2013 Xiph.Org Foundation and contributors
+
+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/SDL2_mixer/lib/x64/SDL2_mixer.dll b/libs/SDL2_mixer/lib/x64/SDL2_mixer.dll
old mode 100755
new mode 100644
index 116bb1df6..40bb1c146
Binary files a/libs/SDL2_mixer/lib/x64/SDL2_mixer.dll and b/libs/SDL2_mixer/lib/x64/SDL2_mixer.dll differ
diff --git a/libs/SDL2_mixer/lib/x64/SDL2_mixer.lib b/libs/SDL2_mixer/lib/x64/SDL2_mixer.lib
old mode 100755
new mode 100644
diff --git a/libs/SDL2_mixer/lib/x64/libFLAC-8.dll b/libs/SDL2_mixer/lib/x64/libFLAC-8.dll
old mode 100755
new mode 100644
index b5603902d..71f2e19d9
Binary files a/libs/SDL2_mixer/lib/x64/libFLAC-8.dll and b/libs/SDL2_mixer/lib/x64/libFLAC-8.dll differ
diff --git a/libs/SDL2_mixer/lib/x64/libmodplug-1.dll b/libs/SDL2_mixer/lib/x64/libmodplug-1.dll
old mode 100755
new mode 100644
index 31509378b..7c0512674
Binary files a/libs/SDL2_mixer/lib/x64/libmodplug-1.dll and b/libs/SDL2_mixer/lib/x64/libmodplug-1.dll differ
diff --git a/libs/SDL2_mixer/lib/x64/libmpg123-0.dll b/libs/SDL2_mixer/lib/x64/libmpg123-0.dll
old mode 100755
new mode 100644
index d222d2dc5..c7809b163
Binary files a/libs/SDL2_mixer/lib/x64/libmpg123-0.dll and b/libs/SDL2_mixer/lib/x64/libmpg123-0.dll differ
diff --git a/libs/SDL2_mixer/lib/x64/libogg-0.dll b/libs/SDL2_mixer/lib/x64/libogg-0.dll
old mode 100755
new mode 100644
index 7b94e6032..513348159
Binary files a/libs/SDL2_mixer/lib/x64/libogg-0.dll and b/libs/SDL2_mixer/lib/x64/libogg-0.dll differ
diff --git a/libs/SDL2_mixer/lib/x64/libopus-0.dll b/libs/SDL2_mixer/lib/x64/libopus-0.dll
new file mode 100644
index 000000000..9ba6c3860
Binary files /dev/null and b/libs/SDL2_mixer/lib/x64/libopus-0.dll differ
diff --git a/libs/SDL2_mixer/lib/x64/libopusfile-0.dll b/libs/SDL2_mixer/lib/x64/libopusfile-0.dll
new file mode 100644
index 000000000..97a88b610
Binary files /dev/null and b/libs/SDL2_mixer/lib/x64/libopusfile-0.dll differ
diff --git a/libs/SDL2_mixer/lib/x64/libvorbis-0.dll b/libs/SDL2_mixer/lib/x64/libvorbis-0.dll
old mode 100755
new mode 100644
index 8d8d6537b..f5ae1bf75
Binary files a/libs/SDL2_mixer/lib/x64/libvorbis-0.dll and b/libs/SDL2_mixer/lib/x64/libvorbis-0.dll differ
diff --git a/libs/SDL2_mixer/lib/x64/libvorbisfile-3.dll b/libs/SDL2_mixer/lib/x64/libvorbisfile-3.dll
old mode 100755
new mode 100644
index 08f8f7aa8..d0787368a
Binary files a/libs/SDL2_mixer/lib/x64/libvorbisfile-3.dll and b/libs/SDL2_mixer/lib/x64/libvorbisfile-3.dll differ
diff --git a/libs/SDL2_mixer/lib/x86/LICENSE.FLAC.txt b/libs/SDL2_mixer/lib/x86/LICENSE.FLAC.txt
index 94fd3aa69..2e67b77cb 100644
--- a/libs/SDL2_mixer/lib/x86/LICENSE.FLAC.txt
+++ b/libs/SDL2_mixer/lib/x86/LICENSE.FLAC.txt
@@ -1,5 +1,5 @@
 The source code to this library used with SDL_mixer can be found here:
-http://www.libsdl.org/projects/SDL_mixer/libs/
+https://hg.libsdl.org/SDL_mixer/file/default/external
 ---
 
 Copyright (C) 2000,2001,2002,2003,2004,2005,2006,2007  Josh Coalson
diff --git a/libs/SDL2_mixer/lib/x86/LICENSE.modplug.txt b/libs/SDL2_mixer/lib/x86/LICENSE.modplug.txt
index 59fbf826c..a89532db8 100644
--- a/libs/SDL2_mixer/lib/x86/LICENSE.modplug.txt
+++ b/libs/SDL2_mixer/lib/x86/LICENSE.modplug.txt
@@ -1 +1,5 @@
+The source code to this library used with SDL_mixer can be found here:
+https://hg.libsdl.org/SDL_mixer/file/default/external
+---
+
 ModPlug-XMMS and libmodplug are now in the public domain.
diff --git a/libs/SDL2_mixer/lib/x86/LICENSE.mpg123.txt b/libs/SDL2_mixer/lib/x86/LICENSE.mpg123.txt
index d7bb85fc3..2111cd79f 100644
--- a/libs/SDL2_mixer/lib/x86/LICENSE.mpg123.txt
+++ b/libs/SDL2_mixer/lib/x86/LICENSE.mpg123.txt
@@ -1,3 +1,7 @@
+The source code to this library used with SDL_mixer can be found here:
+https://hg.libsdl.org/SDL_mixer/file/default/external
+---
+
 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:
diff --git a/libs/SDL2_mixer/lib/x86/LICENSE.ogg-vorbis.txt b/libs/SDL2_mixer/lib/x86/LICENSE.ogg-vorbis.txt
index c2cb6d56e..6456dc4ed 100644
--- a/libs/SDL2_mixer/lib/x86/LICENSE.ogg-vorbis.txt
+++ b/libs/SDL2_mixer/lib/x86/LICENSE.ogg-vorbis.txt
@@ -1,5 +1,5 @@
 The source code to this library used with SDL_mixer can be found here:
-http://www.libsdl.org/projects/SDL_mixer/libs/
+https://hg.libsdl.org/SDL_image/file/default/external
 ---
 
 Copyright (c) 2002-2008 Xiph.org Foundation
diff --git a/libs/SDL2_mixer/lib/x86/LICENSE.opus.txt b/libs/SDL2_mixer/lib/x86/LICENSE.opus.txt
new file mode 100644
index 000000000..adb56a854
--- /dev/null
+++ b/libs/SDL2_mixer/lib/x86/LICENSE.opus.txt
@@ -0,0 +1,48 @@
+The source code to this library used with SDL_mixer can be found here:
+https://hg.libsdl.org/SDL_mixer/file/default/external
+---
+
+Copyright 2001-2011 Xiph.Org, Skype Limited, Octasic,
+                    Jean-Marc Valin, Timothy B. Terriberry,
+                    CSIRO, Gregory Maxwell, Mark Borgerding,
+                    Erik de Castro Lopo
+
+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 Internet Society, IETF or IETF Trust, nor the 
+names of specific 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 COPYRIGHT OWNER
+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.
+
+Opus is subject to the royalty-free patent licenses which are
+specified at:
+
+Xiph.Org Foundation:
+https://datatracker.ietf.org/ipr/1524/
+
+Microsoft Corporation:
+https://datatracker.ietf.org/ipr/1914/
+
+Broadcom Corporation:
+https://datatracker.ietf.org/ipr/1526/
diff --git a/libs/SDL2_mixer/lib/x86/LICENSE.opusfile.txt b/libs/SDL2_mixer/lib/x86/LICENSE.opusfile.txt
new file mode 100644
index 000000000..dfc9681fc
--- /dev/null
+++ b/libs/SDL2_mixer/lib/x86/LICENSE.opusfile.txt
@@ -0,0 +1,32 @@
+The source code to this library used with SDL_mixer can be found here:
+https://hg.libsdl.org/SDL_mixer/file/default/external
+---
+
+Copyright (c) 1994-2013 Xiph.Org Foundation and contributors
+
+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/SDL2_mixer/lib/x86/SDL2_mixer.dll b/libs/SDL2_mixer/lib/x86/SDL2_mixer.dll
old mode 100755
new mode 100644
index 54ebbb1d4..96abfa1ab
Binary files a/libs/SDL2_mixer/lib/x86/SDL2_mixer.dll and b/libs/SDL2_mixer/lib/x86/SDL2_mixer.dll differ
diff --git a/libs/SDL2_mixer/lib/x86/SDL2_mixer.lib b/libs/SDL2_mixer/lib/x86/SDL2_mixer.lib
old mode 100755
new mode 100644
diff --git a/libs/SDL2_mixer/lib/x86/libFLAC-8.dll b/libs/SDL2_mixer/lib/x86/libFLAC-8.dll
old mode 100755
new mode 100644
index 1c55ad496..b56ea2a8c
Binary files a/libs/SDL2_mixer/lib/x86/libFLAC-8.dll and b/libs/SDL2_mixer/lib/x86/libFLAC-8.dll differ
diff --git a/libs/SDL2_mixer/lib/x86/libmodplug-1.dll b/libs/SDL2_mixer/lib/x86/libmodplug-1.dll
old mode 100755
new mode 100644
index a2cba0d6b..d66a317dd
Binary files a/libs/SDL2_mixer/lib/x86/libmodplug-1.dll and b/libs/SDL2_mixer/lib/x86/libmodplug-1.dll differ
diff --git a/libs/SDL2_mixer/lib/x86/libmpg123-0.dll b/libs/SDL2_mixer/lib/x86/libmpg123-0.dll
old mode 100755
new mode 100644
index ca7de300d..240298bbf
Binary files a/libs/SDL2_mixer/lib/x86/libmpg123-0.dll and b/libs/SDL2_mixer/lib/x86/libmpg123-0.dll differ
diff --git a/libs/SDL2_mixer/lib/x86/libogg-0.dll b/libs/SDL2_mixer/lib/x86/libogg-0.dll
old mode 100755
new mode 100644
index 3abe6ebfc..233c0f42a
Binary files a/libs/SDL2_mixer/lib/x86/libogg-0.dll and b/libs/SDL2_mixer/lib/x86/libogg-0.dll differ
diff --git a/libs/SDL2_mixer/lib/x86/libopus-0.dll b/libs/SDL2_mixer/lib/x86/libopus-0.dll
new file mode 100644
index 000000000..94ea541d2
Binary files /dev/null and b/libs/SDL2_mixer/lib/x86/libopus-0.dll differ
diff --git a/libs/SDL2_mixer/lib/x86/libopusfile-0.dll b/libs/SDL2_mixer/lib/x86/libopusfile-0.dll
new file mode 100644
index 000000000..260796b6a
Binary files /dev/null and b/libs/SDL2_mixer/lib/x86/libopusfile-0.dll differ
diff --git a/libs/SDL2_mixer/lib/x86/libvorbis-0.dll b/libs/SDL2_mixer/lib/x86/libvorbis-0.dll
old mode 100755
new mode 100644
index 4e44ef088..4e4aaa543
Binary files a/libs/SDL2_mixer/lib/x86/libvorbis-0.dll and b/libs/SDL2_mixer/lib/x86/libvorbis-0.dll differ
diff --git a/libs/SDL2_mixer/lib/x86/libvorbisfile-3.dll b/libs/SDL2_mixer/lib/x86/libvorbisfile-3.dll
old mode 100755
new mode 100644
index e757eb6de..5d90a235c
Binary files a/libs/SDL2_mixer/lib/x86/libvorbisfile-3.dll and b/libs/SDL2_mixer/lib/x86/libvorbisfile-3.dll differ
diff --git a/libs/SDL2_mixer/x86_64-w64-mingw32/bin/LICENSE.FLAC.txt b/libs/SDL2_mixer/x86_64-w64-mingw32/bin/LICENSE.FLAC.txt
index 94fd3aa69..2e67b77cb 100644
--- a/libs/SDL2_mixer/x86_64-w64-mingw32/bin/LICENSE.FLAC.txt
+++ b/libs/SDL2_mixer/x86_64-w64-mingw32/bin/LICENSE.FLAC.txt
@@ -1,5 +1,5 @@
 The source code to this library used with SDL_mixer can be found here:
-http://www.libsdl.org/projects/SDL_mixer/libs/
+https://hg.libsdl.org/SDL_mixer/file/default/external
 ---
 
 Copyright (C) 2000,2001,2002,2003,2004,2005,2006,2007  Josh Coalson
diff --git a/libs/SDL2_mixer/x86_64-w64-mingw32/bin/LICENSE.modplug.txt b/libs/SDL2_mixer/x86_64-w64-mingw32/bin/LICENSE.modplug.txt
index 59fbf826c..a89532db8 100644
--- a/libs/SDL2_mixer/x86_64-w64-mingw32/bin/LICENSE.modplug.txt
+++ b/libs/SDL2_mixer/x86_64-w64-mingw32/bin/LICENSE.modplug.txt
@@ -1 +1,5 @@
+The source code to this library used with SDL_mixer can be found here:
+https://hg.libsdl.org/SDL_mixer/file/default/external
+---
+
 ModPlug-XMMS and libmodplug are now in the public domain.
diff --git a/libs/SDL2_mixer/x86_64-w64-mingw32/bin/LICENSE.mpg123.txt b/libs/SDL2_mixer/x86_64-w64-mingw32/bin/LICENSE.mpg123.txt
index d7bb85fc3..2111cd79f 100644
--- a/libs/SDL2_mixer/x86_64-w64-mingw32/bin/LICENSE.mpg123.txt
+++ b/libs/SDL2_mixer/x86_64-w64-mingw32/bin/LICENSE.mpg123.txt
@@ -1,3 +1,7 @@
+The source code to this library used with SDL_mixer can be found here:
+https://hg.libsdl.org/SDL_mixer/file/default/external
+---
+
 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:
diff --git a/libs/SDL2_mixer/x86_64-w64-mingw32/bin/LICENSE.ogg-vorbis.txt b/libs/SDL2_mixer/x86_64-w64-mingw32/bin/LICENSE.ogg-vorbis.txt
index c2cb6d56e..6456dc4ed 100644
--- a/libs/SDL2_mixer/x86_64-w64-mingw32/bin/LICENSE.ogg-vorbis.txt
+++ b/libs/SDL2_mixer/x86_64-w64-mingw32/bin/LICENSE.ogg-vorbis.txt
@@ -1,5 +1,5 @@
 The source code to this library used with SDL_mixer can be found here:
-http://www.libsdl.org/projects/SDL_mixer/libs/
+https://hg.libsdl.org/SDL_image/file/default/external
 ---
 
 Copyright (c) 2002-2008 Xiph.org Foundation
diff --git a/libs/SDL2_mixer/x86_64-w64-mingw32/bin/LICENSE.opus.txt b/libs/SDL2_mixer/x86_64-w64-mingw32/bin/LICENSE.opus.txt
new file mode 100644
index 000000000..adb56a854
--- /dev/null
+++ b/libs/SDL2_mixer/x86_64-w64-mingw32/bin/LICENSE.opus.txt
@@ -0,0 +1,48 @@
+The source code to this library used with SDL_mixer can be found here:
+https://hg.libsdl.org/SDL_mixer/file/default/external
+---
+
+Copyright 2001-2011 Xiph.Org, Skype Limited, Octasic,
+                    Jean-Marc Valin, Timothy B. Terriberry,
+                    CSIRO, Gregory Maxwell, Mark Borgerding,
+                    Erik de Castro Lopo
+
+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 Internet Society, IETF or IETF Trust, nor the 
+names of specific 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 COPYRIGHT OWNER
+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.
+
+Opus is subject to the royalty-free patent licenses which are
+specified at:
+
+Xiph.Org Foundation:
+https://datatracker.ietf.org/ipr/1524/
+
+Microsoft Corporation:
+https://datatracker.ietf.org/ipr/1914/
+
+Broadcom Corporation:
+https://datatracker.ietf.org/ipr/1526/
diff --git a/libs/SDL2_mixer/x86_64-w64-mingw32/bin/LICENSE.opusfile.txt b/libs/SDL2_mixer/x86_64-w64-mingw32/bin/LICENSE.opusfile.txt
new file mode 100644
index 000000000..dfc9681fc
--- /dev/null
+++ b/libs/SDL2_mixer/x86_64-w64-mingw32/bin/LICENSE.opusfile.txt
@@ -0,0 +1,32 @@
+The source code to this library used with SDL_mixer can be found here:
+https://hg.libsdl.org/SDL_mixer/file/default/external
+---
+
+Copyright (c) 1994-2013 Xiph.Org Foundation and contributors
+
+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/SDL2_mixer/x86_64-w64-mingw32/bin/SDL2_mixer.dll b/libs/SDL2_mixer/x86_64-w64-mingw32/bin/SDL2_mixer.dll
index 116bb1df6..40bb1c146 100755
Binary files a/libs/SDL2_mixer/x86_64-w64-mingw32/bin/SDL2_mixer.dll and b/libs/SDL2_mixer/x86_64-w64-mingw32/bin/SDL2_mixer.dll differ
diff --git a/libs/SDL2_mixer/x86_64-w64-mingw32/bin/libFLAC-8.dll b/libs/SDL2_mixer/x86_64-w64-mingw32/bin/libFLAC-8.dll
index b5603902d..71f2e19d9 100755
Binary files a/libs/SDL2_mixer/x86_64-w64-mingw32/bin/libFLAC-8.dll and b/libs/SDL2_mixer/x86_64-w64-mingw32/bin/libFLAC-8.dll differ
diff --git a/libs/SDL2_mixer/x86_64-w64-mingw32/bin/libmodplug-1.dll b/libs/SDL2_mixer/x86_64-w64-mingw32/bin/libmodplug-1.dll
index 31509378b..7c0512674 100755
Binary files a/libs/SDL2_mixer/x86_64-w64-mingw32/bin/libmodplug-1.dll and b/libs/SDL2_mixer/x86_64-w64-mingw32/bin/libmodplug-1.dll differ
diff --git a/libs/SDL2_mixer/x86_64-w64-mingw32/bin/libmpg123-0.dll b/libs/SDL2_mixer/x86_64-w64-mingw32/bin/libmpg123-0.dll
index d222d2dc5..c7809b163 100755
Binary files a/libs/SDL2_mixer/x86_64-w64-mingw32/bin/libmpg123-0.dll and b/libs/SDL2_mixer/x86_64-w64-mingw32/bin/libmpg123-0.dll differ
diff --git a/libs/SDL2_mixer/x86_64-w64-mingw32/bin/libogg-0.dll b/libs/SDL2_mixer/x86_64-w64-mingw32/bin/libogg-0.dll
index 7b94e6032..513348159 100755
Binary files a/libs/SDL2_mixer/x86_64-w64-mingw32/bin/libogg-0.dll and b/libs/SDL2_mixer/x86_64-w64-mingw32/bin/libogg-0.dll differ
diff --git a/libs/SDL2_mixer/x86_64-w64-mingw32/bin/libopus-0.dll b/libs/SDL2_mixer/x86_64-w64-mingw32/bin/libopus-0.dll
new file mode 100644
index 000000000..9ba6c3860
Binary files /dev/null and b/libs/SDL2_mixer/x86_64-w64-mingw32/bin/libopus-0.dll differ
diff --git a/libs/SDL2_mixer/x86_64-w64-mingw32/bin/libopusfile-0.dll b/libs/SDL2_mixer/x86_64-w64-mingw32/bin/libopusfile-0.dll
new file mode 100644
index 000000000..97a88b610
Binary files /dev/null and b/libs/SDL2_mixer/x86_64-w64-mingw32/bin/libopusfile-0.dll differ
diff --git a/libs/SDL2_mixer/x86_64-w64-mingw32/bin/libvorbis-0.dll b/libs/SDL2_mixer/x86_64-w64-mingw32/bin/libvorbis-0.dll
index 8d8d6537b..f5ae1bf75 100755
Binary files a/libs/SDL2_mixer/x86_64-w64-mingw32/bin/libvorbis-0.dll and b/libs/SDL2_mixer/x86_64-w64-mingw32/bin/libvorbis-0.dll differ
diff --git a/libs/SDL2_mixer/x86_64-w64-mingw32/bin/libvorbisfile-3.dll b/libs/SDL2_mixer/x86_64-w64-mingw32/bin/libvorbisfile-3.dll
index 08f8f7aa8..d0787368a 100755
Binary files a/libs/SDL2_mixer/x86_64-w64-mingw32/bin/libvorbisfile-3.dll and b/libs/SDL2_mixer/x86_64-w64-mingw32/bin/libvorbisfile-3.dll differ
diff --git a/libs/SDL2_mixer/x86_64-w64-mingw32/include/SDL2/SDL_mixer.h b/libs/SDL2_mixer/x86_64-w64-mingw32/include/SDL2/SDL_mixer.h
index cbb8ae6b6..009d8a2da 100644
--- a/libs/SDL2_mixer/x86_64-w64-mingw32/include/SDL2/SDL_mixer.h
+++ b/libs/SDL2_mixer/x86_64-w64-mingw32/include/SDL2/SDL_mixer.h
@@ -1,6 +1,6 @@
 /*
   SDL_mixer:  An audio mixer library based on the SDL library
-  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
@@ -38,7 +38,7 @@ extern "C" {
 */
 #define SDL_MIXER_MAJOR_VERSION 2
 #define SDL_MIXER_MINOR_VERSION 0
-#define SDL_MIXER_PATCHLEVEL    2
+#define SDL_MIXER_PATCHLEVEL    4
 
 /* This macro can be used to fill a version structure with the compile-time
  * version of the SDL_mixer library.
@@ -80,7 +80,8 @@ typedef enum
     MIX_INIT_MOD    = 0x00000002,
     MIX_INIT_MP3    = 0x00000008,
     MIX_INIT_OGG    = 0x00000010,
-    MIX_INIT_MID    = 0x00000020
+    MIX_INIT_MID    = 0x00000020,
+    MIX_INIT_OPUS   = 0x00000040
 } MIX_InitFlags;
 
 /* Loads dynamic libraries and prepares them for use.  Flags should be
@@ -134,7 +135,8 @@ typedef enum {
     MUS_MP3,
     MUS_MP3_MAD_UNUSED,
     MUS_FLAC,
-    MUS_MODPLUG_UNUSED
+    MUS_MODPLUG_UNUSED,
+    MUS_OPUS
 } Mix_MusicType;
 
 /* The internal format for a music chunk interpreted via mikmod */
diff --git a/libs/SDL2_mixer/x86_64-w64-mingw32/lib/libSDL2_mixer.a b/libs/SDL2_mixer/x86_64-w64-mingw32/lib/libSDL2_mixer.a
index 7d39a1f63..b6483716e 100644
Binary files a/libs/SDL2_mixer/x86_64-w64-mingw32/lib/libSDL2_mixer.a and b/libs/SDL2_mixer/x86_64-w64-mingw32/lib/libSDL2_mixer.a differ
diff --git a/libs/SDL2_mixer/x86_64-w64-mingw32/lib/libSDL2_mixer.dll.a b/libs/SDL2_mixer/x86_64-w64-mingw32/lib/libSDL2_mixer.dll.a
index d812f5c85..82a4bef08 100755
Binary files a/libs/SDL2_mixer/x86_64-w64-mingw32/lib/libSDL2_mixer.dll.a and b/libs/SDL2_mixer/x86_64-w64-mingw32/lib/libSDL2_mixer.dll.a differ
diff --git a/libs/SDL2_mixer/x86_64-w64-mingw32/lib/libSDL2_mixer.la b/libs/SDL2_mixer/x86_64-w64-mingw32/lib/libSDL2_mixer.la
new file mode 100644
index 000000000..dba212c5a
--- /dev/null
+++ b/libs/SDL2_mixer/x86_64-w64-mingw32/lib/libSDL2_mixer.la
@@ -0,0 +1,41 @@
+# libSDL2_mixer.la - a libtool library file
+# Generated by ltmain.sh (GNU libtool) 2.2.6
+#
+# Please DO NOT delete this file!
+# It is necessary for linking the library.
+
+# The name that we can dlopen(3).
+dlname='../bin/SDL2_mixer.dll'
+
+# Names of this library.
+library_names='libSDL2_mixer.dll.a'
+
+# The name of the static archive.
+old_library='libSDL2_mixer.a'
+
+# Linker flags that can not go in dependency_libs.
+inherited_linker_flags=''
+
+# Libraries that this one depends upon.
+dependency_libs=' -L/opt/local/x86_64-w64-mingw32/lib -lmingw32 /opt/local/x86_64-w64-mingw32/lib/libSDL2.la -ldinput8 -ldxguid -ldxerr8 -luser32 -lgdi32 -limm32 -lole32 -loleaut32 -lshell32 -lsetupapi -lversion -luuid -lwinmm'
+
+# Names of additional weak libraries provided by this library
+weak_library_names=''
+
+# Version information for libSDL2_mixer.
+current=2
+age=2
+revision=2
+
+# Is this an already installed library?
+installed=yes
+
+# Should we warn about portability when linking against -modules?
+shouldnotlink=no
+
+# Files to dlopen/dlpreopen
+dlopen=''
+dlpreopen=''
+
+# Directory that this library needs to be installed in:
+libdir='/Users/valve/release/SDL_mixer/SDL2_mixer-2.0.4/x86_64-w64-mingw32/lib'
diff --git a/libs/SDL2_mixer/x86_64-w64-mingw32/lib/pkgconfig/SDL2_mixer.pc b/libs/SDL2_mixer/x86_64-w64-mingw32/lib/pkgconfig/SDL2_mixer.pc
index 56c30ccfe..b7984169f 100644
--- a/libs/SDL2_mixer/x86_64-w64-mingw32/lib/pkgconfig/SDL2_mixer.pc
+++ b/libs/SDL2_mixer/x86_64-w64-mingw32/lib/pkgconfig/SDL2_mixer.pc
@@ -1,11 +1,11 @@
-prefix=/usr/local/x86_64-w64-mingw32
+prefix=/opt/local/x86_64-w64-mingw32
 exec_prefix=${prefix}
 libdir=${exec_prefix}/lib
 includedir=${prefix}/include
 
 Name: SDL2_mixer
 Description: mixer library for Simple DirectMedia Layer
-Version: 2.0.2
+Version: 2.0.4
 Requires: sdl2 >= 2.0.7
 Libs: -L${libdir} -lSDL2_mixer
 Cflags: -I${includedir}/SDL2
diff --git a/libs/gme/win64/libgme.dll.a b/libs/gme/win64/libgme.dll.a
new file mode 100644
index 000000000..38079dc2a
Binary files /dev/null and b/libs/gme/win64/libgme.dll.a differ
diff --git a/srb2.png b/srb2.png
index 9c13eae9a..72a08f664 100644
Binary files a/srb2.png and b/srb2.png differ
diff --git a/srb2banner.png b/srb2banner.png
new file mode 100644
index 000000000..9c13eae9a
Binary files /dev/null and b/srb2banner.png differ
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 46a42a92c..99f2beebe 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -227,6 +227,12 @@ set(SRB2_CONFIG_YASM OFF CACHE BOOL
 set(SRB2_CONFIG_STATIC_OPENGL OFF CACHE BOOL
 	"Use statically linked OpenGL. NOT RECOMMENDED.")
 
+### use internal libraries?
+if(${CMAKE_SYSTEM} MATCHES "Windows") ###set on Windows only
+	set(SRB2_CONFIG_USE_INTERNAL_LIBRARIES OFF CACHE BOOL
+	"Use SRB2's internal copies of required dependencies (SDL2, PNG, zlib, GME).")
+endif()
+
 if(${SRB2_CONFIG_HAVE_BLUA})
 	add_definitions(-DHAVE_BLUA)
 	set(SRB2_LUA_SOURCES
@@ -314,7 +320,17 @@ if(${SRB2_CONFIG_HAVE_BLUA})
 endif()
 
 if(${SRB2_CONFIG_HAVE_GME})
-	find_package(GME)
+	if(${SRB2_CONFIG_USE_INTERNAL_LIBRARIES})
+		set(GME_FOUND ON)
+		set(GME_INCLUDE_DIRS ${CMAKE_SOURCE_DIR}/libs/gme/include)
+        if(${SRB2_SYSTEM_BITS} EQUAL 64)
+			set(GME_LIBRARIES "-L${CMAKE_SOURCE_DIR}/libs/gme/win64 -lgme")
+		else() # 32-bit
+			set(GME_LIBRARIES "-L${CMAKE_SOURCE_DIR}/libs/gme/win32 -lgme")
+		endif()
+	else()
+		find_package(GME)
+	endif()
 	if(${GME_FOUND})
 		set(SRB2_HAVE_GME ON)
 		add_definitions(-DHAVE_LIBGME)
@@ -324,9 +340,20 @@ if(${SRB2_CONFIG_HAVE_GME})
 endif()
 
 if(${SRB2_CONFIG_HAVE_ZLIB})
-	find_package(ZLIB)
+	if(${SRB2_CONFIG_USE_INTERNAL_LIBRARIES})
+		set(ZLIB_FOUND ON)
+		set(ZLIB_INCLUDE_DIRS ${CMAKE_SOURCE_DIR}/libs/zlib)
+		if(${SRB2_SYSTEM_BITS} EQUAL 64)
+			set(ZLIB_LIBRARIES "-L${CMAKE_SOURCE_DIR}/libs/zlib/win32 -lz64")
+		else() # 32-bit
+			set(ZLIB_LIBRARIES "-L${CMAKE_SOURCE_DIR}/libs/zlib/win32 -lz32")
+		endif()
+	else()
+		find_package(ZLIB)
+	endif()
 	if(${ZLIB_FOUND})
 		set(SRB2_HAVE_ZLIB ON)
+		add_definitions(-DHAVE_ZLIB)
 	else()
 		message(WARNING "You have specified that ZLIB is available but it was not found. SRB2 may not compile correctly.")
 	endif()
@@ -334,7 +361,17 @@ endif()
 
 if(${SRB2_CONFIG_HAVE_PNG} AND ${SRB2_CONFIG_HAVE_ZLIB})
 	if (${ZLIB_FOUND})
-		find_package(PNG)
+		if(${SRB2_CONFIG_USE_INTERNAL_LIBRARIES})
+			set(PNG_FOUND ON)
+			set(PNG_INCLUDE_DIRS ${CMAKE_SOURCE_DIR}/libs/libpng-src)
+			if(${SRB2_SYSTEM_BITS} EQUAL 64)
+				set(PNG_LIBRARIES "-L${CMAKE_SOURCE_DIR}/libs/libpng-src/projects -lpng64")
+			else() # 32-bit
+				set(PNG_LIBRARIES "-L${CMAKE_SOURCE_DIR}/libs/libpng-src/projects -lpng32")
+			endif()
+		else()
+			find_package(PNG)
+		endif()
 		if(${PNG_FOUND})
 			set(SRB2_HAVE_PNG ON)
 			add_definitions(-DHAVE_PNG)
@@ -350,6 +387,7 @@ if(${SRB2_CONFIG_HWRENDER})
 	set(SRB2_HWRENDER_SOURCES
 		${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_bsp.c
 		${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_cache.c
+		${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_clip.c
 		${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_draw.c
 		${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_light.c
 		${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_main.c
@@ -358,6 +396,7 @@ if(${SRB2_CONFIG_HWRENDER})
 	)
 
 	set (SRB2_HWRENDER_HEADERS
+		${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_clip.h
 		${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_data.h
 		${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_defs.h
 		${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_dll.h
diff --git a/src/Makefile b/src/Makefile
index dd250b0bc..fbf75f26c 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -2,7 +2,7 @@
 #     GNU Make makefile for SRB2
 #############################################################################
 # Copyright (C) 1998-2000 by DooM Legacy Team.
-# Copyright (C) 2003-2014 by Sonic Team Junior.
+# Copyright (C) 2003-2018 by Sonic Team Junior.
 #
 # This program is free software distributed under the
 # terms of the GNU General Public License, version 2.
@@ -66,6 +66,7 @@
 #     Compile without 3D sound support, add 'NOHS=1'
 #     Compile with GDBstubs, add 'RDB=1'
 #     Compile without PNG, add 'NOPNG=1'
+#     Compile without zlib, add 'NOZLIB=1'
 #
 # Addon for SDL:
 #     To Cross-Compile, add 'SDL_CONFIG=/usr/*/bin/sdl-config'
@@ -119,6 +120,7 @@ include Makefile.cfg
 
 ifdef DUMMY
 NOPNG=1
+NOZLIB=1
 NONET=1
 NOHW=1
 NOHS=1
@@ -174,6 +176,11 @@ ifdef MINGW
 include win32/Makefile.cfg
 endif #ifdef MINGW
 
+ifdef MINGW64
+MINGW=1
+include win32/Makefile.cfg
+endif #ifdef MINGW64
+
 ifdef UNIX
 UNIXCOMMON=1
 endif
@@ -199,6 +206,7 @@ endif
 
 ifdef NDS
 NOPNG=1
+NOZLIB=1
 NONET=1
 #NOHW=1
 NOHS=1
@@ -266,7 +274,7 @@ ifndef DC
 endif
 	OPTS+=-DHWRENDER
 	OBJS+=$(OBJDIR)/hw_bsp.o $(OBJDIR)/hw_draw.o $(OBJDIR)/hw_light.o \
-		 $(OBJDIR)/hw_main.o $(OBJDIR)/hw_md2.o $(OBJDIR)/hw_cache.o $(OBJDIR)/hw_trick.o
+		 $(OBJDIR)/hw_main.o $(OBJDIR)/hw_clip.o $(OBJDIR)/hw_md2.o $(OBJDIR)/hw_cache.o $(OBJDIR)/hw_trick.o
 endif
 
 ifdef NOHS
@@ -325,13 +333,6 @@ LIBS+=$(PNG_LDFLAGS)
 CFLAGS+=$(PNG_CFLAGS)
 endif
 
-ZLIB_PKGCONFIG?=zlib
-ZLIB_CFLAGS?=$(shell $(PKG_CONFIG) $(ZLIB_PKGCONFIG) --cflags)
-ZLIB_LDFLAGS?=$(shell $(PKG_CONFIG) $(ZLIB_PKGCONFIG) --libs)
-
-LIBS+=$(ZLIB_LDFLAGS)
-CFLAGS+=$(ZLIB_CFLAGS)
-
 ifdef HAVE_LIBGME
 OPTS+=-DHAVE_LIBGME
 
@@ -343,6 +344,18 @@ LIBS+=$(LIBGME_LDFLAGS)
 CFLAGS+=$(LIBGME_CFLAGS)
 endif
 
+ifndef NOZLIB
+OPTS+=-DHAVE_ZLIB
+ZLIB_PKGCONFIG?=zlib
+ZLIB_CFLAGS?=$(shell $(PKG_CONFIG) $(ZLIB_PKGCONFIG) --cflags)
+ZLIB_LDFLAGS?=$(shell $(PKG_CONFIG) $(ZLIB_PKGCONFIG) --libs)
+
+LIBS+=$(ZLIB_LDFLAGS)
+CFLAGS+=$(ZLIB_CFLAGS)
+else
+NOPNG=1
+endif
+
 ifdef STATIC
 LIBS:=-static $(LIBS)
 endif
@@ -702,7 +715,6 @@ $(BIN)/s_openal.so: $(OBJDIR)/s_openal.o
 	-$(MKDIR) $(BIN)
 	@echo Linking S_OpenAL.so...
 	$(CC) --shared $^ -o $@ -g --nostartfiles -lm -lopenal
-
 endif
 
 else
@@ -711,7 +723,7 @@ ifdef MINGW
 $(OBJDIR)/r_opengl.o: hardware/r_opengl/r_opengl.c hardware/r_opengl/r_opengl.h \
  doomdef.h doomtype.h g_state.h m_swap.h hardware/hw_drv.h screen.h \
  command.h hardware/hw_data.h hardware/hw_glide.h hardware/hw_defs.h \
- hardware/hw_md2.h hardware/hw_glob.h hardware/hw_main.h am_map.h \
+ hardware/hw_md2.h hardware/hw_glob.h hardware/hw_main.h hardware/hw_clip.h am_map.h \
  d_event.h d_player.h p_pspr.h m_fixed.h tables.h info.h d_think.h \
  p_mobj.h doomdata.h d_ticcmd.h r_defs.h hardware/hw_dll.h
 	$(CC) $(CFLAGS) $(WFLAGS) -c $< -o $@
@@ -719,7 +731,7 @@ else
 $(OBJDIR)/r_opengl.o: hardware/r_opengl/r_opengl.c hardware/r_opengl/r_opengl.h \
  doomdef.h doomtype.h g_state.h m_swap.h hardware/hw_drv.h screen.h \
  command.h hardware/hw_data.h hardware/hw_glide.h hardware/hw_defs.h \
- hardware/hw_md2.h hardware/hw_glob.h hardware/hw_main.h am_map.h \
+ hardware/hw_md2.h hardware/hw_glob.h hardware/hw_main.h hardware/hw_clip.h am_map.h \
  d_event.h d_player.h p_pspr.h m_fixed.h tables.h info.h d_think.h \
  p_mobj.h doomdata.h d_ticcmd.h r_defs.h hardware/hw_dll.h
 	$(CC) $(CFLAGS) $(WFLAGS) -I/usr/X11R6/include -c $< -o $@
@@ -872,7 +884,7 @@ ifndef NOHW
 $(OBJDIR)/r_opengl.o: hardware/r_opengl/r_opengl.c hardware/r_opengl/r_opengl.h \
  doomdef.h doomtype.h g_state.h m_swap.h hardware/hw_drv.h screen.h \
  command.h hardware/hw_data.h hardware/hw_glide.h hardware/hw_defs.h \
- hardware/hw_md2.h hardware/hw_glob.h hardware/hw_main.h am_map.h \
+ hardware/hw_md2.h hardware/hw_glob.h hardware/hw_main.h hardware/hw_clip.h am_map.h \
  d_event.h d_player.h p_pspr.h m_fixed.h tables.h info.h d_think.h \
  p_mobj.h doomdata.h d_ticcmd.h r_defs.h hardware/hw_dll.h
 	$(CC) $(CFLAGS) $(WFLAGS) -D_WINDOWS -mwindows -c $< -o $@
@@ -880,7 +892,7 @@ $(OBJDIR)/r_opengl.o: hardware/r_opengl/r_opengl.c hardware/r_opengl/r_opengl.h
 $(OBJDIR)/ogl_win.o: hardware/r_opengl/ogl_win.c hardware/r_opengl/r_opengl.h \
  doomdef.h doomtype.h g_state.h m_swap.h hardware/hw_drv.h screen.h \
  command.h hardware/hw_data.h hardware/hw_glide.h hardware/hw_defs.h \
- hardware/hw_md2.h hardware/hw_glob.h hardware/hw_main.h am_map.h \
+ hardware/hw_md2.h hardware/hw_glob.h hardware/hw_main.h hardware/hw_clip.h am_map.h \
  d_event.h d_player.h p_pspr.h m_fixed.h tables.h info.h d_think.h \
  p_mobj.h doomdata.h d_ticcmd.h r_defs.h hardware/hw_dll.h
 	$(CC) $(CFLAGS) $(WFLAGS) -D_WINDOWS -mwindows -c $< -o $@
@@ -888,7 +900,7 @@ $(OBJDIR)/ogl_win.o: hardware/r_opengl/ogl_win.c hardware/r_opengl/r_opengl.h \
 $(OBJDIR)/r_minigl.o: hardware/r_minigl/r_minigl.c hardware/r_opengl/r_opengl.h \
  doomdef.h doomtype.h g_state.h m_swap.h hardware/hw_drv.h screen.h \
  command.h hardware/hw_data.h hardware/hw_glide.h hardware/hw_defs.h \
- hardware/hw_md2.h hardware/hw_glob.h hardware/hw_main.h am_map.h \
+ hardware/hw_md2.h hardware/hw_glob.h hardware/hw_main.h hardware/hw_clip.h am_map.h \
  d_event.h d_player.h p_pspr.h m_fixed.h tables.h info.h d_think.h \
  p_mobj.h doomdata.h d_ticcmd.h r_defs.h hardware/hw_dll.h
 	$(CC) $(CFLAGS) $(WFLAGS) -D_WINDOWS -mwindows -c $< -o $@
diff --git a/src/Makefile.cfg b/src/Makefile.cfg
index 5f0096d63..cdd4c3c73 100644
--- a/src/Makefile.cfg
+++ b/src/Makefile.cfg
@@ -190,9 +190,6 @@ endif
 ifdef GCC46
 WFLAGS+=-Wno-suggest-attribute=noreturn
 endif
-ifdef GCC71
-WFLAGS+=-Wno-error=implicit-fallthrough -Wimplicit-fallthrough=3
-endif
 
 ifndef MINGW
 ifdef GCC45
@@ -222,6 +219,18 @@ endif
 ifdef GCC61
  WFLAGS+=-Wno-tautological-compare -Wno-error=tautological-compare
 endif
+ifdef GCC71
+ WFLAGS+=-Wno-error=implicit-fallthrough
+ WFLAGS+=-Wno-implicit-fallthrough
+endif
+ifdef GCC80
+ WFLAGS+=-Wno-error=format-overflow
+ WFLAGS+=-Wno-error=stringop-truncation
+ WFLAGS+=-Wno-error=stringop-overflow
+ WFLAGS+=-Wno-format-overflow
+ WFLAGS+=-Wno-stringop-truncation
+ WFLAGS+=-Wno-stringop-overflow
+endif
 
 
 #indicate platform and what interface use with
@@ -235,6 +244,7 @@ ifndef LINUX
 ifndef FREEBSD
 ifndef CYGWIN32
 ifndef MINGW
+ifndef MINGW64
 ifndef SDL
 ifndef NDS
 ifndef DUMMY
@@ -252,6 +262,7 @@ endif
 endif
 endif
 endif
+endif
 
 #determine the interface directory (where you put all i_*.c)
 i_cdmus_o=$(OBJDIR)/i_cdmus.o
diff --git a/src/am_map.c b/src/am_map.c
index b28cecf11..6b97dd282 100644
--- a/src/am_map.c
+++ b/src/am_map.c
@@ -2,7 +2,7 @@
 //-----------------------------------------------------------------------------
 // Copyright (C) 1993-1996 by id Software, Inc.
 // Copyright (C) 1998-2000 by DooM Legacy Team.
-// Copyright (C) 1999-2016 by Sonic Team Junior.
+// Copyright (C) 1999-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
diff --git a/src/am_map.h b/src/am_map.h
index df145848b..4e8c782a9 100644
--- a/src/am_map.h
+++ b/src/am_map.h
@@ -2,7 +2,7 @@
 //-----------------------------------------------------------------------------
 // Copyright (C) 1993-1996 by id Software, Inc.
 // Copyright (C) 1998-2000 by DooM Legacy Team.
-// Copyright (C) 1999-2016 by Sonic Team Junior.
+// Copyright (C) 1999-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
diff --git a/src/android/i_sound.c b/src/android/i_sound.c
index ecf96f2f0..2bb304424 100644
--- a/src/android/i_sound.c
+++ b/src/android/i_sound.c
@@ -21,13 +21,14 @@ void I_ShutdownSound(void){}
 //  SFX I/O
 //
 
-INT32 I_StartSound(sfxenum_t id, INT32 vol, INT32 sep, INT32 pitch, INT32 priority)
+INT32 I_StartSound(sfxenum_t id, INT32 vol, INT32 sep, INT32 pitch, INT32 priority, INT32 channel)
 {
         (void)id;
         (void)vol;
         (void)sep;
         (void)pitch;
         (void)priority;
+        (void)channel;
         return -1;
 }
 
@@ -55,90 +56,87 @@ void I_SetSfxVolume(INT32 volume)
         (void)volume;
 }
 
-//
-//  MUSIC I/O
-//
+/// ------------------------
+//  MUSIC SYSTEM
+/// ------------------------
+
 UINT8 music_started = 0;
+UINT8 digmusic_started = 0;
 
 void I_InitMusic(void){}
 
 void I_ShutdownMusic(void){}
 
-void I_PauseSong(INT32 handle)
+/// ------------------------
+//  MUSIC PROPERTIES
+/// ------------------------
+
+musictype_t I_SongType(void)
 {
-        (void)handle;
+	return MU_NONE;
 }
 
-void I_ResumeSong(INT32 handle)
+boolean I_SongPlaying(void)
 {
-        (void)handle;
+	return false;
 }
 
-//
-//  MIDI I/O
-//
-
-UINT8 midimusic_started = 0;
-
-void I_InitMIDIMusic(void){}
-
-void I_ShutdownMIDIMusic(void){}
-
-void I_SetMIDIMusicVolume(INT32 volume)
+boolean I_SongPaused(void)
 {
-        (void)volume;
+	return false;
 }
 
-INT32 I_RegisterSong(void *data, size_t len)
-{
-        (void)data;
-        (void)len;
-        return -1;
-}
-
-boolean I_PlaySong(INT32 handle, INT32 looping)
-{
-        (void)handle;
-        (void)looping;
-        return false;
-}
-
-void I_StopSong(INT32 handle)
-{
-        (void)handle;
-}
-
-void I_UnRegisterSong(INT32 handle)
-{
-        (void)handle;
-}
-
-//
-//  DIGMUSIC I/O
-//
-
-UINT8 digmusic_started = 0;
-
-void I_InitDigMusic(void){}
-
-void I_ShutdownDigMusic(void){}
-
-boolean I_StartDigSong(const char *musicname, INT32 looping)
-{
-        (void)musicname;
-        (void)looping;
-        return false;
-}
-
-void I_StopDigSong(void){}
-
-void I_SetDigMusicVolume(INT32 volume)
-{
-        (void)volume;
-}
+/// ------------------------
+//  MUSIC EFFECTS
+/// ------------------------
 
 boolean I_SetSongSpeed(float speed)
 {
         (void)speed;
         return false;
 }
+
+/// ------------------------
+//  MUSIC PLAYBACK
+/// ------------------------
+
+UINT8 midimusic_started = 0;
+
+boolean I_LoadSong(char *data, size_t len)
+{
+        (void)data;
+        (void)len;
+        return -1;
+}
+
+void I_UnloadSong()
+{
+
+}
+
+boolean I_PlaySong(boolean looping)
+{
+        (void)handle;
+        (void)looping;
+        return false;
+}
+
+void I_StopSong(void)
+{
+        (void)handle;
+}
+
+void I_PauseSong(void)
+{
+        (void)handle;
+}
+
+void I_ResumeSong(void)
+{
+        (void)handle;
+}
+
+void I_SetMusicVolume(INT32 volume)
+{
+        (void)volume;
+}
diff --git a/src/asm_defs.inc b/src/asm_defs.inc
index db59d2c69..e494a676e 100644
--- a/src/asm_defs.inc
+++ b/src/asm_defs.inc
@@ -1,7 +1,7 @@
 // SONIC ROBO BLAST 2
 //-----------------------------------------------------------------------------
 // Copyright (C) 1998-2000 by DooM Legacy Team.
-// Copyright (C) 1999-2014 by Sonic Team Junior.
+// Copyright (C) 1999-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
diff --git a/src/b_bot.c b/src/b_bot.c
index 56be0613b..a6d07895b 100644
--- a/src/b_bot.c
+++ b/src/b_bot.c
@@ -1,7 +1,7 @@
 // SONIC ROBO BLAST 2
 //-----------------------------------------------------------------------------
 // Copyright (C) 2007-2016 by John "JTE" Muniz.
-// Copyright (C) 2011-2016 by Sonic Team Junior.
+// Copyright (C) 2011-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
diff --git a/src/b_bot.h b/src/b_bot.h
index 259405f38..20b2803b6 100644
--- a/src/b_bot.h
+++ b/src/b_bot.h
@@ -1,7 +1,7 @@
 // SONIC ROBO BLAST 2
 //-----------------------------------------------------------------------------
 // Copyright (C) 2007-2016 by John "JTE" Muniz.
-// Copyright (C) 2012-2016 by Sonic Team Junior.
+// Copyright (C) 2012-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
diff --git a/src/byteptr.h b/src/byteptr.h
index 410d7c004..aa09d6be4 100644
--- a/src/byteptr.h
+++ b/src/byteptr.h
@@ -1,7 +1,7 @@
 // SONIC ROBO BLAST 2
 //-----------------------------------------------------------------------------
 // Copyright (C) 1998-2000 by DooM Legacy Team.
-// Copyright (C) 1999-2016 by Sonic Team Junior.
+// Copyright (C) 1999-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
@@ -15,7 +15,9 @@
 #define DEALIGNED
 #endif
 
-#ifndef _BIG_ENDIAN
+#include "endian.h"
+
+#ifndef SRB2_BIG_ENDIAN
 //
 // Little-endian machines
 //
@@ -75,7 +77,7 @@
 #define READANGLE(p)        *((angle_t *)p)++
 #endif
 
-#else //_BIG_ENDIAN
+#else //SRB2_BIG_ENDIAN
 //
 // definitions for big-endian machines with alignment constraints.
 //
@@ -144,7 +146,7 @@ FUNCINLINE static ATTRINLINE UINT32 readulong(void *ptr)
 #define READCHAR(p)         ({    char *p_tmp = (   char *)p;    char b =        *p_tmp; p_tmp++; p = (void *)p_tmp; b; })
 #define READFIXED(p)        ({ fixed_t *p_tmp = (fixed_t *)p; fixed_t b =   readlong(p); p_tmp++; p = (void *)p_tmp; b; })
 #define READANGLE(p)        ({ angle_t *p_tmp = (angle_t *)p; angle_t b =  readulong(p); p_tmp++; p = (void *)p_tmp; b; })
-#endif //_BIG_ENDIAN
+#endif //SRB2_BIG_ENDIAN
 
 #undef DEALIGNED
 
diff --git a/src/command.c b/src/command.c
index f77fb5a4d..4a65a0aa6 100644
--- a/src/command.c
+++ b/src/command.c
@@ -1,7 +1,7 @@
 // SONIC ROBO BLAST 2
 //-----------------------------------------------------------------------------
 // Copyright (C) 1998-2000 by DooM Legacy Team.
-// Copyright (C) 1999-2016 by Sonic Team Junior.
+// Copyright (C) 1999-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
diff --git a/src/command.h b/src/command.h
index 989ead8cf..7420c2103 100644
--- a/src/command.h
+++ b/src/command.h
@@ -1,7 +1,7 @@
 // SONIC ROBO BLAST 2
 //-----------------------------------------------------------------------------
 // Copyright (C) 1998-2000 by DooM Legacy Team.
-// Copyright (C) 1999-2016 by Sonic Team Junior.
+// Copyright (C) 1999-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
diff --git a/src/console.c b/src/console.c
index 3c06561ce..2c148bc69 100644
--- a/src/console.c
+++ b/src/console.c
@@ -1,7 +1,7 @@
 // SONIC ROBO BLAST 2
 //-----------------------------------------------------------------------------
 // Copyright (C) 1998-2000 by DooM Legacy Team.
-// Copyright (C) 1999-2016 by Sonic Team Junior.
+// Copyright (C) 1999-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
@@ -101,8 +101,6 @@ static void CON_RecalcSize(void);
 
 static void CONS_hudlines_Change(void);
 static void CONS_backcolor_Change(void);
-static void CON_DrawBackpic(patch_t *pic, INT32 startx, INT32 destwidth);
-//static void CON_DrawBackpic2(pic_t *pic, INT32 startx, INT32 destwidth);
 
 //======================================================================
 //                   CONSOLE VARS AND COMMANDS
@@ -1233,24 +1231,15 @@ void CONS_Printf(const char *fmt, ...)
 	if (con_startup)
 	{
 #if (defined (_WINDOWS)) || (defined (__OS2__) && !defined (HAVE_SDL))
-		static lumpnum_t con_backpic_lumpnum = UINT32_MAX;
-		patch_t *con_backpic;
+		patch_t *con_backpic = W_CachePatchName("CONSBACK", PU_CACHE);
 
-		if (con_backpic_lumpnum == UINT32_MAX)
-			con_backpic_lumpnum = W_GetNumForName("CONSBACK");
+		// Jimita: CON_DrawBackpic just called V_DrawScaledPatch
+		V_DrawScaledPatch(0, 0, 0, con_backpic);
 
-		// We load the raw lump, even in hardware mode
-		con_backpic = (patch_t*)W_CacheLumpNum(con_backpic_lumpnum, PU_CACHE);
-
-		// show startup screen and message using only 'software' graphics
-		// (rendermode may be hardware accelerated, but the video mode is not set yet)
-		CON_DrawBackpic(con_backpic, 0, vid.width); // put console background
-		I_LoadingScreen(txt);
-
-		Z_Unlock(con_backpic);
+		W_UnlockCachedPatch(con_backpic);
+		I_LoadingScreen(txt);				// Win32/OS2 only
 #else
-		// here we display the console background and console text
-		// (no hardware accelerated support for these versions)
+		// here we display the console text
 		CON_Drawer();
 		I_FinishUpdate(); // page flip or blit buffer
 #endif
@@ -1474,64 +1463,6 @@ static void CON_DrawHudlines(void)
 	con_clearlines = y; // this is handled by HU_Erase();
 }
 
-// Scale a pic_t at 'startx' pos, to 'destwidth' columns.
-//   startx, destwidth is resolution dependent
-// Used to draw console borders, console background.
-// The pic must be sized BASEVIDHEIGHT height.
-static void CON_DrawBackpic(patch_t *pic, INT32 startx, INT32 destwidth)
-{
-	(void)startx;
-	(void)destwidth;
-	V_DrawScaledPatch(0, 0, 0, pic);
-}
-
-#if 0
-static inline void CON_DrawBackpic2(pic_t *pic, INT32 startx, INT32 destwidth)
-{
-	INT32 x, y;
-	INT32 v;
-	UINT8 *src, *dest;
-	const UINT8 *deststop;
-	INT32 frac, fracstep;
-
-	dest = screens[0]+startx;
-	deststop = screens[0] + vid.rowbytes * vid.height;
-
-	for (y = 0; y < con_curlines; y++, dest += vid.width)
-	{
-		// scale the picture to the resolution
-		v = SHORT(pic->height) - ((con_curlines - y) * (BASEVIDHEIGHT-1) / vid.height) - 1;
-
-		src = pic->data + v*SHORT(pic->width);
-
-		// in case of the console backpic, simplify
-		if (SHORT(pic->width) == destwidth)
-			M_Memcpy(dest, src, destwidth);
-		else
-		{
-			// scale pic to screen width
-			frac = 0;
-			fracstep = (SHORT(pic->width)<<16)/destwidth;
-			for (x = 0; x < destwidth; x += 4)
-			{
-				if (dest+x > deststop) break;
-				dest[x] = src[frac>>FRACBITS];
-				frac += fracstep;
-				if (dest+x+1 > deststop) break;
-				dest[x+1] = src[frac>>FRACBITS];
-				frac += fracstep;
-				if (dest+x+2 > deststop) break;
-				dest[x+2] = src[frac>>FRACBITS];
-				frac += fracstep;
-				if (dest+x+3 > deststop) break;
-				dest[x+3] = src[frac>>FRACBITS];
-				frac += fracstep;
-			}
-		}
-	}
-}
-#endif
-
 // draw the console background, text, and prompt if enough place
 //
 static void CON_DrawConsole(void)
@@ -1554,18 +1485,10 @@ static void CON_DrawConsole(void)
 	// draw console background
 	if (cons_backpic.value || con_forcepic)
 	{
-		static lumpnum_t con_backpic_lumpnum = UINT32_MAX;
-		patch_t *con_backpic;
+		patch_t *con_backpic = W_CachePatchName("CONSBACK", PU_CACHE);
 
-		if (con_backpic_lumpnum == UINT32_MAX)
-			con_backpic_lumpnum = W_GetNumForName("CONSBACK");
-
-		con_backpic = (patch_t*)W_CachePatchNum(con_backpic_lumpnum, PU_CACHE);
-
-		if (rendermode != render_soft)
-			V_DrawScaledPatch(0, 0, 0, con_backpic);
-		else if (rendermode != render_none)
-			CON_DrawBackpic(con_backpic, 0, vid.width); // picture as background
+		// Jimita: CON_DrawBackpic just called V_DrawScaledPatch
+		V_DrawScaledPatch(0, 0, 0, con_backpic);
 
 		W_UnlockCachedPatch(con_backpic);
 	}
diff --git a/src/console.h b/src/console.h
index 8cf6483ff..7f448f5fe 100644
--- a/src/console.h
+++ b/src/console.h
@@ -1,7 +1,7 @@
 // SONIC ROBO BLAST 2
 //-----------------------------------------------------------------------------
 // Copyright (C) 1998-2000 by DooM Legacy Team.
-// Copyright (C) 1999-2016 by Sonic Team Junior.
+// Copyright (C) 1999-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
diff --git a/src/d_clisrv.c b/src/d_clisrv.c
index 6e22dde23..073c0d363 100644
--- a/src/d_clisrv.c
+++ b/src/d_clisrv.c
@@ -1,7 +1,7 @@
 // SONIC ROBO BLAST 2
 //-----------------------------------------------------------------------------
 // Copyright (C) 1998-2000 by DooM Legacy Team.
-// Copyright (C) 1999-2016 by Sonic Team Junior.
+// Copyright (C) 1999-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
@@ -1568,8 +1568,6 @@ static void CL_LoadReceivedSavegame(void)
 	automapactive = false;
 
 	// load a base level
-	playerdeadview = false;
-
 	if (P_LoadNetGame())
 	{
 		const INT32 actnum = mapheaderinfo[gamemap-1]->actnum;
@@ -1625,6 +1623,8 @@ static void SendAskInfo(INT32 node, boolean viams)
 serverelem_t serverlist[MAXSERVERLIST];
 UINT32 serverlistcount = 0;
 
+#define FORCECLOSE 0x8000
+
 static void SL_ClearServerList(INT32 connectedserver)
 {
 	UINT32 i;
@@ -1632,7 +1632,7 @@ static void SL_ClearServerList(INT32 connectedserver)
 	for (i = 0; i < serverlistcount; i++)
 		if (connectedserver != serverlist[i].node)
 		{
-			Net_CloseConnection(serverlist[i].node);
+			Net_CloseConnection(serverlist[i].node|FORCECLOSE);
 			serverlist[i].node = 0;
 		}
 	serverlistcount = 0;
@@ -1714,12 +1714,25 @@ void CL_UpdateServerList(boolean internetsearch, INT32 room)
 				// Make sure MS version matches our own, to
 				// thwart nefarious servers who lie to the MS.
 
-				if(strcmp(version, server_list[i].version) == 0)
+				if (strcmp(version, server_list[i].version) == 0)
 				{
 					INT32 node = I_NetMakeNodewPort(server_list[i].ip, server_list[i].port);
 					if (node == -1)
 						break; // no more node free
 					SendAskInfo(node, true);
+					// Force close the connection so that servers can't eat
+					// up nodes forever if we never get a reply back from them
+					// (usually when they've not forwarded their ports).
+					//
+					// Don't worry, we'll get in contact with the working
+					// servers again when they send SERVERINFO to us later!
+					//
+					// (Note: as a side effect this probably means every
+					// server in the list will probably be using the same node (e.g. node 1),
+					// not that it matters which nodes they use when
+					// the connections are closed afterwards anyway)
+					// -- Monster Iestyn 12/11/18
+					Net_CloseConnection(node|FORCECLOSE);
 				}
 			}
 		}
@@ -3096,12 +3109,6 @@ static void Got_AddPlayer(UINT8 **p, INT32 playernum)
 			displayplayer = newplayernum;
 			secondarydisplayplayer = newplayernum;
 			DEBFILE("spawning me\n");
-			// Apply player flags as soon as possible!
-			players[newplayernum].pflags &= ~(PF_FLIPCAM|PF_ANALOGMODE);
-			if (cv_flipcam.value)
-				players[newplayernum].pflags |= PF_FLIPCAM;
-			if (cv_analog.value)
-				players[newplayernum].pflags |= PF_ANALOGMODE;
 		}
 		else
 		{
@@ -3109,12 +3116,6 @@ static void Got_AddPlayer(UINT8 **p, INT32 playernum)
 			DEBFILE("spawning my brother\n");
 			if (botingame)
 				players[newplayernum].bot = 1;
-			// Same goes for player 2 when relevant
-			players[newplayernum].pflags &= ~(PF_FLIPCAM|PF_ANALOGMODE);
-			if (cv_flipcam2.value)
-				players[newplayernum].pflags |= PF_FLIPCAM;
-			if (cv_analog2.value)
-				players[newplayernum].pflags |= PF_ANALOGMODE;
 		}
 		D_SendPlayerConfig();
 		addedtogame = true;
diff --git a/src/d_clisrv.h b/src/d_clisrv.h
index e7f1e8433..fc15d0567 100644
--- a/src/d_clisrv.h
+++ b/src/d_clisrv.h
@@ -1,7 +1,7 @@
 // SONIC ROBO BLAST 2
 //-----------------------------------------------------------------------------
 // Copyright (C) 1998-2000 by DooM Legacy Team.
-// Copyright (C) 1999-2016 by Sonic Team Junior.
+// Copyright (C) 1999-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
diff --git a/src/d_event.h b/src/d_event.h
index b0d0e3c58..e9374efaf 100644
--- a/src/d_event.h
+++ b/src/d_event.h
@@ -2,7 +2,7 @@
 //-----------------------------------------------------------------------------
 // Copyright (C) 1993-1996 by id Software, Inc.
 // Copyright (C) 1998-2000 by DooM Legacy Team.
-// Copyright (C) 1999-2016 by Sonic Team Junior.
+// Copyright (C) 1999-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
diff --git a/src/d_main.c b/src/d_main.c
index df3398752..23835136a 100644
--- a/src/d_main.c
+++ b/src/d_main.c
@@ -2,7 +2,7 @@
 //-----------------------------------------------------------------------------
 // Copyright (C) 1993-1996 by id Software, Inc.
 // Copyright (C) 1998-2000 by DooM Legacy Team.
-// Copyright (C) 1999-2016 by Sonic Team Junior.
+// Copyright (C) 1999-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
@@ -121,20 +121,17 @@ INT32 postimgparam;
 postimg_t postimgtype2 = postimg_none;
 INT32 postimgparam2;
 
-#ifdef _XBOX
-boolean nomidimusic = true, nosound = true;
-boolean nodigimusic = true;
-#else
-boolean nomidimusic = false, nosound = false;
-boolean nodigimusic = false; // No fmod-based music
-#endif
-
 // These variables are only true if
-// the respective sound system is initialized
-// and active, but no sounds/music should play.
-boolean music_disabled = false;
+// whether the respective sound system is disabled
+// or they're init'ed, but the player just toggled them
+#ifdef _XBOX
+boolean midi_disabled = true, sound_disabled = true;
+boolean digital_disabled = true;
+#else
+boolean midi_disabled = false;
 boolean sound_disabled = false;
 boolean digital_disabled = false;
+#endif
 
 boolean advancedemo;
 #ifdef DEBUGFILE
@@ -173,7 +170,7 @@ void D_PostEvent(const event_t *ev)
 	eventhead = (eventhead+1) & (MAXEVENTS-1);
 }
 // just for lock this function
-#ifndef DOXYGEN
+#if defined (PC_DOS) && !defined (DOXYGEN)
 void D_PostEvent_end(void) {};
 #endif
 
@@ -420,10 +417,13 @@ static void D_Display(void)
 			}
 
 			// Image postprocessing effect
-			if (postimgtype)
-				V_DoPostProcessor(0, postimgtype, postimgparam);
-			if (postimgtype2)
-				V_DoPostProcessor(1, postimgtype2, postimgparam2);
+			if (rendermode == render_soft)
+			{
+				if (postimgtype)
+					V_DoPostProcessor(0, postimgtype, postimgparam);
+				if (postimgtype2)
+					V_DoPostProcessor(1, postimgtype2, postimgparam2);
+			}
 		}
 
 		if (lastdraw)
@@ -720,7 +720,6 @@ void D_StartTitle(void)
 	maptol = 0;
 
 	gameaction = ga_nothing;
-	playerdeadview = false;
 	displayplayer = consoleplayer = 0;
 	//demosequence = -1;
 	gametype = GT_COOP;
@@ -765,10 +764,6 @@ static inline void D_CleanFile(void)
 	}
 }
 
-#ifndef _MAX_PATH
-#define _MAX_PATH MAX_WADPATH
-#endif
-
 // ==========================================================================
 // Identify the SRB2 version, and IWAD file to use.
 // ==========================================================================
@@ -829,7 +824,7 @@ static void IdentifyVersion(void)
 	else if (srb2wad1 != NULL && FIL_ReadFileOK(srb2wad1))
 		D_AddFile(srb2wad1);
 	else
-		I_Error("SRB2.SRB/SRB2.WAD not found! Expected in %s, ss files: %s and %s\n", srb2waddir, srb2wad1, srb2wad2);
+		I_Error("SRB2.SRB/SRB2.WAD not found! Expected in %s, ss files: %s or %s\n", srb2waddir, srb2wad1, srb2wad2);
 
 	if (srb2wad1)
 		free(srb2wad1);
@@ -932,6 +927,20 @@ void D_SRB2Main(void)
 	INT32 pstartmap = 1;
 	boolean autostart = false;
 
+	// Print GPL notice for our console users (Linux)
+	CONS_Printf(
+	"\n\nSonic Robo Blast 2\n"
+	"Copyright (C) 1998-2018 by Sonic Team Junior\n\n"
+	"This program comes with ABSOLUTELY NO WARRANTY.\n\n"
+	"This is free software, and you are welcome to redistribute it\n"
+	"and/or modify it under the terms of the GNU General Public License\n"
+	"as published by the Free Software Foundation; either version 2 of\n"
+	"the License, or (at your option) any later version.\n"
+	"See the 'LICENSE.txt' file for details.\n\n"
+	"Sonic the Hedgehog and related characters are trademarks of SEGA.\n"
+	"We do not claim ownership of SEGA's intellectual property used\n"
+	"in this program.\n\n");
+
 	// keep error messages until the final flush(stderr)
 #if !defined (PC_DOS) && !defined (_WIN32_WCE) && !defined(NOTERMIOS)
 	if (setvbuf(stderr, NULL, _IOFBF, 1000))
@@ -1212,27 +1221,27 @@ void D_SRB2Main(void)
 	// setting up sound
 	if (dedicated)
 	{
-		nosound = true;
-		nomidimusic = nodigimusic = true;
+		sound_disabled = true;
+		midi_disabled = digital_disabled = true;
 	}
 	else
 	{
-		CONS_Printf("S_Init(): Setting up sound.\n");
+		CONS_Printf("S_InitSfxChannels(): Setting up sound channels.\n");
 	}
 	if (M_CheckParm("-nosound"))
-		nosound = true;
+		sound_disabled = true;
 	if (M_CheckParm("-nomusic")) // combines -nomidimusic and -nodigmusic
-		nomidimusic = nodigimusic = true;
+		midi_disabled = digital_disabled = true;
 	else
 	{
 		if (M_CheckParm("-nomidimusic"))
-			nomidimusic = true; ; // WARNING: DOS version initmusic in I_StartupSound
+			midi_disabled = true; // WARNING: DOS version initmusic in I_StartupSound
 		if (M_CheckParm("-nodigmusic"))
-			nodigimusic = true; // WARNING: DOS version initmusic in I_StartupSound
+			digital_disabled = true; // WARNING: DOS version initmusic in I_StartupSound
 	}
 	I_StartupSound();
 	I_InitMusic();
-	S_Init(cv_soundvolume.value, cv_digmusicvolume.value, cv_midimusicvolume.value);
+	S_InitSfxChannels(cv_soundvolume.value);
 
 	CONS_Printf("ST_Init(): Init status bar.\n");
 	ST_Init();
diff --git a/src/d_main.h b/src/d_main.h
index 6dc273b15..d67a5bb49 100644
--- a/src/d_main.h
+++ b/src/d_main.h
@@ -2,7 +2,7 @@
 //-----------------------------------------------------------------------------
 // Copyright (C) 1993-1996 by id Software, Inc.
 // Copyright (C) 1998-2000 by DooM Legacy Team.
-// Copyright (C) 1999-2016 by Sonic Team Junior.
+// Copyright (C) 1999-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
@@ -34,14 +34,14 @@ void D_SRB2Loop(void) FUNCNORETURN;
 // D_SRB2Main()
 // Not a globally visible function, just included for source reference,
 // calls all startup code, parses command line options.
-// If not overrided by user input, calls N_AdvanceDemo.
+// If not overrided by user input, calls D_AdvanceDemo.
 //
 void D_SRB2Main(void);
 
 // Called by IO functions when input is detected.
 void D_PostEvent(const event_t *ev);
-#ifndef DOXYGEN
-FUNCMATH void D_PostEvent_end(void);    // delimiter for locking memory
+#if defined (PC_DOS) && !defined (DOXYGEN)
+void D_PostEvent_end(void);    // delimiter for locking memory
 #endif
 
 void D_ProcessEvents(void);
@@ -51,9 +51,6 @@ const char *D_Home(void);
 //
 // BASE LEVEL
 //
-void D_PageTicker(void);
-// pagename is lumpname of a 320x200 patch to fill the screen
-void D_PageDrawer(const char *pagename);
 void D_AdvanceDemo(void);
 void D_StartTitle(void);
 
diff --git a/src/d_net.c b/src/d_net.c
index 643c41ac9..82c60e4ae 100644
--- a/src/d_net.c
+++ b/src/d_net.c
@@ -2,7 +2,7 @@
 //-----------------------------------------------------------------------------
 // Copyright (C) 1993-1996 by id Software, Inc.
 // Copyright (C) 1998-2000 by DooM Legacy Team.
-// Copyright (C) 1999-2016 by Sonic Team Junior.
+// Copyright (C) 1999-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
@@ -49,7 +49,9 @@ doomcom_t *doomcom = NULL;
 /// \brief network packet data, points inside doomcom
 doomdata_t *netbuffer = NULL;
 
+#ifdef DEBUGFILE
 FILE *debugfile = NULL; // put some net info in a file during the game
+#endif
 
 #define MAXREBOUND 8
 static doomdata_t reboundstore[MAXREBOUND];
diff --git a/src/d_net.h b/src/d_net.h
index 84814ce39..55ea308b3 100644
--- a/src/d_net.h
+++ b/src/d_net.h
@@ -2,7 +2,7 @@
 //-----------------------------------------------------------------------------
 // Copyright (C) 1993-1996 by id Software, Inc.
 // Copyright (C) 1998-2000 by DooM Legacy Team.
-// Copyright (C) 1999-2016 by Sonic Team Junior.
+// Copyright (C) 1999-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
diff --git a/src/d_netcmd.c b/src/d_netcmd.c
index bf26ca61a..16788baeb 100644
--- a/src/d_netcmd.c
+++ b/src/d_netcmd.c
@@ -1,7 +1,7 @@
 // SONIC ROBO BLAST 2
 //-----------------------------------------------------------------------------
 // Copyright (C) 1998-2000 by DooM Legacy Team.
-// Copyright (C) 1999-2016 by Sonic Team Junior.
+// Copyright (C) 1999-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
@@ -128,8 +128,6 @@ FUNCNORETURN static ATTRNORETURN void Command_Quit_f(void);
 static void Command_Playintro_f(void);
 
 static void Command_Displayplayer_f(void);
-static void Command_Tunes_f(void);
-static void Command_RestartAudio_f(void);
 
 static void Command_ExitLevel_f(void);
 static void Command_Showmap_f(void);
@@ -319,7 +317,6 @@ consvar_t cv_overtime = {"overtime", "Yes", CV_NETVAR, CV_YesNo, NULL, 0, NULL,
 consvar_t cv_rollingdemos = {"rollingdemos", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
 
 consvar_t cv_timetic = {"timerres", "Normal", CV_SAVE, timetic_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; // use tics in display
-consvar_t cv_resetmusic = {"resetmusic", "No", CV_SAVE, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL};
 
 static CV_PossibleValue_t pointlimit_cons_t[] = {{0, "MIN"}, {999999990, "MAX"}, {0, NULL}};
 consvar_t cv_pointlimit = {"pointlimit", "0", CV_NETVAR|CV_CALL|CV_NOINIT, pointlimit_cons_t,
@@ -668,9 +665,6 @@ void D_RegisterClientCommands(void)
 	CV_RegisterVar(&cv_ghost_guest);
 
 	COM_AddCommand("displayplayer", Command_Displayplayer_f);
-	COM_AddCommand("tunes", Command_Tunes_f);
-	COM_AddCommand("restartaudio", Command_RestartAudio_f);
-	CV_RegisterVar(&cv_resetmusic);
 
 	// FIXME: not to be here.. but needs be done for config loading
 	CV_RegisterVar(&cv_usegamma);
@@ -1369,9 +1363,9 @@ void SendWeaponPref(void)
 	XBOXSTATIC UINT8 buf[1];
 
 	buf[0] = 0;
-	if (players[consoleplayer].pflags & PF_FLIPCAM)
+	if (cv_flipcam.value)
 		buf[0] |= 1;
-	if (players[consoleplayer].pflags & PF_ANALOGMODE)
+	if (cv_analog.value)
 		buf[0] |= 2;
 	SendNetXCmd(XD_WEAPONPREF, buf, 1);
 }
@@ -1381,9 +1375,9 @@ void SendWeaponPref2(void)
 	XBOXSTATIC UINT8 buf[1];
 
 	buf[0] = 0;
-	if (players[secondarydisplayplayer].pflags & PF_FLIPCAM)
+	if (cv_flipcam2.value)
 		buf[0] |= 1;
-	if (players[secondarydisplayplayer].pflags & PF_ANALOGMODE)
+	if (cv_analog2.value)
 		buf[0] |= 2;
 	SendNetXCmd2(XD_WEAPONPREF, buf, 1);
 }
@@ -1802,6 +1796,10 @@ static void Got_Mapcmd(UINT8 **cp, INT32 playernum)
 			mapname, resetplayer, lastgametype, gametype, chmappending));
 		CONS_Printf(M_GetText("Speeding off to level...\n"));
 	}
+
+	CON_ToggleOff();
+	CON_ClearHUD();
+
 	if (demoplayback && !timingdemo)
 		precache = false;
 
@@ -1818,7 +1816,6 @@ static void Got_Mapcmd(UINT8 **cp, INT32 playernum)
 	G_InitNew(ultimatemode, mapname, resetplayer, skipprecutscene);
 	if (demoplayback && !timingdemo)
 		precache = true;
-	CON_ToggleOff();
 	if (timingdemo)
 		G_DoneLevelLoad();
 
@@ -3881,95 +3878,6 @@ static void Command_Displayplayer_f(void)
 	CONS_Printf(M_GetText("Displayplayer is %d\n"), displayplayer);
 }
 
-static void Command_Tunes_f(void)
-{
-	const char *tunearg;
-	UINT16 tunenum, track = 0;
-	const size_t argc = COM_Argc();
-
-	if (argc < 2) //tunes slot ...
-	{
-		CONS_Printf("tunes <name/num> [track] [speed] / <-show> / <-default> / <-none>:\n");
-		CONS_Printf(M_GetText("Play an arbitrary music lump. If a map number is used, 'MAP##M' is played.\n"));
-		CONS_Printf(M_GetText("If the format supports multiple songs, you can specify which one to play.\n\n"));
-		CONS_Printf(M_GetText("* With \"-show\", shows the currently playing tune and track.\n"));
-		CONS_Printf(M_GetText("* With \"-default\", returns to the default music for the map.\n"));
-		CONS_Printf(M_GetText("* With \"-none\", any music playing will be stopped.\n"));
-		return;
-	}
-
-	tunearg = COM_Argv(1);
-	tunenum = (UINT16)atoi(tunearg);
-	track = 0;
-
-	if (!strcasecmp(tunearg, "-show"))
-	{
-		CONS_Printf(M_GetText("The current tune is: %s [track %d]\n"),
-			mapmusname, (mapmusflags & MUSIC_TRACKMASK));
-		return;
-	}
-	if (!strcasecmp(tunearg, "-none"))
-	{
-		S_StopMusic();
-		return;
-	}
-	else if (!strcasecmp(tunearg, "-default"))
-	{
-		tunearg = mapheaderinfo[gamemap-1]->musname;
-		track = mapheaderinfo[gamemap-1]->mustrack;
-	}
-	else if (!tunearg[2] && toupper(tunearg[0]) >= 'A' && toupper(tunearg[0]) <= 'Z')
-		tunenum = (UINT16)M_MapNumber(tunearg[0], tunearg[1]);
-
-	if (tunenum && tunenum >= 1036)
-	{
-		CONS_Alert(CONS_NOTICE, M_GetText("Valid music slots are 1 to 1035.\n"));
-		return;
-	}
-	if (!tunenum && strlen(tunearg) > 6) // This is automatic -- just show the error just in case
-		CONS_Alert(CONS_NOTICE, M_GetText("Music name too long - truncated to six characters.\n"));
-
-	if (argc > 2)
-		track = (UINT16)atoi(COM_Argv(2))-1;
-
-	if (tunenum)
-		snprintf(mapmusname, 7, "%sM", G_BuildMapName(tunenum));
-	else
-		strncpy(mapmusname, tunearg, 7);
-	mapmusname[6] = 0;
-	mapmusflags = (track & MUSIC_TRACKMASK);
-
-	S_ChangeMusic(mapmusname, mapmusflags, true);
-
-	if (argc > 3)
-	{
-		float speed = (float)atof(COM_Argv(3));
-		if (speed > 0.0f)
-			S_SpeedMusic(speed);
-	}
-}
-
-static void Command_RestartAudio_f(void)
-{
-	if (dedicated)  // No point in doing anything if game is a dedicated server.
-		return;
-
-	S_StopMusic();
-	I_ShutdownMusic();
-	I_ShutdownSound();
-	I_StartupSound();
-	I_InitMusic();
-
-// These must be called or no sound and music until manually set.
-
-	I_SetSfxVolume(cv_soundvolume.value);
-	I_SetDigMusicVolume(cv_digmusicvolume.value);
-	I_SetMIDIMusicVolume(cv_midimusicvolume.value);
-	if (Playing()) // Gotta make sure the player is in a level
-		P_RestoreMusic(&players[consoleplayer]);
-
-}
-
 /** Quits a game and returns to the title screen.
   *
   */
diff --git a/src/d_netcmd.h b/src/d_netcmd.h
index d8fae72f7..09bde4e5b 100644
--- a/src/d_netcmd.h
+++ b/src/d_netcmd.h
@@ -1,7 +1,7 @@
 // SONIC ROBO BLAST 2
 //-----------------------------------------------------------------------------
 // Copyright (C) 1998-2000 by DooM Legacy Team.
-// Copyright (C) 1999-2016 by Sonic Team Junior.
+// Copyright (C) 1999-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
@@ -20,6 +20,12 @@
 // console vars
 extern consvar_t cv_playername;
 extern consvar_t cv_playercolor;
+extern consvar_t cv_skin;
+// secondary splitscreen player
+extern consvar_t cv_playername2;
+extern consvar_t cv_playercolor2;
+extern consvar_t cv_skin2;
+
 #ifdef SEENAMES
 extern consvar_t cv_seenames, cv_allowseenames;
 #endif
@@ -32,7 +38,6 @@ extern consvar_t cv_joyport2;
 #endif
 extern consvar_t cv_joyscale;
 extern consvar_t cv_joyscale2;
-extern consvar_t cv_controlperkey;
 
 // splitscreen with second mouse
 extern consvar_t cv_mouse2port;
@@ -40,11 +45,6 @@ extern consvar_t cv_usemouse2;
 #if (defined (__unix__) && !defined (MSDOS)) || defined (UNIXCOMMON)
 extern consvar_t cv_mouse2opt;
 #endif
-extern consvar_t cv_invertmouse2;
-extern consvar_t cv_alwaysfreelook2;
-extern consvar_t cv_mousemove2;
-extern consvar_t cv_mousesens2;
-extern consvar_t cv_mouseysens2;
 
 // normally in p_mobj but the .h is not read
 extern consvar_t cv_itemrespawntime;
@@ -53,13 +53,6 @@ extern consvar_t cv_itemrespawn;
 extern consvar_t cv_flagtime;
 extern consvar_t cv_suddendeath;
 
-extern consvar_t cv_skin;
-
-// secondary splitscreen player
-extern consvar_t cv_playername2;
-extern consvar_t cv_playercolor2;
-extern consvar_t cv_skin2;
-
 extern consvar_t cv_touchtag;
 extern consvar_t cv_hidetime;
 
@@ -77,9 +70,6 @@ extern consvar_t cv_autobalance;
 extern consvar_t cv_teamscramble;
 extern consvar_t cv_scrambleonchange;
 
-extern consvar_t cv_useranalog, cv_useranalog2;
-extern consvar_t cv_analog, cv_analog2;
-
 extern consvar_t cv_netstat;
 #ifdef WALLSPLATS
 extern consvar_t cv_splats;
@@ -109,8 +99,6 @@ extern consvar_t cv_startinglives;
 // for F_finale.c
 extern consvar_t cv_rollingdemos;
 
-extern consvar_t cv_resetmusic;
-
 extern consvar_t cv_ringslinger, cv_soundtest;
 
 extern consvar_t cv_specialrings, cv_powerstones, cv_matchboxes, cv_competitionboxes;
@@ -121,17 +109,7 @@ extern consvar_t cv_maxping;
 
 extern consvar_t cv_skipmapcheck;
 
-extern consvar_t cv_sleep, cv_screenshot_option, cv_screenshot_folder;
-
-extern consvar_t cv_moviemode;
-
-extern consvar_t cv_zlib_level, cv_zlib_memory, cv_zlib_strategy;
-
-extern consvar_t cv_zlib_window_bits, cv_zlib_levela, cv_zlib_memorya;
-
-extern consvar_t cv_zlib_strategya, cv_zlib_window_bitsa;
-
-extern consvar_t cv_apng_delay;
+extern consvar_t cv_sleep;
 
 typedef enum
 {
@@ -212,7 +190,6 @@ void Command_ExitGame_f(void);
 void Command_Retry_f(void);
 void D_GameTypeChanged(INT32 lastgametype); // not a real _OnChange function anymore
 void D_MapChange(INT32 pmapnum, INT32 pgametype, boolean pultmode, boolean presetplayers, INT32 pdelay, boolean pskipprecutscene, boolean pfromlevelselect);
-void ObjectPlace_OnChange(void);
 void ItemFinder_OnChange(void);
 void D_SetPassword(const char *pw);
 
@@ -220,5 +197,3 @@ void D_SetPassword(const char *pw);
 UINT8 CanChangeSkin(INT32 playernum);
 
 #endif
-
-
diff --git a/src/d_netfil.c b/src/d_netfil.c
index 6742cfe28..7c4806580 100644
--- a/src/d_netfil.c
+++ b/src/d_netfil.c
@@ -1,7 +1,7 @@
 // SONIC ROBO BLAST 2
 //-----------------------------------------------------------------------------
 // Copyright (C) 1998-2000 by DooM Legacy Team.
-// Copyright (C) 1999-2016 by Sonic Team Junior.
+// Copyright (C) 1999-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
@@ -94,7 +94,7 @@ static filetran_t transfer[MAXNETNODES];
 // Receiver structure
 INT32 fileneedednum; // Number of files needed to join the server
 fileneeded_t fileneeded[MAX_WADFILES]; // List of needed files
-char downloaddir[256] = "DOWNLOAD";
+char downloaddir[512] = "DOWNLOAD";
 
 #ifdef CLIENT_LOADINGSCREEN
 // for cl loading screen
diff --git a/src/d_netfil.h b/src/d_netfil.h
index b9b7b2f2e..a7b692931 100644
--- a/src/d_netfil.h
+++ b/src/d_netfil.h
@@ -1,7 +1,7 @@
 // SONIC ROBO BLAST 2
 //-----------------------------------------------------------------------------
 // Copyright (C) 1998-2000 by DooM Legacy Team.
-// Copyright (C) 1999-2016 by Sonic Team Junior.
+// Copyright (C) 1999-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
@@ -48,7 +48,7 @@ typedef struct
 
 extern INT32 fileneedednum;
 extern fileneeded_t fileneeded[MAX_WADFILES];
-extern char downloaddir[256];
+extern char downloaddir[512];
 
 #ifdef CLIENT_LOADINGSCREEN
 extern INT32 lastfilenum;
diff --git a/src/d_player.h b/src/d_player.h
index 5a4ebc1de..7c5ac6890 100644
--- a/src/d_player.h
+++ b/src/d_player.h
@@ -2,7 +2,7 @@
 //-----------------------------------------------------------------------------
 // Copyright (C) 1993-1996 by id Software, Inc.
 // Copyright (C) 1998-2000 by DooM Legacy Team.
-// Copyright (C) 1999-2016 by Sonic Team Junior.
+// Copyright (C) 1999-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
diff --git a/src/d_think.h b/src/d_think.h
index 2831b9f2b..b907c17fd 100644
--- a/src/d_think.h
+++ b/src/d_think.h
@@ -2,7 +2,7 @@
 //-----------------------------------------------------------------------------
 // Copyright (C) 1993-1996 by id Software, Inc.
 // Copyright (C) 1998-2000 by DooM Legacy Team.
-// Copyright (C) 1999-2016 by Sonic Team Junior.
+// Copyright (C) 1999-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
diff --git a/src/d_ticcmd.h b/src/d_ticcmd.h
index 83f684b6f..1ea015439 100644
--- a/src/d_ticcmd.h
+++ b/src/d_ticcmd.h
@@ -2,7 +2,7 @@
 //-----------------------------------------------------------------------------
 // Copyright (C) 1993-1996 by id Software, Inc.
 // Copyright (C) 1998-2000 by DooM Legacy Team.
-// Copyright (C) 1999-2016 by Sonic Team Junior.
+// Copyright (C) 1999-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
diff --git a/src/dehacked.c b/src/dehacked.c
index b7e874b16..7f549ce8e 100644
--- a/src/dehacked.c
+++ b/src/dehacked.c
@@ -1,7 +1,7 @@
 // SONIC ROBO BLAST 2
 //-----------------------------------------------------------------------------
 // Copyright (C) 1998-2000 by DooM Legacy Team.
-// Copyright (C) 1999-2016 by Sonic Team Junior.
+// Copyright (C) 1999-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
@@ -3069,7 +3069,7 @@ static void readmaincfg(MYFILE *f)
 				strncpy(timeattackfolder, gamedatafilename, min(filenamelen, sizeof (timeattackfolder)));
 				timeattackfolder[min(filenamelen, sizeof (timeattackfolder) - 1)] = '\0';
 
-				strncpy(savegamename, timeattackfolder, sizeof (timeattackfolder));
+				strncpy(savegamename, timeattackfolder, strlen(timeattackfolder));
 				strlcat(savegamename, "%u.ssg", sizeof(savegamename));
 				// can't use sprintf since there is %u in savegamename
 				strcatbf(savegamename, srb2home, PATHSEP);
@@ -7769,7 +7769,7 @@ fixed_t get_number(const char *word)
 #endif
 }
 
-void FUNCMATH DEH_Check(void)
+void DEH_Check(void)
 {
 #if defined(_DEBUG) || defined(PARANOIA)
 	const size_t dehstates = sizeof(STATE_LIST)/sizeof(const char*);
diff --git a/src/dehacked.h b/src/dehacked.h
index 8832216b8..411cb6c1b 100644
--- a/src/dehacked.h
+++ b/src/dehacked.h
@@ -1,7 +1,7 @@
 // SONIC ROBO BLAST 2
 //-----------------------------------------------------------------------------
 // Copyright (C) 1998-2000 by DooM Legacy Team.
-// Copyright (C) 1999-2016 by Sonic Team Junior.
+// Copyright (C) 1999-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
diff --git a/src/djgppdos/i_sound.c b/src/djgppdos/i_sound.c
index 88fc807f4..52c90aac2 100644
--- a/src/djgppdos/i_sound.c
+++ b/src/djgppdos/i_sound.c
@@ -134,21 +134,12 @@ FUNCINLINE static ATTRINLINE int Volset(int vol)
 
 void I_SetSfxVolume(INT32 volume)
 {
-	if (nosound)
+	if (sound_disabled)
 		return;
 
 	set_volume (Volset(volume),-1);
 }
 
-void I_SetMIDIMusicVolume(INT32 volume)
-{
-	if (nomidimusic)
-		return;
-
-	// Now set volume on output device.
-	set_volume (-1, Volset(volume));
-}
-
 //
 // Starting a sound means adding it
 //  to the current list of active sounds
@@ -165,11 +156,13 @@ INT32 I_StartSound ( sfxenum_t     id,
                    INT32         vol,
                    INT32         sep,
                    INT32         pitch,
-                   INT32         priority )
+                   INT32         priority,
+				   INT32         channel)
 {
 	int voice;
+	(void)channel;
 
-	if (nosound)
+	if (sound_disabled)
 	return 0;
 
 	// UNUSED
@@ -190,7 +183,7 @@ void I_StopSound (INT32 handle)
 	//  an setting the channel to zero.
 	int voice=handle & (VIRTUAL_VOICES-1);
 
-	if (nosound)
+	if (sound_disabled)
 		return;
 
 	if (voice_check(voice)==S_sfx[handle>>VOICESSHIFT].data)
@@ -199,7 +192,7 @@ void I_StopSound (INT32 handle)
 
 INT32 I_SoundIsPlaying(INT32 handle)
 {
-	if (nosound)
+	if (sound_disabled)
 		return FALSE;
 
 	if (voice_check(handle & (VIRTUAL_VOICES-1))==S_sfx[handle>>VOICESSHIFT].data)
@@ -229,7 +222,7 @@ void I_UpdateSoundParams( INT32 handle,
 	int voice=handle & (VIRTUAL_VOICES-1);
 	int numsfx=handle>>VOICESSHIFT;
 
-	if (nosound)
+	if (sound_disabled)
 		return;
 
 	if (voice_check(voice)==S_sfx[numsfx].data)
@@ -270,17 +263,17 @@ void I_StartupSound(void)
 	char   err[255];
 #endif
 
-	if (nosound)
+	if (sound_disabled)
 		sfxcard=DIGI_NONE;
 	else
 		sfxcard=DIGI_AUTODETECT;
 
-	if (nomidimusic)
+	if (midi_disabled)
 		midicard=MIDI_NONE;
 	else
 		midicard=MIDI_AUTODETECT; //DetectMusicCard();
 
-	nodigimusic=true; //Alam: No OGG/MP3/IT/MOD support
+	digital_disabled=true; //Alam: No OGG/MP3/IT/MOD support
 
 	// Secure and configure sound device first.
 	CONS_Printf("I_StartupSound: ");
@@ -293,8 +286,8 @@ void I_StartupSound(void)
 	{
 		sprintf (err,"Sound init error : %s\n",allegro_error);
 		CONS_Error (err);
-		nosound=true;
-		nomidimusic=true;
+		sound_disabled=true;
+		midi_disabled=true;
 	}
 	else
 	{
@@ -321,7 +314,11 @@ static MIDI* currsong;   //im assuming only 1 song will be played at once
 static int      islooping=0;
 static int      musicdies=-1;
 UINT8           music_started=0;
+boolean         songpaused=false;
 
+/// ------------------------
+//  MUSIC SYSTEM
+/// ------------------------
 
 /* load_midi_mem:
  *  Loads a standard MIDI file from memory, returning a pointer to
@@ -389,116 +386,66 @@ static MIDI *load_midi_mem(char *mempointer,int *e)
 	return midi;
 }
 
-void I_InitMIDIMusic(void)
+void I_InitMusic(void)
 {
-	if (nomidimusic)
+	if (midi_disabled)
 		return;
 
 	I_AddExitFunc(I_ShutdownMusic);
 	music_started = true;
-}
-
-void I_ShutdownMIDIMusic(void)
-{
-	if ( !music_started )
-		return;
-
-	I_StopSong(1);
-
-	music_started=false;
-}
-
-void I_InitDigMusic(void)
-{
-//	CONS_Printf("Digital music not yet supported under DOS.\n");
-}
-
-void I_ShutdownDigMusic(void)
-{
-//	CONS_Printf("Digital music not yet supported under DOS.\n");
-}
-
-void I_InitMusic(void)
-{
-	if (!nodigimusic)
-		I_InitDigMusic();
-	if (!nomidimusic)
-		I_InitMIDIMusic();
+	songpaused = false;
 }
 
 void I_ShutdownMusic(void)
 {
-	I_ShutdownMIDIMusic();
-	I_ShutdownDigMusic();
+	if ( !music_started )
+		return;
+
+	I_StopSong();
+
+	music_started=false;
 }
 
-boolean I_PlaySong(INT32 handle, INT32 looping)
-{
-	handle = 0;
-	if (nomidimusic)
-		return false;
+/// ------------------------
+//  MUSIC PROPERTIES
+/// ------------------------
 
-	islooping = looping;
-	musicdies = gametic + NEWTICRATE*30;
-	if (play_midi(currsong,looping)==0)
-		return true;
+musictype_t I_SongType(void)
+{
+	if (currsong)
+		return MU_MID;
+	else
+		return MU_NONE;
+}
+
+boolean I_SongPlaying()
+{
+	return (boolean)currsong;
+}
+
+boolean I_SongPaused()
+{
+	return songpaused;
+}
+
+/// ------------------------
+//  MUSIC EFFECTS
+/// ------------------------
+
+boolean I_SetSongSpeed(float speed)
+{
+	(void)speed;
 	return false;
 }
 
-void I_PauseSong (INT32 handle)
-{
-	handle = 0;
-	if (nomidimusic)
-		return;
+/// ------------------------
+//  MUSIC PLAYBACK
+/// ------------------------
 
-	midi_pause();
-}
-
-void I_ResumeSong (INT32 handle)
-{
-	handle = 0;
-	if (nomidimusic)
-		return;
-
-	midi_resume();
-}
-
-void I_StopSong(INT32 handle)
-{
-	handle = 0;
-	if (nomidimusic)
-		return;
-
-	islooping = 0;
-	musicdies = 0;
-	stop_midi();
-}
-
-// Is the song playing?
-#if 0
-int I_QrySongPlaying(int handle)
-{
-	if (nomidimusic)
-		return 0;
-
-	//return islooping || musicdies > gametic;
-	return (midi_pos==-1);
-}
-#endif
-
-void I_UnRegisterSong(INT32 handle)
-{
-	handle = 0;
-	if (nomidimusic)
-		return;
-
-	//destroy_midi(currsong);
-}
-
-INT32 I_RegisterSong(void *data, size_t len)
+boolean I_LoadSong(char *data, size_t len)
 {
 	int e = len; //Alam: For error
-	if (nomidimusic)
+	if (midi_disabled)
 		return 0;
 
 	if (memcmp(data,"MThd",4)==0) // support mid file in WAD !!!
@@ -520,32 +467,81 @@ INT32 I_RegisterSong(void *data, size_t len)
 	return 1;
 }
 
-/// \todo Add OGG/MP3 support for dos
-boolean I_StartDigSong(const char *musicname, INT32 looping)
+void I_UnloadSong(void)
 {
-	musicname = NULL;
-	looping = 0;
-	//CONS_Printf("I_StartDigSong: Not yet supported under DOS.\n");
+	handle = 0;
+	if (midi_disabled)
+		return;
+
+	//destroy_midi(currsong);
+}
+
+boolean I_PlaySong(boolean looping)
+{
+	handle = 0;
+	if (midi_disabled)
+		return false;
+
+	islooping = looping;
+	musicdies = gametic + NEWTICRATE*30;
+	if (play_midi(currsong,looping)==0)
+		return true;
 	return false;
 }
 
-void I_StopDigSong(void)
+void I_StopSong(void)
 {
-//	CONS_Printf("I_StopDigSong: Not yet supported under DOS.\n");
+	handle = 0;
+	if (midi_disabled)
+		return;
+
+	islooping = 0;
+	musicdies = 0;
+	stop_midi();
+	songpaused = false;
 }
 
-void I_SetDigMusicVolume(INT32 volume)
+void I_PauseSong (INT32 handle)
 {
-	volume = 0;
-	if (nodigimusic)
+	handle = 0;
+	if (midi_disabled)
+		return;
+	midi_pause();
+	songpaused = true;
+}
+
+void I_ResumeSong (INT32 handle)
+{
+	handle = 0;
+	if (midi_disabled)
+		return;
+	midi_resume();
+	songpaused = false;
+}
+
+void I_SetMusicVolume(INT32 volume)
+{
+	if (midi_disabled)
 		return;
 
 	// Now set volume on output device.
-//	CONS_Printf("Digital music not yet supported under DOS.\n");
+	set_volume (-1, Volset(volume));
 }
 
-boolean I_SetSongSpeed(float speed)
+boolean I_SetSongTrack(INT32 track)
 {
-	(void)speed;
+	(void)track;
 	return false;
 }
+
+// Is the song playing?
+#if 0
+int I_QrySongPlaying(int handle)
+{
+	if (midi_disabled)
+		return 0;
+
+	//return islooping || musicdies > gametic;
+	return (midi_pos==-1);
+}
+#endif
diff --git a/src/djgppdos/rdb-s.h b/src/djgppdos/rdb-s.h
index 6202dacfa..7a6d8be3c 100644
--- a/src/djgppdos/rdb-s.h
+++ b/src/djgppdos/rdb-s.h
@@ -1,7 +1,7 @@
 // Emacs style mode select   -*- C++ -*-
 //-----------------------------------------------------------------------------
 //
-// Copyright (C) 2005 by Sonic Team Jr.
+// Copyright (C) 2005-2018 by Sonic Team Jr.
 //
 // This program is free software; you can redistribute it and/or
 // modify it under the terms of the GNU General Public License
diff --git a/src/doomdata.h b/src/doomdata.h
index e916a151f..ff025e99c 100644
--- a/src/doomdata.h
+++ b/src/doomdata.h
@@ -2,7 +2,7 @@
 //-----------------------------------------------------------------------------
 // Copyright (C) 1993-1996 by id Software, Inc.
 // Copyright (C) 1998-2000 by DooM Legacy Team.
-// Copyright (C) 1999-2016 by Sonic Team Junior.
+// Copyright (C) 1999-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
diff --git a/src/doomdef.h b/src/doomdef.h
index 7f641558f..470fa20bb 100644
--- a/src/doomdef.h
+++ b/src/doomdef.h
@@ -2,7 +2,7 @@
 //-----------------------------------------------------------------------------
 // Copyright (C) 1993-1996 by id Software, Inc.
 // Copyright (C) 1998-2000 by DooM Legacy Team.
-// Copyright (C) 1999-2016 by Sonic Team Junior.
+// Copyright (C) 1999-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
@@ -502,4 +502,11 @@ extern const char *compdate, *comptime, *comprevision, *compbranch;
 /// \note   Required for proper collision with moving sloped surfaces that have sector specials on them.
 //#define SECTORSPECIALSAFTERTHINK
 
+/// FINALLY some real clipping that doesn't make walls dissappear AND speeds the game up
+/// (that was the original comment from SRB2CB, sadly it is a lie and actually slows game down)
+/// on the bright side it fixes some weird issues with translucent walls
+/// \note	SRB2CB port.
+///      	SRB2CB itself ported this from PrBoom+
+#define NEWCLIP
+
 #endif // __DOOMDEF__
diff --git a/src/doomstat.h b/src/doomstat.h
index 8072a1552..52da2ae2c 100644
--- a/src/doomstat.h
+++ b/src/doomstat.h
@@ -2,7 +2,7 @@
 //-----------------------------------------------------------------------------
 // Copyright (C) 1993-1996 by id Software, Inc.
 // Copyright (C) 1998-2000 by DooM Legacy Team.
-// Copyright (C) 1999-2016 by Sonic Team Junior.
+// Copyright (C) 1999-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
@@ -85,10 +85,7 @@ extern boolean fromlevelselect;
 // Internal parameters for sound rendering.
 // ========================================
 
-extern boolean nomidimusic; // defined in d_main.c
-extern boolean nosound;
-extern boolean nodigimusic;
-extern boolean music_disabled;
+extern boolean midi_disabled;
 extern boolean sound_disabled;
 extern boolean digital_disabled;
 
@@ -445,19 +442,17 @@ extern mapthing_t *redctfstarts[MAXPLAYERS]; // CTF
 
 #if defined (macintosh)
 #define DEBFILE(msg) I_OutputMsg(msg)
-extern FILE *debugfile;
 #else
 #define DEBUGFILE
 #ifdef DEBUGFILE
 #define DEBFILE(msg) { if (debugfile) { fputs(msg, debugfile); fflush(debugfile); } }
-extern FILE *debugfile;
 #else
 #define DEBFILE(msg) {}
-extern FILE *debugfile;
 #endif
 #endif
 
 #ifdef DEBUGFILE
+extern FILE *debugfile;
 extern INT32 debugload;
 #endif
 
diff --git a/src/doomtype.h b/src/doomtype.h
index a711b466d..b44e32e46 100644
--- a/src/doomtype.h
+++ b/src/doomtype.h
@@ -2,7 +2,7 @@
 //-----------------------------------------------------------------------------
 // Copyright (C) 1993-1996 by id Software, Inc.
 // Copyright (C) 1998-2000 by DooM Legacy Team.
-// Copyright (C) 1999-2016 by Sonic Team Junior.
+// Copyright (C) 1999-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
@@ -44,12 +44,13 @@
 typedef long ssize_t;
 
 /* Older Visual C++ headers don't have the Win64-compatible typedefs... */
-#if ((_MSC_VER <= 1200) && (!defined(DWORD_PTR)))
-#define DWORD_PTR DWORD
-#endif
-
-#if ((_MSC_VER <= 1200) && (!defined(PDWORD_PTR)))
-#define PDWORD_PTR PDWORD
+#if (_MSC_VER <= 1200)
+	#ifndef DWORD_PTR
+		#define DWORD_PTR DWORD
+	#endif
+	#ifndef PDWORD_PTR
+		#define PDWORD_PTR PDWORD
+	#endif
 #endif
 #elif defined (_arch_dreamcast) // KOS Dreamcast
 #include <arch/types.h>
@@ -97,12 +98,14 @@ typedef long ssize_t;
 #define NOIPX
 #endif
 
+/* Strings and some misc platform specific stuff */
+
 #if defined (_MSC_VER) || defined (__OS2__)
 	// Microsoft VisualC++
 #ifdef _MSC_VER
 #if (_MSC_VER <= 1800) // MSVC 2013 and back
 	#define snprintf                _snprintf
-#if (_MSC_VER <= 1200) // MSVC 2012 and back
+#if (_MSC_VER <= 1200) // MSVC 6.0 and back
 	#define vsnprintf               _vsnprintf
 #endif
 #endif
@@ -178,6 +181,8 @@ size_t strlcpy(char *dst, const char *src, size_t siz);
 // not the number of bytes in the buffer.
 #define STRBUFCPY(dst,src) strlcpy(dst, src, sizeof dst)
 
+/* Boolean type definition */
+
 // \note __BYTEBOOL__ used to be set above if "macintosh" was defined,
 // if macintosh's version of boolean type isn't needed anymore, then isn't this macro pointless now?
 #ifndef __BYTEBOOL__
@@ -185,7 +190,7 @@ size_t strlcpy(char *dst, const char *src, size_t siz);
 
 	//faB: clean that up !!
 	#if defined( _MSC_VER)  && (_MSC_VER >= 1800) // MSVC 2013 and forward
-	#include "stdbool.h"
+		#include "stdbool.h"
 	#elif (defined (_WIN32) || (defined (_WIN32_WCE) && !defined (__GNUC__))) && !defined (_XBOX)
 		#define false   FALSE           // use windows types
 		#define true    TRUE
@@ -240,93 +245,71 @@ size_t strlcpy(char *dst, const char *src, size_t siz);
 #define UINT64_MAX 0xffffffffffffffffULL /* 18446744073709551615ULL */
 #endif
 
-union FColorRGBA
-{
-	UINT32 rgba;
-	struct
-	{
-		UINT8 red;
-		UINT8 green;
-		UINT8 blue;
-		UINT8 alpha;
-	} s;
-} ATTRPACK;
-typedef union FColorRGBA RGBA_t;
-
-typedef enum
-{
-	postimg_none,
-	postimg_water,
-	postimg_motion,
-	postimg_flip,
-	postimg_heat
-} postimg_t;
-
-typedef UINT32 lumpnum_t; // 16 : 16 unsigned long (wad num: lump num)
-#define LUMPERROR UINT32_MAX
-
-typedef UINT32 tic_t;
-#define INFTICS UINT32_MAX
-
-#ifdef _BIG_ENDIAN
-#define UINT2RGBA(a) a
-#else
-#define UINT2RGBA(a) (UINT32)((a&0xff)<<24)|((a&0xff00)<<8)|((a&0xff0000)>>8)|(((UINT32)a&0xff000000)>>24)
-#endif
+/* Compiler-specific attributes and other macros */
 
 #ifdef __GNUC__ // __attribute__ ((X))
-#define FUNCNORETURN __attribute__ ((noreturn))
-#if ((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 1)) && defined (__MINGW32__)
-#include "inttypes.h"
-#if 0 //defined  (__USE_MINGW_ANSI_STDIO) && __USE_MINGW_ANSI_STDIO > 0
-#define FUNCPRINTF __attribute__ ((format(gnu_printf, 1, 2)))
-#define FUNCDEBUG  __attribute__ ((format(gnu_printf, 2, 3)))
-#define FUNCIERROR __attribute__ ((format(gnu_printf, 1, 2),noreturn))
-#elif (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4)
-#define FUNCPRINTF __attribute__ ((format(ms_printf, 1, 2)))
-#define FUNCDEBUG  __attribute__ ((format(ms_printf, 2, 3)))
-#define FUNCIERROR __attribute__ ((format(ms_printf, 1, 2),noreturn))
-#else
-#define FUNCPRINTF __attribute__ ((format(printf, 1, 2)))
-#define FUNCDEBUG  __attribute__ ((format(printf, 2, 3)))
-#define FUNCIERROR __attribute__ ((format(printf, 1, 2),noreturn))
-#endif
-#else
-#define FUNCPRINTF __attribute__ ((format(printf, 1, 2)))
-#define FUNCDEBUG  __attribute__ ((format(printf, 2, 3)))
-#define FUNCIERROR __attribute__ ((format(printf, 1, 2),noreturn))
-#endif
-#ifndef FUNCIERROR
-#define FUNCIERROR __attribute__ ((noreturn))
-#endif
-#define FUNCMATH __attribute__((const))
-#if (__GNUC__ > 3) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1)
-#define FUNCDEAD __attribute__ ((deprecated))
-#define FUNCINLINE __attribute__((always_inline))
-#define FUNCNONNULL __attribute__((nonnull))
-#endif
-#define FUNCNOINLINE __attribute__((noinline))
-#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4)
-#ifdef __i386__ // i386 only
-#define FUNCTARGET(X)  __attribute__ ((__target__ (X)))
-#endif
-#endif
-#if defined (__MINGW32__) && ((__GNUC__ > 3) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4))
-#define ATTRPACK __attribute__((packed, gcc_struct))
-#else
-#define ATTRPACK __attribute__((packed))
-#endif
-#define ATTRUNUSED __attribute__((unused))
-#ifdef _XBOX
-#define FILESTAMP I_OutputMsg("%s:%d\n",__FILE__,__LINE__);
-#define XBOXSTATIC static
-#endif
+	#define FUNCNORETURN __attribute__ ((noreturn))
+
+	#if ((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 1)) && defined (__MINGW32__) // MinGW, >= GCC 4.1
+		#include "inttypes.h"
+		#if 0 //defined  (__USE_MINGW_ANSI_STDIO) && __USE_MINGW_ANSI_STDIO > 0
+			#define FUNCPRINTF __attribute__ ((format(gnu_printf, 1, 2)))
+			#define FUNCDEBUG  __attribute__ ((format(gnu_printf, 2, 3)))
+			#define FUNCIERROR __attribute__ ((format(gnu_printf, 1, 2),noreturn))
+		#elif (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4) // >= GCC 4.4
+			#define FUNCPRINTF __attribute__ ((format(ms_printf, 1, 2)))
+			#define FUNCDEBUG  __attribute__ ((format(ms_printf, 2, 3)))
+			#define FUNCIERROR __attribute__ ((format(ms_printf, 1, 2),noreturn))
+		#else
+			#define FUNCPRINTF __attribute__ ((format(printf, 1, 2)))
+			#define FUNCDEBUG  __attribute__ ((format(printf, 2, 3)))
+			#define FUNCIERROR __attribute__ ((format(printf, 1, 2),noreturn))
+		#endif
+	#else
+		#define FUNCPRINTF __attribute__ ((format(printf, 1, 2)))
+		#define FUNCDEBUG  __attribute__ ((format(printf, 2, 3)))
+		#define FUNCIERROR __attribute__ ((format(printf, 1, 2),noreturn))
+	#endif
+
+	#ifndef FUNCIERROR
+		#define FUNCIERROR __attribute__ ((noreturn))
+	#endif
+
+	#define FUNCMATH __attribute__((const))
+
+	#if (__GNUC__ > 3) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1) // >= GCC 3.1
+		#define FUNCDEAD __attribute__ ((deprecated))
+		#define FUNCINLINE __attribute__((always_inline))
+		#define FUNCNONNULL __attribute__((nonnull))
+	#endif
+
+	#define FUNCNOINLINE __attribute__((noinline))
+
+	#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4) // >= GCC 4.4
+		#ifdef __i386__ // i386 only
+			#define FUNCTARGET(X)  __attribute__ ((__target__ (X)))
+		#endif
+	#endif
+
+	#if defined (__MINGW32__) && ((__GNUC__ > 3) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) // MinGW, >= GCC 3.4
+		#define ATTRPACK __attribute__((packed, gcc_struct))
+	#else
+		#define ATTRPACK __attribute__((packed))
+	#endif
+
+	#define ATTRUNUSED __attribute__((unused))
+
+	// Xbox-only macros
+	#ifdef _XBOX
+		#define FILESTAMP I_OutputMsg("%s:%d\n",__FILE__,__LINE__);
+		#define XBOXSTATIC static
+	#endif
 #elif defined (_MSC_VER)
-#define ATTRNORETURN __declspec(noreturn)
-#define ATTRINLINE __forceinline
-#if _MSC_VER > 1200
-#define ATTRNOINLINE __declspec(noinline)
-#endif
+	#define ATTRNORETURN __declspec(noreturn)
+	#define ATTRINLINE __forceinline
+	#if _MSC_VER > 1200 // >= MSVC 6.0
+		#define ATTRNOINLINE __declspec(noinline)
+	#endif
 #endif
 
 #ifndef FUNCPRINTF
@@ -380,4 +363,43 @@ typedef UINT32 tic_t;
 #ifndef FILESTAMP
 #define FILESTAMP
 #endif
+
+/* Miscellaneous types that don't fit anywhere else (Can this be changed?) */
+
+union FColorRGBA
+{
+	UINT32 rgba;
+	struct
+	{
+		UINT8 red;
+		UINT8 green;
+		UINT8 blue;
+		UINT8 alpha;
+	} s;
+} ATTRPACK;
+typedef union FColorRGBA RGBA_t;
+
+typedef enum
+{
+	postimg_none,
+	postimg_water,
+	postimg_motion,
+	postimg_flip,
+	postimg_heat
+} postimg_t;
+
+typedef UINT32 lumpnum_t; // 16 : 16 unsigned long (wad num: lump num)
+#define LUMPERROR UINT32_MAX
+
+typedef UINT32 tic_t;
+#define INFTICS UINT32_MAX
+
+#include "endian.h" // This is needed to make sure the below macro acts correctly in big endian builds
+
+#ifdef SRB2_BIG_ENDIAN
+#define UINT2RGBA(a) a
+#else
+#define UINT2RGBA(a) (UINT32)((a&0xff)<<24)|((a&0xff00)<<8)|((a&0xff0000)>>8)|(((UINT32)a&0xff000000)>>24)
+#endif
+
 #endif //__DOOMTYPE__
diff --git a/src/dummy/i_sound.c b/src/dummy/i_sound.c
index 51dbb610d..7275bb1ae 100644
--- a/src/dummy/i_sound.c
+++ b/src/dummy/i_sound.c
@@ -23,13 +23,14 @@ void I_UpdateSound(void){};
 //  SFX I/O
 //
 
-INT32 I_StartSound(sfxenum_t id, UINT8 vol, UINT8 sep, UINT8 pitch, UINT8 priority)
+INT32 I_StartSound(sfxenum_t id, UINT8 vol, UINT8 sep, UINT8 pitch, UINT8 priority, INT32 channel)
 {
 	(void)id;
 	(void)vol;
 	(void)sep;
 	(void)pitch;
 	(void)priority;
+	(void)channel;
 	return -1;
 }
 
@@ -57,82 +58,36 @@ void I_SetSfxVolume(UINT8 volume)
 	(void)volume;
 }
 
-//
-//  MUSIC I/O
-//
+/// ------------------------
+//  MUSIC SYSTEM
+/// ------------------------
 
 void I_InitMusic(void){}
 
 void I_ShutdownMusic(void){}
 
-void I_PauseSong(INT32 handle)
+/// ------------------------
+//  MUSIC PROPERTIES
+/// ------------------------
+
+musictype_t I_SongType(void)
 {
-	(void)handle;
+	return MU_NONE;
 }
 
-void I_ResumeSong(INT32 handle)
+boolean I_SongPlaying(void)
 {
-	(void)handle;
-}
-
-//
-//  MIDI I/O
-//
-
-void I_InitMIDIMusic(void){}
-
-void I_ShutdownMIDIMusic(void){}
-
-void I_SetMIDIMusicVolume(UINT8 volume)
-{
-	(void)volume;
-}
-
-INT32 I_RegisterSong(void *data, size_t len)
-{
-	(void)data;
-	(void)len;
-	return -1;
-}
-
-boolean I_PlaySong(INT32 handle, boolean looping)
-{
-	(void)handle;
-	(void)looping;
 	return false;
 }
 
-void I_StopSong(INT32 handle)
+boolean I_SongPaused(void)
 {
-	(void)handle;
-}
-
-void I_UnRegisterSong(INT32 handle)
-{
-	(void)handle;
-}
-
-//
-//  DIGMUSIC I/O
-//
-
-void I_InitDigMusic(void){}
-
-void I_ShutdownDigMusic(void){}
-
-boolean I_StartDigSong(const char *musicname, boolean looping)
-{
-	(void)musicname;
-	(void)looping;
 	return false;
 }
 
-void I_StopDigSong(void){}
-
-void I_SetDigMusicVolume(UINT8 volume)
-{
-	(void)volume;
-}
+/// ------------------------
+//  MUSIC EFFECTS
+/// ------------------------
 
 boolean I_SetSongSpeed(float speed)
 {
@@ -140,8 +95,51 @@ boolean I_SetSongSpeed(float speed)
 	return false;
 }
 
+/// ------------------------
+//  MUSIC PLAYBACK
+/// ------------------------
+
+boolean I_LoadSong(char *data, size_t len)
+{
+	(void)data;
+	(void)len;
+	return -1;
+}
+
+void I_UnloadSong(void)
+{
+	(void)handle;
+}
+
+boolean I_PlaySong(boolean looping)
+{
+	(void)handle;
+	(void)looping;
+	return false;
+}
+
+void I_StopSong(void)
+{
+	(void)handle;
+}
+
+void I_PauseSong(void)
+{
+	(void)handle;
+}
+
+void I_ResumeSong(void)
+{
+	(void)handle;
+}
+
+void I_SetMusicVolume(UINT8 volume)
+{
+	(void)volume;
+}
+
 boolean I_SetSongTrack(int track)
 {
 	(void)track;
 	return false;
-}
+}
\ No newline at end of file
diff --git a/src/endian.h b/src/endian.h
index 2b876e7cb..d3c1cb18b 100644
--- a/src/endian.h
+++ b/src/endian.h
@@ -1,6 +1,6 @@
 // SONIC ROBO BLAST 2
 //-----------------------------------------------------------------------------
-// Copyright (C) 2014-2016 by Sonic Team Junior.
+// Copyright (C) 2014-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
diff --git a/src/f_finale.c b/src/f_finale.c
index a8b27bb80..7662ac061 100644
--- a/src/f_finale.c
+++ b/src/f_finale.c
@@ -2,7 +2,7 @@
 //-----------------------------------------------------------------------------
 // Copyright (C) 1993-1996 by id Software, Inc.
 // Copyright (C) 1998-2000 by DooM Legacy Team.
-// Copyright (C) 1999-2016 by Sonic Team Junior.
+// Copyright (C) 1999-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
@@ -442,7 +442,6 @@ void F_StartIntro(void)
 
 	G_SetGamestate(GS_INTRO);
 	gameaction = ga_nothing;
-	playerdeadview = false;
 	paused = false;
 	CON_ToggleOff();
 	CON_ClearHUD();
@@ -980,6 +979,8 @@ static const char *credits[] = {
 	"Callum Dickinson",
 	"Scott \"Graue\" Feeney",
 	"Nathan \"Jazz\" Giroux",
+	"Vivian \"toaster\" Grannell",
+	"Kepa \"Nev3r\" Iceta",
 	"Thomas \"Shadow Hog\" Igoe",
 	"Iestyn \"Monster Iestyn\" Jealous",
 	"Ronald \"Furyhunter\" Kinard", // The SDL2 port
@@ -987,6 +988,7 @@ static const char *credits[] = {
 	"Ehab \"Wolfy\" Saeed",
 	"\"Kaito Sinclaire\"",
 	"\"SSNTails\"",
+	"Marco \"mazmazz\" Zafra",
 	"",
 	"\1Programming",
 	"\1Assistance",
@@ -994,7 +996,6 @@ static const char *credits[] = {
 	"Andrew \"orospakr\" Clunis",
 	"Gregor \"Oogaland\" Dick",
 	"Louis-Antoine \"LJSonic\" de Moulins", // for fixing 2.1's netcode (de Rochefort doesn't quite fit on the screen sorry lol)
-	"Vivian \"toaster\" Grannell",
 	"Julio \"Chaos Zero 64\" Guir",
 	"\"Kalaron\"", // Coded some of Sryder13's collection of OpenGL fixes, especially fog
 	"Matthew \"Shuffle\" Marsalko",
@@ -1002,7 +1003,12 @@ static const char *credits[] = {
 	"\"Morph\"", // For SRB2Morphed stuff
 	"Colin \"Sonict\" Pfaff",
 	"Sean \"Sryder13\" Ryder",
+	"Tasos \"tatokis\" Sahanidis", // Corrected C FixedMul, making 64-bit builds netplay compatible
+	"\"Steel Titanium\"",
 	"Ben \"Cue\" Woodford",
+	// Git contributors with 5+ approved merges, at least a few of substantive quality, may be named
+	// Everyone else is acknowledged here
+	"STJr Git Contributors",
 	"",
 	"\1Sprite Artists",
 	"Odi \"Iceman404\" Atunzu",
@@ -1049,13 +1055,13 @@ static const char *credits[] = {
 	"Thomas \"Shadow Hog\" Igoe",
 	"Erik \"Torgo\" Nielsen",
 	"\"Kaito Sinclaire\"",
-	"Wessel \"Spherallic\" Smit",
+	"Wessel \"sphere\" Smit",
 	"\"Spazzo\"",
 	"\"SSNTails\"",
 	"Rob Tisdell",
 	"Jarrett \"JEV3\" Voight",
 	"Johnny \"Sonikku\" Wallbank",
-	"Marco \"Digiku\" Zafra",
+	"Marco \"mazmazz\" Zafra",
 	"",
 	"\1Boss Design",
 	"Ben \"Mystic\" Geyer",
@@ -1130,7 +1136,6 @@ void F_StartCredits(void)
 	}
 
 	gameaction = ga_nothing;
-	playerdeadview = false;
 	paused = false;
 	CON_ToggleOff();
 	CON_ClearHUD();
@@ -1154,6 +1159,9 @@ void F_CreditDrawer(void)
 	for (i = 0; credits_pics[i].patch; i++)
 		V_DrawSciencePatch(credits_pics[i].x<<FRACBITS, (credits_pics[i].y<<FRACBITS) - 4*(animtimer<<FRACBITS)/5, 0, W_CachePatchName(credits_pics[i].patch, PU_CACHE), FRACUNIT>>1);
 
+	// Dim the background
+	V_DrawFadeScreen();
+
 	// Draw credits text on top
 	for (i = 0; credits[i]; i++)
 	{
@@ -1277,7 +1285,6 @@ void F_StartGameEvaluation(void)
 		G_SaveGame((UINT32)cursaveslot);
 
 	gameaction = ga_nothing;
-	playerdeadview = false;
 	paused = false;
 	CON_ToggleOff();
 	CON_ClearHUD();
@@ -1388,7 +1395,6 @@ void F_StartGameEnd(void)
 	G_SetGamestate(GS_GAMEEND);
 
 	gameaction = ga_nothing;
-	playerdeadview = false;
 	paused = false;
 	CON_ToggleOff();
 	CON_ClearHUD();
@@ -1405,6 +1411,7 @@ void F_StartGameEnd(void)
 //
 void F_GameEndDrawer(void)
 {
+	// this function does nothing
 }
 
 //
@@ -1591,7 +1598,6 @@ void F_StartContinue(void)
 	gameaction = ga_nothing;
 
 	keypressed = false;
-	playerdeadview = false;
 	paused = false;
 	CON_ToggleOff();
 	CON_ClearHUD();
@@ -1760,7 +1766,6 @@ void F_StartCustomCutscene(INT32 cutscenenum, boolean precutscene, boolean reset
 	G_SetGamestate(GS_CUTSCENE);
 
 	gameaction = ga_nothing;
-	playerdeadview = false;
 	paused = false;
 	CON_ToggleOff();
 
diff --git a/src/f_finale.h b/src/f_finale.h
index 1f23643be..efab71698 100644
--- a/src/f_finale.h
+++ b/src/f_finale.h
@@ -2,7 +2,7 @@
 //-----------------------------------------------------------------------------
 // Copyright (C) 1993-1996 by id Software, Inc.
 // Copyright (C) 1998-2000 by DooM Legacy Team.
-// Copyright (C) 1999-2016 by Sonic Team Junior.
+// Copyright (C) 1999-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
@@ -35,7 +35,7 @@ void F_CutsceneTicker(void);
 void F_TitleDemoTicker(void);
 
 // Called by main loop.
-FUNCMATH void F_GameEndDrawer(void);
+void F_GameEndDrawer(void);
 void F_IntroDrawer(void);
 void F_TitleScreenDrawer(void);
 
diff --git a/src/f_wipe.c b/src/f_wipe.c
index e45f2e85b..95dd5bbde 100644
--- a/src/f_wipe.c
+++ b/src/f_wipe.c
@@ -3,7 +3,7 @@
 // Copyright (C) 1993-1996 by id Software, Inc.
 // Copyright (C) 1998-2000 by DooM Legacy Team.
 // Copyright (C) 2013-2016 by Matthew "Inuyasha" Walsh.
-// Copyright (C) 1999-2016 by Sonic Team Junior.
+// Copyright (C) 1999-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
diff --git a/src/g_game.c b/src/g_game.c
index 4f1c49b42..4a7719fa0 100644
--- a/src/g_game.c
+++ b/src/g_game.c
@@ -2,7 +2,7 @@
 //-----------------------------------------------------------------------------
 // Copyright (C) 1993-1996 by id Software, Inc.
 // Copyright (C) 1998-2000 by DooM Legacy Team.
-// Copyright (C) 1999-2016 by Sonic Team Junior.
+// Copyright (C) 1999-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
@@ -1575,11 +1575,6 @@ static void Analog_OnChange(void)
 		return;
 	}
 
-	if (cv_analog.value)
-		players[consoleplayer].pflags |= PF_ANALOGMODE;
-	else
-		players[consoleplayer].pflags &= ~PF_ANALOGMODE;
-
 	SendWeaponPref();
 }
 
@@ -1600,11 +1595,6 @@ static void Analog2_OnChange(void)
 		return;
 	}
 
-	if (cv_analog2.value)
-		players[secondarydisplayplayer].pflags |= PF_ANALOGMODE;
-	else
-		players[secondarydisplayplayer].pflags &= ~PF_ANALOGMODE;
-
 	SendWeaponPref2();
 }
 
@@ -3616,7 +3606,6 @@ void G_InitNew(UINT8 pultmode, const char *mapname, boolean resetplayer, boolean
 	mapmusflags |= MUSIC_RELOADRESET;
 
 	ultimatemode = pultmode;
-	playerdeadview = false;
 	automapactive = false;
 	imcontinuing = false;
 
diff --git a/src/g_game.h b/src/g_game.h
index ada82404c..e33d13661 100644
--- a/src/g_game.h
+++ b/src/g_game.h
@@ -2,7 +2,7 @@
 //-----------------------------------------------------------------------------
 // Copyright (C) 1993-1996 by id Software, Inc.
 // Copyright (C) 1998-2000 by DooM Legacy Team.
-// Copyright (C) 1999-2016 by Sonic Team Junior.
+// Copyright (C) 1999-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
@@ -56,6 +56,9 @@ extern INT16 rw_maximums[NUM_WEAPONS];
 // used in game menu
 extern consvar_t cv_crosshair, cv_crosshair2;
 extern consvar_t cv_invertmouse, cv_alwaysfreelook, cv_mousemove;
+extern consvar_t cv_invertmouse2, cv_alwaysfreelook2, cv_mousemove2;
+extern consvar_t cv_useranalog, cv_useranalog2;
+extern consvar_t cv_analog, cv_analog2;
 extern consvar_t cv_sideaxis,cv_turnaxis,cv_moveaxis,cv_lookaxis,cv_fireaxis,cv_firenaxis;
 extern consvar_t cv_sideaxis2,cv_turnaxis2,cv_moveaxis2,cv_lookaxis2,cv_fireaxis2,cv_firenaxis2;
 extern consvar_t cv_ghost_bestscore, cv_ghost_besttime, cv_ghost_bestrings, cv_ghost_last, cv_ghost_guest;
diff --git a/src/g_input.c b/src/g_input.c
index b004384c0..09ea336ac 100644
--- a/src/g_input.c
+++ b/src/g_input.c
@@ -1,7 +1,7 @@
 // SONIC ROBO BLAST 2
 //-----------------------------------------------------------------------------
 // Copyright (C) 1998-2000 by DooM Legacy Team.
-// Copyright (C) 1999-2016 by Sonic Team Junior.
+// Copyright (C) 1999-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
diff --git a/src/g_input.h b/src/g_input.h
index d65339321..6dc99ac55 100644
--- a/src/g_input.h
+++ b/src/g_input.h
@@ -1,7 +1,7 @@
 // SONIC ROBO BLAST 2
 //-----------------------------------------------------------------------------
 // Copyright (C) 1998-2000 by DooM Legacy Team.
-// Copyright (C) 1999-2016 by Sonic Team Junior.
+// Copyright (C) 1999-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
@@ -126,6 +126,8 @@ typedef enum
 
 // mouse values are used once
 extern consvar_t cv_mousesens, cv_mouseysens;
+extern consvar_t cv_mousesens2, cv_mouseysens2;
+extern consvar_t cv_controlperkey;
 
 extern INT32 mousex, mousey;
 extern INT32 mlooky; //mousey with mlookSensitivity
diff --git a/src/g_state.h b/src/g_state.h
index 81548b7ce..76c9bd16f 100644
--- a/src/g_state.h
+++ b/src/g_state.h
@@ -1,7 +1,7 @@
 // SONIC ROBO BLAST 2
 //-----------------------------------------------------------------------------
 // Copyright (C) 1998-2000 by DooM Legacy Team.
-// Copyright (C) 1999-2016 by Sonic Team Junior.
+// Copyright (C) 1999-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
diff --git a/src/hardware/hw3sound.c b/src/hardware/hw3sound.c
index c68430921..f7c6e1da0 100644
--- a/src/hardware/hw3sound.c
+++ b/src/hardware/hw3sound.c
@@ -361,7 +361,7 @@ INT32 HW3S_I_StartSound(const void *origin_p, source3D_data_t *source_parm, chan
 
 	if (splitscreen) listenmobj2 = players[secondarydisplayplayer].mo;
 
-	if (nosound)
+	if (sound_disabled)
 		return -1;
 
 	sfx = &S_sfx[sfx_id];
diff --git a/src/hardware/hw_bsp.c b/src/hardware/hw_bsp.c
index 17eb8761c..a180697d5 100644
--- a/src/hardware/hw_bsp.c
+++ b/src/hardware/hw_bsp.c
@@ -564,8 +564,6 @@ static inline void HWR_SubsecPoly(INT32 num, poly_t *poly)
 	subsector_t *sub;
 	seg_t *lseg;
 
-	sscount++;
-
 	sub = &subsectors[num];
 	count = sub->numlines;
 	lseg = &segs[sub->firstline];
@@ -635,6 +633,7 @@ static void WalkBSPNode(INT32 bspnum, poly_t *poly, UINT16 *leafnode, fixed_t *b
 			HWR_SubsecPoly(bspnum&(~NF_SUBSECTOR), poly);
 			//Hurdler: implement a loading status
 
+#ifdef HWR_LOADING_SCREEN
 			if (ls_count-- <= 0)
 			{
 				char s[16];
@@ -659,6 +658,7 @@ static void WalkBSPNode(INT32 bspnum, poly_t *poly, UINT16 *leafnode, fixed_t *b
 
 				I_UpdateNoVsync();
 			}
+#endif
 		}
 		M_ClearBox(bbox);
 		poly = extrasubsectors[bspnum&~NF_SUBSECTOR].planepoly;
@@ -880,8 +880,8 @@ static void AdjustSegs(void)
 		count = subsectors[i].numlines;
 		lseg = &segs[subsectors[i].firstline];
 		p = extrasubsectors[i].planepoly;
-		if (!p)
-			continue;
+		//if (!p)
+			//continue;
 		for (; count--; lseg++)
 		{
 			float distv1,distv2,tmp;
@@ -894,29 +894,31 @@ static void AdjustSegs(void)
 				continue;
 #endif
 
-			for (j = 0; j < p->numpts; j++)
-			{
-				distv1 = p->pts[j].x - FIXED_TO_FLOAT(lseg->v1->x);
-				tmp    = p->pts[j].y - FIXED_TO_FLOAT(lseg->v1->y);
-				distv1 = distv1*distv1+tmp*tmp;
-				if (distv1 <= nearv1)
+			if (p) {
+				for (j = 0; j < p->numpts; j++)
 				{
-					v1found = j;
-					nearv1 = distv1;
-				}
-				// the same with v2
-				distv2 = p->pts[j].x - FIXED_TO_FLOAT(lseg->v2->x);
-				tmp    = p->pts[j].y - FIXED_TO_FLOAT(lseg->v2->y);
-				distv2 = distv2*distv2+tmp*tmp;
-				if (distv2 <= nearv2)
-				{
-					v2found = j;
-					nearv2 = distv2;
+					distv1 = p->pts[j].x - FIXED_TO_FLOAT(lseg->v1->x);
+					tmp    = p->pts[j].y - FIXED_TO_FLOAT(lseg->v1->y);
+					distv1 = distv1*distv1+tmp*tmp;
+					if (distv1 <= nearv1)
+					{
+						v1found = j;
+						nearv1 = distv1;
+					}
+					// the same with v2
+					distv2 = p->pts[j].x - FIXED_TO_FLOAT(lseg->v2->x);
+					tmp    = p->pts[j].y - FIXED_TO_FLOAT(lseg->v2->y);
+					distv2 = distv2*distv2+tmp*tmp;
+					if (distv2 <= nearv2)
+					{
+						v2found = j;
+						nearv2 = distv2;
+					}
 				}
 			}
-			if (nearv1 <= NEARDIST*NEARDIST)
+			if (p && nearv1 <= NEARDIST*NEARDIST)
 				// share vertice with segs
-				lseg->v1 = (vertex_t *)&(p->pts[v1found]);
+				lseg->pv1 = &(p->pts[v1found]);
 			else
 			{
 				// BP: here we can do better, using PointInSeg and compute
@@ -927,24 +929,24 @@ static void AdjustSegs(void)
 				polyvertex_t *pv = HWR_AllocVertex();
 				pv->x = FIXED_TO_FLOAT(lseg->v1->x);
 				pv->y = FIXED_TO_FLOAT(lseg->v1->y);
-				lseg->v1 = (vertex_t *)pv;
+				lseg->pv1 = pv;
 			}
-			if (nearv2 <= NEARDIST*NEARDIST)
-				lseg->v2 = (vertex_t *)&(p->pts[v2found]);
+			if (p && nearv2 <= NEARDIST*NEARDIST)
+				lseg->pv2 = &(p->pts[v2found]);
 			else
 			{
 				polyvertex_t *pv = HWR_AllocVertex();
 				pv->x = FIXED_TO_FLOAT(lseg->v2->x);
 				pv->y = FIXED_TO_FLOAT(lseg->v2->y);
-				lseg->v2 = (vertex_t *)pv;
+				lseg->pv2 = pv;
 			}
 
 			// recompute length
 			{
 				float x,y;
-				x = ((polyvertex_t *)lseg->v2)->x - ((polyvertex_t *)lseg->v1)->x
+				x = ((polyvertex_t *)lseg->pv2)->x - ((polyvertex_t *)lseg->pv1)->x
 					+ FIXED_TO_FLOAT(FRACUNIT/2);
-				y = ((polyvertex_t *)lseg->v2)->y - ((polyvertex_t *)lseg->v1)->y
+				y = ((polyvertex_t *)lseg->pv2)->y - ((polyvertex_t *)lseg->pv1)->y
 					+ FIXED_TO_FLOAT(FRACUNIT/2);
 				lseg->flength = (float)hypot(x, y);
 				// BP: debug see this kind of segs
diff --git a/src/hardware/hw_clip.c b/src/hardware/hw_clip.c
new file mode 100644
index 000000000..6d120efe7
--- /dev/null
+++ b/src/hardware/hw_clip.c
@@ -0,0 +1,465 @@
+/* Emacs style mode select   -*- C++ -*-
+ *-----------------------------------------------------------------------------
+ *
+ *
+ *  PrBoom: a Doom port merged with LxDoom and LSDLDoom
+ *  based on BOOM, a modified and improved DOOM engine
+ *  Copyright (C) 1999 by
+ *  id Software, Chi Hoang, Lee Killough, Jim Flynn, Rand Phares, Ty Halderman
+ *  Copyright (C) 1999-2000 by
+ *  Jess Haas, Nicolas Kalkhof, Colin Phipps, Florian Schulze
+ *  Copyright 2005, 2006 by
+ *  Florian Schulze, Colin Phipps, Neil Stevens, Andrey Budko
+ *
+ *  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.
+ *
+ * DESCRIPTION:
+ *
+ *---------------------------------------------------------------------
+ */
+
+/*
+ *
+ ** gl_clipper.cpp
+ **
+ ** Handles visibility checks.
+ ** Loosely based on the JDoom clipper.
+ **
+ **---------------------------------------------------------------------------
+ ** Copyright 2003 Tim Stump
+ ** All rights reserved.
+ **
+ ** Redistribution and use in source and binary forms, with or without
+ ** modification, are permitted provided that the following conditions
+ ** are met:
+ **
+ ** 1. Redistributions of source code must retain the above copyright
+ **    notice, this list of conditions and the following disclaimer.
+ ** 2. 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.
+ ** 3. The name of the author may not be used to endorse or promote products
+ **    derived from this software without specific prior written permission.
+ **
+ ** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ **---------------------------------------------------------------------------
+ **
+ */
+
+#include <math.h>
+#include "../v_video.h"
+#include "hw_clip.h"
+#include "hw_glob.h"
+#include "../r_state.h"
+#include "../tables.h"
+#include "r_opengl/r_opengl.h"
+
+#ifdef HAVE_SPHEREFRUSTRUM
+static GLdouble viewMatrix[16];
+static GLdouble projMatrix[16];
+float frustum[6][4];
+#endif
+
+typedef struct clipnode_s
+	{
+		struct clipnode_s *prev, *next;
+		angle_t start, end;
+	} clipnode_t;
+
+clipnode_t *freelist;
+clipnode_t *clipnodes;
+clipnode_t *cliphead;
+
+static clipnode_t * gld_clipnode_GetNew(void);
+static clipnode_t * gld_clipnode_NewRange(angle_t start, angle_t end);
+static boolean gld_clipper_IsRangeVisible(angle_t startAngle, angle_t endAngle);
+static void gld_clipper_AddClipRange(angle_t start, angle_t end);
+static void gld_clipper_RemoveRange(clipnode_t * range);
+static void gld_clipnode_Free(clipnode_t *node);
+
+static clipnode_t * gld_clipnode_GetNew(void)
+{
+	if (freelist)
+	{
+		clipnode_t * p = freelist;
+		freelist = p->next;
+		return p;
+	}
+	else
+	{
+		return (clipnode_t*)malloc(sizeof(clipnode_t));
+	}
+}
+
+static clipnode_t * gld_clipnode_NewRange(angle_t start, angle_t end)
+{
+	clipnode_t * c = gld_clipnode_GetNew();
+	c->start = start;
+	c->end = end;
+	c->next = c->prev=NULL;
+	return c;
+}
+
+boolean gld_clipper_SafeCheckRange(angle_t startAngle, angle_t endAngle)
+{
+	if(startAngle > endAngle)
+	{
+		return (gld_clipper_IsRangeVisible(startAngle, ANGLE_MAX) || gld_clipper_IsRangeVisible(0, endAngle));
+	}
+
+	return gld_clipper_IsRangeVisible(startAngle, endAngle);
+}
+
+static boolean gld_clipper_IsRangeVisible(angle_t startAngle, angle_t endAngle)
+{
+	clipnode_t *ci;
+	ci = cliphead;
+
+	if (endAngle == 0 && ci && ci->start == 0)
+		return false;
+
+	while (ci != NULL && ci->start < endAngle)
+	{
+		if (startAngle >= ci->start && endAngle <= ci->end)
+		{
+			return false;
+		}
+		ci = ci->next;
+	}
+
+	return true;
+}
+
+static void gld_clipnode_Free(clipnode_t *node)
+{
+	node->next = freelist;
+	freelist = node;
+}
+
+static void gld_clipper_RemoveRange(clipnode_t *range)
+{
+	if (range == cliphead)
+	{
+		cliphead = cliphead->next;
+	}
+	else
+	{
+		if (range->prev)
+		{
+			range->prev->next = range->next;
+		}
+		if (range->next)
+		{
+			range->next->prev = range->prev;
+		}
+	}
+
+	gld_clipnode_Free(range);
+}
+
+void gld_clipper_SafeAddClipRange(angle_t startangle, angle_t endangle)
+{
+	if(startangle > endangle)
+	{
+		// The range has to added in two parts.
+		gld_clipper_AddClipRange(startangle, ANGLE_MAX);
+		gld_clipper_AddClipRange(0, endangle);
+	}
+	else
+	{
+		// Add the range as usual.
+		gld_clipper_AddClipRange(startangle, endangle);
+	}
+}
+
+static void gld_clipper_AddClipRange(angle_t start, angle_t end)
+{
+	clipnode_t *node, *temp, *prevNode, *node2, *delnode;
+
+	if (cliphead)
+	{
+		//check to see if range contains any old ranges
+		node = cliphead;
+		while (node != NULL && node->start < end)
+		{
+			if (node->start >= start && node->end <= end)
+			{
+				temp = node;
+				node = node->next;
+				gld_clipper_RemoveRange(temp);
+			}
+			else
+			{
+				if (node->start <= start && node->end >= end)
+				{
+					return;
+				}
+				else
+				{
+					node = node->next;
+				}
+			}
+		}
+
+		//check to see if range overlaps a range (or possibly 2)
+		node = cliphead;
+		while (node != NULL && node->start <= end)
+		{
+			if (node->end >= start)
+			{
+				// we found the first overlapping node
+				if (node->start > start)
+				{
+					// the new range overlaps with this node's start point
+					node->start = start;
+				}
+				if (node->end < end)
+				{
+					node->end = end;
+				}
+
+				node2 = node->next;
+				while (node2 && node2->start <= node->end)
+				{
+					if (node2->end > node->end)
+					{
+						node->end = node2->end;
+					}
+
+					delnode = node2;
+					node2 = node2->next;
+					gld_clipper_RemoveRange(delnode);
+				}
+				return;
+			}
+			node = node->next;
+		}
+
+		//just add range
+		node = cliphead;
+		prevNode = NULL;
+		temp = gld_clipnode_NewRange(start, end);
+		while (node != NULL && node->start < end)
+		{
+			prevNode = node;
+			node = node->next;
+		}
+		temp->next = node;
+		if (node == NULL)
+		{
+			temp->prev = prevNode;
+			if (prevNode)
+			{
+				prevNode->next = temp;
+			}
+			if (!cliphead)
+			{
+				cliphead = temp;
+			}
+		}
+		else
+		{
+			if (node == cliphead)
+			{
+				cliphead->prev = temp;
+				cliphead = temp;
+			}
+			else
+			{
+				temp->prev = prevNode;
+				prevNode->next = temp;
+				node->prev = temp;
+			}
+		}
+	}
+	else
+	{
+		temp = gld_clipnode_NewRange(start, end);
+		cliphead = temp;
+		return;
+	}
+}
+
+void gld_clipper_Clear(void)
+{
+	clipnode_t *node = cliphead;
+	clipnode_t *temp;
+
+	while (node != NULL)
+	{
+		temp = node;
+		node = node->next;
+		gld_clipnode_Free(temp);
+	}
+
+	cliphead = NULL;
+}
+
+#define RMUL (1.6f/1.333333f)
+
+angle_t gld_FrustumAngle(void)
+{
+	double floatangle;
+	angle_t a1;
+
+	float tilt = (float)fabs(((double)(int)aimingangle) / ANG1);
+
+	// NEWCLIP TODO: SRB2CBTODO: make a global render_fov for this function
+
+	float render_fov = FIXED_TO_FLOAT(cv_grfov.value);
+	float render_fovratio = (float)BASEVIDWIDTH / (float)BASEVIDHEIGHT; // SRB2CBTODO: NEWCLIPTODO: Is this right?
+	float render_multiplier = 64.0f / render_fovratio / RMUL;
+
+	if (tilt > 90.0f)
+	{
+		tilt = 90.0f;
+	}
+
+	// If the pitch is larger than this you can look all around at a FOV of 90
+	if (abs((signed)aimingangle) > 46 * ANG1)
+		return 0xffffffff;
+
+	// ok, this is a gross hack that barely works...
+	// but at least it doesn't overestimate too much...
+	floatangle = 2.0f + (45.0f + (tilt / 1.9f)) * (float)render_fov * 48.0f / render_multiplier / 90.0f;
+	a1 = ANG1 * (int)floatangle;
+	if (a1 >= ANGLE_180)
+		return 0xffffffff;
+	return a1;
+}
+
+// SRB2CB I don't think used any of this stuff, let's disable for now since SRB2 probably doesn't want it either
+// compiler complains about (p)glGetDoublev anyway, in case anyone wants this
+// only r_opengl.c can use the base gl funcs as it turns out, that's a problem for whoever wants sphere frustum checks
+// btw to renable define HAVE_SPHEREFRUSTRUM in hw_clip.h
+#ifdef HAVE_SPHEREFRUSTRUM
+//
+// gld_FrustrumSetup
+//
+
+#define CALCMATRIX(a, b, c, d, e, f, g, h)\
+(float)(viewMatrix[a] * projMatrix[b] + \
+viewMatrix[c] * projMatrix[d] + \
+viewMatrix[e] * projMatrix[f] + \
+viewMatrix[g] * projMatrix[h])
+
+#define NORMALIZE_PLANE(i)\
+t = (float)sqrt(\
+frustum[i][0] * frustum[i][0] + \
+frustum[i][1] * frustum[i][1] + \
+frustum[i][2] * frustum[i][2]); \
+frustum[i][0] /= t; \
+frustum[i][1] /= t; \
+frustum[i][2] /= t; \
+frustum[i][3] /= t
+
+void gld_FrustrumSetup(void)
+{
+	float t;
+	float clip[16];
+
+	pglGetDoublev(GL_PROJECTION_MATRIX, projMatrix);
+	pglGetDoublev(GL_MODELVIEW_MATRIX, viewMatrix);
+
+	clip[0]  = CALCMATRIX(0, 0, 1, 4, 2, 8, 3, 12);
+	clip[1]  = CALCMATRIX(0, 1, 1, 5, 2, 9, 3, 13);
+	clip[2]  = CALCMATRIX(0, 2, 1, 6, 2, 10, 3, 14);
+	clip[3]  = CALCMATRIX(0, 3, 1, 7, 2, 11, 3, 15);
+
+	clip[4]  = CALCMATRIX(4, 0, 5, 4, 6, 8, 7, 12);
+	clip[5]  = CALCMATRIX(4, 1, 5, 5, 6, 9, 7, 13);
+	clip[6]  = CALCMATRIX(4, 2, 5, 6, 6, 10, 7, 14);
+	clip[7]  = CALCMATRIX(4, 3, 5, 7, 6, 11, 7, 15);
+
+	clip[8]  = CALCMATRIX(8, 0, 9, 4, 10, 8, 11, 12);
+	clip[9]  = CALCMATRIX(8, 1, 9, 5, 10, 9, 11, 13);
+	clip[10] = CALCMATRIX(8, 2, 9, 6, 10, 10, 11, 14);
+	clip[11] = CALCMATRIX(8, 3, 9, 7, 10, 11, 11, 15);
+
+	clip[12] = CALCMATRIX(12, 0, 13, 4, 14, 8, 15, 12);
+	clip[13] = CALCMATRIX(12, 1, 13, 5, 14, 9, 15, 13);
+	clip[14] = CALCMATRIX(12, 2, 13, 6, 14, 10, 15, 14);
+	clip[15] = CALCMATRIX(12, 3, 13, 7, 14, 11, 15, 15);
+
+	// Right plane
+	frustum[0][0] = clip[ 3] - clip[ 0];
+	frustum[0][1] = clip[ 7] - clip[ 4];
+	frustum[0][2] = clip[11] - clip[ 8];
+	frustum[0][3] = clip[15] - clip[12];
+	NORMALIZE_PLANE(0);
+
+	// Left plane
+	frustum[1][0] = clip[ 3] + clip[ 0];
+	frustum[1][1] = clip[ 7] + clip[ 4];
+	frustum[1][2] = clip[11] + clip[ 8];
+	frustum[1][3] = clip[15] + clip[12];
+	NORMALIZE_PLANE(1);
+
+	// Bottom plane
+	frustum[2][0] = clip[ 3] + clip[ 1];
+	frustum[2][1] = clip[ 7] + clip[ 5];
+	frustum[2][2] = clip[11] + clip[ 9];
+	frustum[2][3] = clip[15] + clip[13];
+	NORMALIZE_PLANE(2);
+
+	// Top plane
+	frustum[3][0] = clip[ 3] - clip[ 1];
+	frustum[3][1] = clip[ 7] - clip[ 5];
+	frustum[3][2] = clip[11] - clip[ 9];
+	frustum[3][3] = clip[15] - clip[13];
+	NORMALIZE_PLANE(3);
+
+	// Far plane
+	frustum[4][0] = clip[ 3] - clip[ 2];
+	frustum[4][1] = clip[ 7] - clip[ 6];
+	frustum[4][2] = clip[11] - clip[10];
+	frustum[4][3] = clip[15] - clip[14];
+	NORMALIZE_PLANE(4);
+
+	// Near plane
+	frustum[5][0] = clip[ 3] + clip[ 2];
+	frustum[5][1] = clip[ 7] + clip[ 6];
+	frustum[5][2] = clip[11] + clip[10];
+	frustum[5][3] = clip[15] + clip[14];
+	NORMALIZE_PLANE(5);
+}
+
+boolean gld_SphereInFrustum(float x, float y, float z, float radius)
+{
+	int p;
+
+	for (p = 0; p < 4; p++)
+	{
+		if (frustum[p][0] * x +
+			frustum[p][1] * y +
+			frustum[p][2] * z +
+			frustum[p][3] <= -radius)
+		{
+			return false;
+		}
+	}
+	return true;
+}
+#endif
diff --git a/src/hardware/hw_clip.h b/src/hardware/hw_clip.h
new file mode 100644
index 000000000..3ba26e5e5
--- /dev/null
+++ b/src/hardware/hw_clip.h
@@ -0,0 +1,24 @@
+/*
+ *  hw_clip.h
+ *  SRB2CB
+ *
+ *  PrBoom's OpenGL clipping
+ *
+ *
+ */
+
+// OpenGL BSP clipping
+#include "../doomdef.h"
+#include "../tables.h"
+#include "../doomtype.h"
+
+//#define HAVE_SPHEREFRUSTRUM // enable if you want gld_SphereInFrustum and related code
+
+boolean gld_clipper_SafeCheckRange(angle_t startAngle, angle_t endAngle);
+void gld_clipper_SafeAddClipRange(angle_t startangle, angle_t endangle);
+void gld_clipper_Clear(void);
+angle_t gld_FrustumAngle(void);
+#ifdef HAVE_SPHEREFRUSTRUM
+void gld_FrustrumSetup(void);
+boolean gld_SphereInFrustum(float x, float y, float z, float radius);
+#endif
diff --git a/src/hardware/hw_data.h b/src/hardware/hw_data.h
index d76fcc1c8..4bbc578ed 100644
--- a/src/hardware/hw_data.h
+++ b/src/hardware/hw_data.h
@@ -26,10 +26,6 @@
 #include <windows.h>
 #endif
 
-#if defined (VID_X11) && !defined (HAVE_SDL)
-#include <GL/glx.h>
-#endif
-
 #include "../doomdef.h"
 //THIS MUST DISAPPEAR!!!
 #include "hw_glide.h"
diff --git a/src/hardware/hw_draw.c b/src/hardware/hw_draw.c
index 84081dd25..75523f3d2 100644
--- a/src/hardware/hw_draw.c
+++ b/src/hardware/hw_draw.c
@@ -112,10 +112,10 @@ void HWR_DrawPatch(GLPatch_t *gpatch, INT32 x, INT32 y, INT32 option)
 	if (option & V_NOSCALESTART)
 		sdupx = sdupy = 2.0f;
 
-	v[0].x = v[3].x = (x*sdupx-gpatch->leftoffset*pdupx)/vid.width - 1;
-	v[2].x = v[1].x = (x*sdupx+(gpatch->width-gpatch->leftoffset)*pdupx)/vid.width - 1;
-	v[0].y = v[1].y = 1-(y*sdupy-gpatch->topoffset*pdupy)/vid.height;
-	v[2].y = v[3].y = 1-(y*sdupy+(gpatch->height-gpatch->topoffset)*pdupy)/vid.height;
+	v[0].x = v[3].x = (x*sdupx-SHORT(gpatch->leftoffset)*pdupx)/vid.width - 1;
+	v[2].x = v[1].x = (x*sdupx+(SHORT(gpatch->width)-SHORT(gpatch->leftoffset))*pdupx)/vid.width - 1;
+	v[0].y = v[1].y = 1-(y*sdupy-SHORT(gpatch->topoffset)*pdupy)/vid.height;
+	v[2].y = v[3].y = 1-(y*sdupy+(SHORT(gpatch->height)-SHORT(gpatch->topoffset))*pdupy)/vid.height;
 
 	v[0].z = v[1].z = v[2].z = v[3].z = 1.0f;
 
@@ -179,18 +179,29 @@ void HWR_DrawFixedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscale,
 	dupx = dupy = (dupx < dupy ? dupx : dupy);
 	fscale = FIXED_TO_FLOAT(pscale);
 
-	if (option & V_OFFSET)
+	// See my comments in v_video.c's V_DrawFixedPatch
+	// -- Monster Iestyn 29/10/18
 	{
-		cx -= (float)gpatch->leftoffset * dupx * fscale;
-		cy -= (float)gpatch->topoffset * dupy * fscale;
-	}
-	else
-	{
-		cy -= (float)gpatch->topoffset * fscale;
+		float offsetx = 0.0f, offsety = 0.0f;
+
+		// left offset
 		if (option & V_FLIP)
-			cx -= ((float)gpatch->width - (float)gpatch->leftoffset) * fscale;
+			offsetx = (float)(SHORT(gpatch->width) - SHORT(gpatch->leftoffset)) * fscale;
 		else
-			cx -= (float)gpatch->leftoffset * fscale;
+			offsetx = (float)SHORT(gpatch->leftoffset) * fscale;
+
+		// top offset
+		// TODO: make some kind of vertical version of V_FLIP, maybe by deprecating V_OFFSET in future?!?
+		offsety = (float)SHORT(gpatch->topoffset) * fscale;
+
+		if ((option & (V_NOSCALESTART|V_OFFSET)) == (V_NOSCALESTART|V_OFFSET)) // Multiply by dupx/dupy for crosshairs
+		{
+			offsetx *= dupx;
+			offsety *= dupy;
+		}
+
+		cx -= offsetx;
+		cy -= offsety;
 	}
 
 	if (option & V_SPLITSCREEN)
@@ -216,14 +227,14 @@ void HWR_DrawFixedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscale,
 				Z_Free(realpatch);
 			}
 			// centre screen
-			if (vid.width != BASEVIDWIDTH * vid.dupx)
+			if ((float)vid.width != (float)BASEVIDWIDTH * dupx)
 			{
 				if (option & V_SNAPTORIGHT)
 					cx += ((float)vid.width - ((float)BASEVIDWIDTH * dupx));
 				else if (!(option & V_SNAPTOLEFT))
 					cx += ((float)vid.width - ((float)BASEVIDWIDTH * dupx))/2;
 			}
-			if (vid.height != BASEVIDHEIGHT * vid.dupy)
+			if ((float)vid.height != (float)BASEVIDHEIGHT * dupy)
 			{
 				if ((option & (V_SPLITSCREEN|V_SNAPTOBOTTOM)) == (V_SPLITSCREEN|V_SNAPTOBOTTOM))
 					cy += ((float)vid.height/2 - ((float)BASEVIDHEIGHT/2 * dupy));
@@ -237,13 +248,13 @@ void HWR_DrawFixedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscale,
 
 	if (pscale != FRACUNIT)
 	{
-		fwidth = (float)gpatch->width * fscale * dupx;
-		fheight = (float)gpatch->height * fscale * dupy;
+		fwidth = (float)SHORT(gpatch->width) * fscale * dupx;
+		fheight = (float)SHORT(gpatch->height) * fscale * dupy;
 	}
 	else
 	{
-		fwidth = (float)gpatch->width * dupx;
-		fheight = (float)gpatch->height * dupy;
+		fwidth = (float)SHORT(gpatch->width) * dupx;
+		fheight = (float)SHORT(gpatch->height) * dupy;
 	}
 
 	// positions of the cx, cy, are between 0 and vid.width/vid.height now, we need them to be between -1 and 1
@@ -341,8 +352,8 @@ void HWR_DrawCroppedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscal
 	dupx = dupy = (dupx < dupy ? dupx : dupy);
 	fscale = FIXED_TO_FLOAT(pscale);
 
-	cy -= (float)gpatch->topoffset * fscale;
-	cx -= (float)gpatch->leftoffset * fscale;
+	cy -= (float)SHORT(gpatch->topoffset) * fscale;
+	cx -= (float)SHORT(gpatch->leftoffset) * fscale;
 
 	if (!(option & V_NOSCALESTART))
 	{
@@ -364,14 +375,14 @@ void HWR_DrawCroppedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscal
 				Z_Free(realpatch);
 			}
 			// centre screen
-			if (vid.width != BASEVIDWIDTH * vid.dupx)
+			if ((float)vid.width != (float)BASEVIDWIDTH * dupx)
 			{
 				if (option & V_SNAPTORIGHT)
 					cx += ((float)vid.width - ((float)BASEVIDWIDTH * dupx));
 				else if (!(option & V_SNAPTOLEFT))
 					cx += ((float)vid.width - ((float)BASEVIDWIDTH * dupx))/2;
 			}
-			if (vid.height != BASEVIDHEIGHT * vid.dupy)
+			if ((float)vid.height != (float)BASEVIDHEIGHT * dupy)
 			{
 				if ((option & (V_SPLITSCREEN|V_SNAPTOBOTTOM)) == (V_SPLITSCREEN|V_SNAPTOBOTTOM))
 					cy += ((float)vid.height/2 - ((float)BASEVIDHEIGHT/2 * dupy));
@@ -392,11 +403,11 @@ void HWR_DrawCroppedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscal
 	if (fheight > h - sy)
 		fheight = h - sy;
 
-	if (fwidth > gpatch->width)
-		fwidth = gpatch->width;
+	if (fwidth > SHORT(gpatch->width))
+		fwidth = SHORT(gpatch->width);
 
-	if (fheight > gpatch->height)
-		fheight = gpatch->height;
+	if (fheight > SHORT(gpatch->height))
+		fheight = SHORT(gpatch->height);
 
 	if (pscale != FRACUNIT)
 	{
@@ -426,10 +437,10 @@ void HWR_DrawCroppedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscal
 
 	v[0].z = v[1].z = v[2].z = v[3].z = 1.0f;
 
-	v[0].sow = v[3].sow = ((sx)/(float)gpatch->width )*gpatch->max_s;
-	v[2].sow = v[1].sow = ((w )/(float)gpatch->width )*gpatch->max_s;
-	v[0].tow = v[1].tow = ((sy)/(float)gpatch->height)*gpatch->max_t;
-	v[2].tow = v[3].tow = ((h )/(float)gpatch->height)*gpatch->max_t;
+	v[0].sow = v[3].sow = ((sx)/(float)SHORT(gpatch->width) )*gpatch->max_s;
+	v[2].sow = v[1].sow = ((w )/(float)SHORT(gpatch->width) )*gpatch->max_s;
+	v[0].tow = v[1].tow = ((sy)/(float)SHORT(gpatch->height))*gpatch->max_t;
+	v[2].tow = v[3].tow = ((h )/(float)SHORT(gpatch->height))*gpatch->max_t;
 
 	flags = BLENDMODE|PF_Clip|PF_NoZClip|PF_NoDepthTest;
 
@@ -835,14 +846,14 @@ void HWR_DrawFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 color)
 		fw *= dupx;
 		fh *= dupy;
 
-		if (vid.width != BASEVIDWIDTH * vid.dupx)
+		if ((float)vid.width != (float)BASEVIDWIDTH * dupx)
 		{
 			if (color & V_SNAPTORIGHT)
 				fx += ((float)vid.width - ((float)BASEVIDWIDTH * dupx));
 			else if (!(color & V_SNAPTOLEFT))
 				fx += ((float)vid.width - ((float)BASEVIDWIDTH * dupx)) / 2;
 		}
-		if (vid.height != BASEVIDHEIGHT * dupy)
+		if ((float)vid.height != (float)BASEVIDHEIGHT * dupy)
 		{
 			// same thing here
 			if (color & V_SNAPTOBOTTOM)
diff --git a/src/hardware/hw_drv.h b/src/hardware/hw_drv.h
index a5ac82001..e2fa90eb0 100644
--- a/src/hardware/hw_drv.h
+++ b/src/hardware/hw_drv.h
@@ -32,10 +32,6 @@
 //                                                       STANDARD DLL EXPORTS
 // ==========================================================================
 
-#ifdef HAVE_SDL
-#undef VID_X11
-#endif
-
 EXPORT boolean HWRAPI(Init) (I_Error_t ErrorFunction);
 #ifndef HAVE_SDL
 EXPORT void HWRAPI(Shutdown) (void);
@@ -43,9 +39,6 @@ EXPORT void HWRAPI(Shutdown) (void);
 #ifdef _WINDOWS
 EXPORT void HWRAPI(GetModeList) (vmode_t **pvidmodes, INT32 *numvidmodes);
 #endif
-#ifdef VID_X11
-EXPORT Window HWRAPI(HookXwin) (Display *, INT32, INT32, boolean);
-#endif
 #if defined (PURESDL) || defined (macintosh)
 EXPORT void HWRAPI(SetPalette) (INT32 *, RGBA_t *gamma);
 #else
@@ -71,10 +64,6 @@ EXPORT void HWRAPI(SetTransform) (FTransform *ptransform);
 EXPORT INT32 HWRAPI(GetTextureUsed) (void);
 EXPORT INT32 HWRAPI(GetRenderVersion) (void);
 
-#ifdef VID_X11 // ifdef to be removed as soon as windoze supports that as well
-// metzgermeister: added for Voodoo detection
-EXPORT char *HWRAPI(GetRenderer) (void);
-#endif
 #ifdef SHUFFLE
 #define SCREENVERTS 10
 EXPORT void HWRAPI(PostImgRedraw) (float points[SCREENVERTS][SCREENVERTS][2]);
@@ -115,10 +104,6 @@ struct hwdriver_s
 #ifdef _WINDOWS
 	GetModeList         pfnGetModeList;
 #endif
-#ifdef VID_X11
-	HookXwin            pfnHookXwin;
-	GetRenderer         pfnGetRenderer;
-#endif
 #ifndef HAVE_SDL
 	Shutdown            pfnShutdown;
 #endif
diff --git a/src/hardware/hw_glob.h b/src/hardware/hw_glob.h
index fea06caff..bdf219464 100644
--- a/src/hardware/hw_glob.h
+++ b/src/hardware/hw_glob.h
@@ -27,6 +27,9 @@
 // the original aspect ratio of Doom graphics isn't square
 #define ORIGINAL_ASPECT (320.0f/200.0f)
 
+// Uncomment this to enable the OpenGL loading screen
+//#define HWR_LOADING_SCREEN
+
 // -----------
 // structures
 // -----------
diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c
index d7c73415a..fb5e2a716 100644
--- a/src/hardware/hw_main.c
+++ b/src/hardware/hw_main.c
@@ -44,6 +44,10 @@
 #endif
 #include "hw_md2.h"
 
+#ifdef NEWCLIP
+#include "hw_clip.h"
+#endif
+
 #define R_FAKEFLOORS
 #define HWPRECIP
 #define SORTING
@@ -99,8 +103,9 @@ CV_PossibleValue_t granisotropicmode_cons_t[] = {{1, "MIN"}, {16, "MAX"}, {0, NU
 boolean drawsky = true;
 
 // needs fix: walls are incorrectly clipped one column less
+#ifndef NEWCLIP
 static consvar_t cv_grclipwalls = {"gr_clipwalls", "Off", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
-
+#endif
 //development variables for diverse uses
 static consvar_t cv_gralpha = {"gr_alpha", "160", 0, CV_Unsigned, NULL, 0, NULL, NULL, 0, 0, NULL};
 static consvar_t cv_grbeta = {"gr_beta", "0", 0, CV_Unsigned, NULL, 0, NULL, NULL, 0, 0, NULL};
@@ -323,9 +328,6 @@ static angle_t gr_xtoviewangle[MAXVIDWIDTH+1];
 // test change fov when looking up/down but bsp projection messup :(
 //#define NOCRAPPYMLOOK
 
-/// \note crappy
-#define drawtextured true
-
 // base values set at SetViewSize
 static float gr_basecentery;
 
@@ -856,11 +858,11 @@ static void HWR_DrawSegsSplats(FSurfaceInfo * pSurf)
 
 	M_ClearBox(segbbox);
 	M_AddToBox(segbbox,
-		FLOAT_TO_FIXED(((polyvertex_t *)gr_curline->v1)->x),
-		FLOAT_TO_FIXED(((polyvertex_t *)gr_curline->v1)->y));
+		FLOAT_TO_FIXED(((polyvertex_t *)gr_curline->pv1)->x),
+		FLOAT_TO_FIXED(((polyvertex_t *)gr_curline->pv1)->y));
 	M_AddToBox(segbbox,
-		FLOAT_TO_FIXED(((polyvertex_t *)gr_curline->v2)->x),
-		FLOAT_TO_FIXED(((polyvertex_t *)gr_curline->v2)->y));
+		FLOAT_TO_FIXED(((polyvertex_t *)gr_curline->pv2)->x),
+		FLOAT_TO_FIXED(((polyvertex_t *)gr_curline->pv2)->y));
 
 	splat = (wallsplat_t *)gr_curline->linedef->splats;
 	for (; splat; splat = splat->next)
@@ -1033,6 +1035,7 @@ static void HWR_ProjectWall(wallVert3D   * wallVerts,
 // (in fact a clipping plane that has a constant, so can clip with simple 2d)
 // with the wall segment
 //
+#ifndef NEWCLIP
 static float HWR_ClipViewSegment(INT32 x, polyvertex_t *v1, polyvertex_t *v2)
 {
 	float num, den;
@@ -1061,11 +1064,12 @@ static float HWR_ClipViewSegment(INT32 x, polyvertex_t *v1, polyvertex_t *v2)
 
 	return num / den;
 }
+#endif
 
 //
 // HWR_SplitWall
 //
-static void HWR_SplitWall(sector_t *sector, wallVert3D *wallVerts, INT32 texnum, FSurfaceInfo* Surf, UINT32 cutflag, ffloor_t *pfloor)
+static void HWR_SplitWall(sector_t *sector, wallVert3D *wallVerts, INT32 texnum, FSurfaceInfo* Surf, INT32 cutflag, ffloor_t *pfloor)
 {
 	/* SoM: split up and light walls according to the
 	 lightlist. This may also include leaving out parts
@@ -1336,7 +1340,11 @@ static void HWR_DrawSkyWall(wallVert3D *wallVerts, FSurfaceInfo *Surf, fixed_t b
 // Anything between means the wall segment has been clipped with solidsegs,
 //  reducing wall overdraw to a minimum
 //
+#ifdef NEWCLIP
+static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
+#else
 static void HWR_StoreWallRange(double startfrac, double endfrac)
+#endif
 {
 	wallVert3D wallVerts[4];
 	v2d_t vs, ve; // start, end vertices of 2d line (view from above)
@@ -1361,16 +1369,18 @@ static void HWR_StoreWallRange(double startfrac, double endfrac)
 	extracolormap_t *colormap;
 	FSurfaceInfo Surf;
 
+#ifndef NEWCLIP
 	if (startfrac > endfrac)
 		return;
+#endif
 
 	gr_sidedef = gr_curline->sidedef;
 	gr_linedef = gr_curline->linedef;
 
-	vs.x = ((polyvertex_t *)gr_curline->v1)->x;
-	vs.y = ((polyvertex_t *)gr_curline->v1)->y;
-	ve.x = ((polyvertex_t *)gr_curline->v2)->x;
-	ve.y = ((polyvertex_t *)gr_curline->v2)->y;
+	vs.x = ((polyvertex_t *)gr_curline->pv1)->x;
+	vs.y = ((polyvertex_t *)gr_curline->pv1)->y;
+	ve.x = ((polyvertex_t *)gr_curline->pv2)->x;
+	ve.y = ((polyvertex_t *)gr_curline->pv2)->y;
 
 #ifdef ESLOPE
 	v1x = FLOAT_TO_FIXED(vs.x);
@@ -1378,44 +1388,21 @@ static void HWR_StoreWallRange(double startfrac, double endfrac)
 	v2x = FLOAT_TO_FIXED(ve.x);
 	v2y = FLOAT_TO_FIXED(ve.y);
 #endif
-
-	if (gr_frontsector->heightsec != -1)
-	{
 #ifdef ESLOPE
-		worldtop = worldtopslope = sectors[gr_frontsector->heightsec].ceilingheight;
-		worldbottom = worldbottomslope = sectors[gr_frontsector->heightsec].floorheight;
-#else
-		worldtop = sectors[gr_frontsector->heightsec].ceilingheight;
-		worldbottom = sectors[gr_frontsector->heightsec].floorheight;
-#endif
-	}
-	else
-	{
-#ifdef ESLOPE
-		if (gr_frontsector->c_slope)
-		{
-			worldtop      = P_GetZAt(gr_frontsector->c_slope, v1x, v1y);
-			worldtopslope = P_GetZAt(gr_frontsector->c_slope, v2x, v2y);
-		}
-		else
-		{
-			worldtop = worldtopslope = gr_frontsector->ceilingheight;
-		}
 
-		if (gr_frontsector->f_slope)
-		{
-			worldbottom      = P_GetZAt(gr_frontsector->f_slope, v1x, v1y);
-			worldbottomslope = P_GetZAt(gr_frontsector->f_slope, v2x, v2y);
-		}
-		else
-		{
-			worldbottom = worldbottomslope = gr_frontsector->floorheight;
-		}
+#define SLOPEPARAMS(slope, end1, end2, normalheight) \
+	if (slope) { \
+		end1 = P_GetZAt(slope, v1x, v1y); \
+		end2 = P_GetZAt(slope, v2x, v2y); \
+	} else \
+		end1 = end2 = normalheight;
+
+	SLOPEPARAMS(gr_frontsector->c_slope, worldtop,    worldtopslope,    gr_frontsector->ceilingheight)
+	SLOPEPARAMS(gr_frontsector->f_slope, worldbottom, worldbottomslope, gr_frontsector->floorheight)
 #else
-		worldtop    = gr_frontsector->ceilingheight;
-		worldbottom = gr_frontsector->floorheight;
+	worldtop    = gr_frontsector->ceilingheight;
+	worldbottom = gr_frontsector->floorheight;
 #endif
-	}
 
 	// remember vertices ordering
 	//  3--2
@@ -1430,20 +1417,23 @@ static void HWR_StoreWallRange(double startfrac, double endfrac)
 	wallVerts[2].z = wallVerts[1].z = ve.y;
 	wallVerts[0].w = wallVerts[1].w = wallVerts[2].w = wallVerts[3].w = 1.0f;
 
-	if (drawtextured)
 	{
 		// x offset the texture
 		fixed_t texturehpeg = gr_sidedef->textureoffset + gr_curline->offset;
 
+#ifndef NEWCLIP
 		// clip texture s start/end coords with solidsegs
 		if (startfrac > 0.0f && startfrac < 1.0f)
 			cliplow = (float)(texturehpeg + (gr_curline->flength*FRACUNIT) * startfrac);
 		else
+#endif
 			cliplow = (float)texturehpeg;
 
+#ifndef NEWCLIP
 		if (endfrac > 0.0f && endfrac < 1.0f)
 			cliphigh = (float)(texturehpeg + (gr_curline->flength*FRACUNIT) * endfrac);
 		else
+#endif
 			cliphigh = (float)(texturehpeg + (gr_curline->flength*FRACUNIT));
 	}
 
@@ -1459,43 +1449,15 @@ static void HWR_StoreWallRange(double startfrac, double endfrac)
 	{
 		INT32 gr_toptexture, gr_bottomtexture;
 		// two sided line
-		if (gr_backsector->heightsec != -1)
-		{
-#ifdef ESLOPE
-			worldhigh = worldhighslope = sectors[gr_backsector->heightsec].ceilingheight;
-			worldlow = worldlowslope = sectors[gr_backsector->heightsec].floorheight;
-#else
-			worldhigh = sectors[gr_backsector->heightsec].ceilingheight;
-			worldlow = sectors[gr_backsector->heightsec].floorheight;
-#endif
-		}
-		else
-		{
-#ifdef ESLOPE
-			if (gr_backsector->c_slope)
-			{
-				worldhigh      = P_GetZAt(gr_backsector->c_slope, v1x, v1y);
-				worldhighslope = P_GetZAt(gr_backsector->c_slope, v2x, v2y);
-			}
-			else
-			{
-				worldhigh = worldhighslope = gr_backsector->ceilingheight;
-			}
 
-			if (gr_backsector->f_slope)
-			{
-				worldlow      = P_GetZAt(gr_backsector->f_slope, v1x, v1y);
-				worldlowslope = P_GetZAt(gr_backsector->f_slope, v2x, v2y);
-			}
-			else
-			{
-				worldlow = worldlowslope = gr_backsector->floorheight;
-			}
+#ifdef ESLOPE
+		SLOPEPARAMS(gr_backsector->c_slope, worldhigh, worldhighslope, gr_backsector->ceilingheight)
+		SLOPEPARAMS(gr_backsector->f_slope, worldlow,  worldlowslope,  gr_backsector->floorheight)
+#undef SLOPEPARAMS
 #else
-			worldhigh = gr_backsector->ceilingheight;
-			worldlow  = gr_backsector->floorheight;
+		worldhigh = gr_backsector->ceilingheight;
+		worldlow  = gr_backsector->floorheight;
 #endif
-		}
 
 		// hack to allow height changes in outdoor areas
 		// This is what gets rid of the upper textures if there should be sky
@@ -1519,7 +1481,6 @@ static void HWR_StoreWallRange(double startfrac, double endfrac)
             worldhigh < worldtop
             ) && gr_toptexture)
 		{
-			if (drawtextured)
 			{
 				fixed_t texturevpegtop; // top
 
@@ -1600,7 +1561,6 @@ static void HWR_StoreWallRange(double startfrac, double endfrac)
 #endif
             worldlow > worldbottom) && gr_bottomtexture) //only if VISIBLE!!!
 		{
-			if (drawtextured)
 			{
 				fixed_t texturevpegbottom = 0; // bottom
 
@@ -1792,7 +1752,6 @@ static void HWR_StoreWallRange(double startfrac, double endfrac)
 			h = min(highcut, polytop);
 			l = max(polybottom, lowcut);
 
-			if (drawtextured)
 			{
 				// PEGGING
 #ifdef ESLOPE
@@ -1848,7 +1807,6 @@ static void HWR_StoreWallRange(double startfrac, double endfrac)
 				h = min(highcut, polytop);
 				l = max(polybottom, lowcut);
 
-				if (drawtextured)
 				{
 					// PEGGING
 					if (!!(gr_linedef->flags & ML_DONTPEGBOTTOM) ^ !!(gr_linedef->flags & ML_EFFECT3))
@@ -2039,7 +1997,6 @@ static void HWR_StoreWallRange(double startfrac, double endfrac)
 		gr_midtexture = R_GetTextureNum(gr_sidedef->midtexture);
 		if (gr_midtexture)
 		{
-			if (drawtextured)
 			{
 				fixed_t     texturevpeg;
 				// PEGGING
@@ -2180,9 +2137,13 @@ static void HWR_StoreWallRange(double startfrac, double endfrac)
 					wallVerts[0].s = wallVerts[3].s = 0;
 					wallVerts[2].s = wallVerts[1].s = 0;
 				}
-				else if (drawtextured)
+				else
 				{
 					fixed_t texturevpeg;
+					boolean attachtobottom = false;
+#ifdef ESLOPE
+					boolean slopeskew = false; // skew FOF walls with slopes?
+#endif
 
 					// Wow, how was this missing from OpenGL for so long?
 					// ...Oh well, anyway, Lower Unpegged now changes pegging of FOFs like in software
@@ -2190,24 +2151,50 @@ static void HWR_StoreWallRange(double startfrac, double endfrac)
 					if (newline)
 					{
 						texturevpeg = sides[newline->sidenum[0]].rowoffset;
-						if (newline->flags & ML_DONTPEGBOTTOM)
-							texturevpeg -= *rover->topheight - *rover->bottomheight;
+						attachtobottom = !!(newline->flags & ML_DONTPEGBOTTOM);
+#ifdef ESLOPE
+						slopeskew = !!(newline->flags & ML_DONTPEGTOP);
+#endif
 					}
 					else
 					{
 						texturevpeg = sides[rover->master->sidenum[0]].rowoffset;
-						if (gr_linedef->flags & ML_DONTPEGBOTTOM)
-							texturevpeg -= *rover->topheight - *rover->bottomheight;
+						attachtobottom = !!(gr_linedef->flags & ML_DONTPEGBOTTOM);
+#ifdef ESLOPE
+						slopeskew = !!(rover->master->flags & ML_DONTPEGTOP);
+#endif
 					}
 
 					grTex = HWR_GetTexture(texnum);
 
 #ifdef ESLOPE
-					wallVerts[3].t = (*rover->topheight - h + texturevpeg) * grTex->scaleY;
-					wallVerts[2].t = (*rover->topheight - hS + texturevpeg) * grTex->scaleY;
-					wallVerts[0].t = (*rover->topheight - l + texturevpeg) * grTex->scaleY;
-					wallVerts[1].t = (*rover->topheight - lS + texturevpeg) * grTex->scaleY;
+					if (!slopeskew) // no skewing
+					{
+						if (attachtobottom)
+							texturevpeg -= *rover->topheight - *rover->bottomheight;
+						wallVerts[3].t = (*rover->topheight - h + texturevpeg) * grTex->scaleY;
+						wallVerts[2].t = (*rover->topheight - hS + texturevpeg) * grTex->scaleY;
+						wallVerts[0].t = (*rover->topheight - l + texturevpeg) * grTex->scaleY;
+						wallVerts[1].t = (*rover->topheight - lS + texturevpeg) * grTex->scaleY;
+					}
+					else
+					{
+						if (!attachtobottom) // skew by top
+						{
+							wallVerts[3].t = wallVerts[2].t = texturevpeg * grTex->scaleY;
+							wallVerts[0].t = (h - l + texturevpeg) * grTex->scaleY;
+							wallVerts[1].t = (hS - lS + texturevpeg) * grTex->scaleY;
+						}
+						else // skew by bottom
+						{
+							wallVerts[0].t = wallVerts[1].t = texturevpeg * grTex->scaleY;
+							wallVerts[3].t = wallVerts[0].t - (h - l) * grTex->scaleY;
+							wallVerts[2].t = wallVerts[1].t - (hS - lS) * grTex->scaleY;
+						}
+					}
 #else
+					if (attachtobottom)
+						texturevpeg -= *rover->topheight - *rover->bottomheight;
 					wallVerts[3].t = wallVerts[2].t = (*rover->topheight - h + texturevpeg) * grTex->scaleY;
 					wallVerts[0].t = wallVerts[1].t = (*rover->topheight - l + texturevpeg) * grTex->scaleY;
 #endif
@@ -2316,7 +2303,7 @@ static void HWR_StoreWallRange(double startfrac, double endfrac)
 					wallVerts[0].s = wallVerts[3].s = 0;
 					wallVerts[2].s = wallVerts[1].s = 0;
 				}
-				else if (drawtextured)
+				else
 				{
 					grTex = HWR_GetTexture(texnum);
 
@@ -2385,6 +2372,110 @@ static void HWR_StoreWallRange(double startfrac, double endfrac)
 //Hurdler: end of 3d-floors test
 }
 
+// From PrBoom:
+//
+// e6y: Check whether the player can look beyond this line
+//
+#ifdef NEWCLIP
+boolean checkforemptylines = true;
+// Don't modify anything here, just check
+// Kalaron: Modified for sloped linedefs
+static boolean CheckClip(seg_t * seg, sector_t * afrontsector, sector_t * abacksector)
+{
+	fixed_t frontf1,frontf2, frontc1, frontc2; // front floor/ceiling ends
+	fixed_t backf1, backf2, backc1, backc2; // back floor ceiling ends
+
+	// GZDoom method of sloped line clipping
+
+#ifdef ESLOPE
+	if (afrontsector->f_slope || afrontsector->c_slope || abacksector->f_slope || abacksector->c_slope)
+	{
+		fixed_t v1x, v1y, v2x, v2y; // the seg's vertexes as fixed_t
+		v1x = FLOAT_TO_FIXED(((polyvertex_t *)gr_curline->pv1)->x);
+		v1y = FLOAT_TO_FIXED(((polyvertex_t *)gr_curline->pv1)->y);
+		v2x = FLOAT_TO_FIXED(((polyvertex_t *)gr_curline->pv2)->x);
+		v2y = FLOAT_TO_FIXED(((polyvertex_t *)gr_curline->pv2)->y);
+#define SLOPEPARAMS(slope, end1, end2, normalheight) \
+		if (slope) { \
+			end1 = P_GetZAt(slope, v1x, v1y); \
+			end2 = P_GetZAt(slope, v2x, v2y); \
+		} else \
+			end1 = end2 = normalheight;
+
+		SLOPEPARAMS(afrontsector->f_slope, frontf1, frontf2, afrontsector->floorheight)
+		SLOPEPARAMS(afrontsector->c_slope, frontc1, frontc2, afrontsector->ceilingheight)
+		SLOPEPARAMS( abacksector->f_slope, backf1,  backf2,  abacksector->floorheight)
+		SLOPEPARAMS( abacksector->c_slope, backc1,  backc2,  abacksector->ceilingheight)
+#undef SLOPEPARAMS
+	}
+	else
+#endif
+	{
+		frontf1 = frontf2 = afrontsector->floorheight;
+		frontc1 = frontc2 = afrontsector->ceilingheight;
+		backf1 = backf2 = abacksector->floorheight;
+		backc1 = backc2 = abacksector->ceilingheight;
+	}
+
+	// now check for closed sectors!
+	if (backc1 <= frontf1 && backc2 <= frontf2)
+	{
+		checkforemptylines = false;
+		if (!seg->sidedef->toptexture)
+			return false;
+
+		if (abacksector->ceilingpic == skyflatnum && afrontsector->ceilingpic == skyflatnum)
+			return false;
+
+		return true;
+	}
+
+	if (backf1 >= frontc1 && backf2 >= frontc2)
+	{
+		checkforemptylines = false;
+		if (!seg->sidedef->bottomtexture)
+			return false;
+
+		// properly render skies (consider door "open" if both floors are sky):
+		if (abacksector->ceilingpic == skyflatnum && afrontsector->ceilingpic == skyflatnum)
+			return false;
+
+		return true;
+	}
+
+	if (backc1 <= backf1 && backc2 <= backf2)
+	{
+		checkforemptylines = false;
+		// preserve a kind of transparent door/lift special effect:
+		if (backc1 < frontc1 || backc2 < frontc2)
+		{
+			if (!seg->sidedef->toptexture)
+				return false;
+		}
+		if (backf1 > frontf1 || backf2 > frontf2)
+		{
+			if (!seg->sidedef->bottomtexture)
+				return false;
+		}
+		if (abacksector->ceilingpic == skyflatnum && afrontsector->ceilingpic == skyflatnum)
+			return false;
+
+		if (abacksector->floorpic == skyflatnum && afrontsector->floorpic == skyflatnum)
+			return false;
+
+		return true;
+	}
+
+	if (backc1 != frontc1 || backc2 != frontc2
+		|| backf1 != frontf1 || backf2 != frontf2)
+		{
+			checkforemptylines = false;
+			return false;
+		}
+
+	return false;
+}
+#else
 //Hurdler: just like in r_bsp.c
 #if 1
 #define MAXSEGS         MAXVIDWIDTH/2+1
@@ -2456,7 +2547,7 @@ static void HWR_ClipSolidWallSegment(INT32 first, INT32 last)
 		}
 		else
 		{
-			highfrac = HWR_ClipViewSegment(start->first+1, (polyvertex_t *)gr_curline->v1, (polyvertex_t *)gr_curline->v2);
+			highfrac = HWR_ClipViewSegment(start->first+1, (polyvertex_t *)gr_curline->pv1, (polyvertex_t *)gr_curline->pv2);
 			HWR_StoreWallRange(0, highfrac);
 		}
 		// Now adjust the clip size.
@@ -2480,8 +2571,8 @@ static void HWR_ClipSolidWallSegment(INT32 first, INT32 last)
 		}
 		else
 		{
-			lowfrac  = HWR_ClipViewSegment(next->last-1, (polyvertex_t *)gr_curline->v1, (polyvertex_t *)gr_curline->v2);
-			highfrac = HWR_ClipViewSegment((next+1)->first+1, (polyvertex_t *)gr_curline->v1, (polyvertex_t *)gr_curline->v2);
+			lowfrac  = HWR_ClipViewSegment(next->last-1, (polyvertex_t *)gr_curline->pv1, (polyvertex_t *)gr_curline->pv2);
+			highfrac = HWR_ClipViewSegment((next+1)->first+1, (polyvertex_t *)gr_curline->pv1, (polyvertex_t *)gr_curline->pv2);
 			HWR_StoreWallRange(lowfrac, highfrac);
 		}
 		next++;
@@ -2515,7 +2606,7 @@ static void HWR_ClipSolidWallSegment(INT32 first, INT32 last)
 		}
 		else
 		{
-			lowfrac  = HWR_ClipViewSegment(next->last-1, (polyvertex_t *)gr_curline->v1, (polyvertex_t *)gr_curline->v2);
+			lowfrac  = HWR_ClipViewSegment(next->last-1, (polyvertex_t *)gr_curline->pv1, (polyvertex_t *)gr_curline->pv2);
 			HWR_StoreWallRange(lowfrac, 1);
 		}
 	}
@@ -2578,8 +2669,8 @@ static void HWR_ClipPassWallSegment(INT32 first, INT32 last)
 		else
 		{
 			highfrac = HWR_ClipViewSegment(min(start->first + 1,
-				start->last), (polyvertex_t *)gr_curline->v1,
-				(polyvertex_t *)gr_curline->v2);
+				start->last), (polyvertex_t *)gr_curline->pv1,
+				(polyvertex_t *)gr_curline->pv2);
 			HWR_StoreWallRange(0, highfrac);
 		}
 	}
@@ -2598,8 +2689,8 @@ static void HWR_ClipPassWallSegment(INT32 first, INT32 last)
 		}
 		else
 		{
-			lowfrac  = HWR_ClipViewSegment(max(start->last-1,start->first), (polyvertex_t *)gr_curline->v1, (polyvertex_t *)gr_curline->v2);
-			highfrac = HWR_ClipViewSegment(min((start+1)->first+1,(start+1)->last), (polyvertex_t *)gr_curline->v1, (polyvertex_t *)gr_curline->v2);
+			lowfrac  = HWR_ClipViewSegment(max(start->last-1,start->first), (polyvertex_t *)gr_curline->pv1, (polyvertex_t *)gr_curline->pv2);
+			highfrac = HWR_ClipViewSegment(min((start+1)->first+1,(start+1)->last), (polyvertex_t *)gr_curline->pv1, (polyvertex_t *)gr_curline->pv2);
 			HWR_StoreWallRange(lowfrac, highfrac);
 		}
 		start++;
@@ -2629,8 +2720,8 @@ static void HWR_ClipPassWallSegment(INT32 first, INT32 last)
 		else
 		{
 			lowfrac = HWR_ClipViewSegment(max(start->last - 1,
-				start->first), (polyvertex_t *)gr_curline->v1,
-				(polyvertex_t *)gr_curline->v2);
+				start->first), (polyvertex_t *)gr_curline->pv1,
+				(polyvertex_t *)gr_curline->pv2);
 			HWR_StoreWallRange(lowfrac, 1);
 		}
 	}
@@ -2670,6 +2761,7 @@ static void HWR_ClearClipSegs(void)
 	gr_solidsegs[1].last = 0x7fffffff;
 	hw_newend = gr_solidsegs+2;
 }
+#endif // NEWCLIP
 
 // -----------------+
 // HWR_AddLine      : Clips the given segment and adds any visible pieces to the line list.
@@ -2678,24 +2770,46 @@ static void HWR_ClearClipSegs(void)
 // -----------------+
 static void HWR_AddLine(seg_t * line)
 {
-	INT32 x1, x2;
 	angle_t angle1, angle2;
+#ifndef NEWCLIP
+	INT32 x1, x2;
 	angle_t span, tspan;
+#endif
 
 	// SoM: Backsector needs to be run through R_FakeFlat
 	static sector_t tempsec;
 
+	fixed_t v1x, v1y, v2x, v2y; // the seg's vertexes as fixed_t
+#ifdef POLYOBJECTS
 	if (line->polyseg && !(line->polyseg->flags & POF_RENDERSIDES))
 		return;
+#endif
 
 	gr_curline = line;
 
-	// OPTIMIZE: quickly reject orthogonal back sides.
-	angle1 = R_PointToAngle(FLOAT_TO_FIXED(((polyvertex_t *)gr_curline->v1)->x),
-	                        FLOAT_TO_FIXED(((polyvertex_t *)gr_curline->v1)->y));
-	angle2 = R_PointToAngle(FLOAT_TO_FIXED(((polyvertex_t *)gr_curline->v2)->x),
-	                        FLOAT_TO_FIXED(((polyvertex_t *)gr_curline->v2)->y));
+	v1x = FLOAT_TO_FIXED(((polyvertex_t *)gr_curline->pv1)->x);
+	v1y = FLOAT_TO_FIXED(((polyvertex_t *)gr_curline->pv1)->y);
+	v2x = FLOAT_TO_FIXED(((polyvertex_t *)gr_curline->pv2)->x);
+	v2y = FLOAT_TO_FIXED(((polyvertex_t *)gr_curline->pv2)->y);
 
+	// OPTIMIZE: quickly reject orthogonal back sides.
+	angle1 = R_PointToAngle(v1x, v1y);
+	angle2 = R_PointToAngle(v2x, v2y);
+
+#ifdef NEWCLIP
+	 // PrBoom: Back side, i.e. backface culling - read: endAngle >= startAngle!
+	if (angle2 - angle1 < ANGLE_180)
+		return;
+
+	// PrBoom: use REAL clipping math YAYYYYYYY!!!
+
+	if (!gld_clipper_SafeCheckRange(angle2, angle1))
+    {
+		return;
+    }
+
+	checkforemptylines = true;
+#else
 	// Clip to view edges.
 	span = angle1 - angle2;
 
@@ -2736,8 +2850,8 @@ static void HWR_AddLine(seg_t * line)
 		float fx1,fx2,fy1,fy2;
 		//BP: test with a better projection than viewangletox[R_PointToAngle(angle)]
 		// do not enable this at release 4 mul and 2 div
-		fx1 = ((polyvertex_t *)(line->v1))->x-gr_viewx;
-		fy1 = ((polyvertex_t *)(line->v1))->y-gr_viewy;
+		fx1 = ((polyvertex_t *)(line->pv1))->x-gr_viewx;
+		fy1 = ((polyvertex_t *)(line->pv1))->y-gr_viewy;
 		fy2 = (fx1 * gr_viewcos + fy1 * gr_viewsin);
 		if (fy2 < 0)
 			// the point is back
@@ -2745,8 +2859,8 @@ static void HWR_AddLine(seg_t * line)
 		else
 			fx1 = gr_windowcenterx + (fx1 * gr_viewsin - fy1 * gr_viewcos) * gr_centerx / fy2;
 
-		fx2 = ((polyvertex_t *)(line->v2))->x-gr_viewx;
-		fy2 = ((polyvertex_t *)(line->v2))->y-gr_viewy;
+		fx2 = ((polyvertex_t *)(line->pv2))->x-gr_viewx;
+		fy2 = ((polyvertex_t *)(line->pv2))->y-gr_viewy;
 		fy1 = (fx2 * gr_viewcos + fy2 * gr_viewsin);
 		if (fy1 < 0)
 			// the point is back
@@ -2774,8 +2888,34 @@ static void HWR_AddLine(seg_t * line)
 		return;
 	}
 */
+#endif
+
 	gr_backsector = line->backsector;
 
+#ifdef NEWCLIP
+	if (!line->backsector)
+    {
+		gld_clipper_SafeAddClipRange(angle2, angle1);
+    }
+    else
+    {
+		gr_backsector = R_FakeFlat(gr_backsector, &tempsec, NULL, NULL, true);
+		if (CheckClip(line, gr_frontsector, gr_backsector))
+		{
+			gld_clipper_SafeAddClipRange(angle2, angle1);
+			checkforemptylines = false;
+		}
+		// Reject empty lines used for triggers and special events.
+		// Identical floor and ceiling on both sides,
+		//  identical light levels on both sides,
+		//  and no middle texture.
+		if (checkforemptylines && R_IsEmptyLine(line, gr_frontsector, gr_backsector))
+			return;
+    }
+
+	HWR_ProcessSeg(); // Doesn't need arguments because they're defined globally :D
+	return;
+#else
 	// Single sided line?
 	if (!gr_backsector)
 		goto clipsolid;
@@ -2785,14 +2925,9 @@ static void HWR_AddLine(seg_t * line)
 #ifdef ESLOPE
 	if (gr_frontsector->f_slope || gr_frontsector->c_slope || gr_backsector->f_slope || gr_backsector->c_slope)
 	{
-		fixed_t v1x, v1y, v2x, v2y; // the seg's vertexes as fixed_t
 		fixed_t frontf1,frontf2, frontc1, frontc2; // front floor/ceiling ends
 		fixed_t backf1, backf2, backc1, backc2; // back floor ceiling ends
 
-		v1x = FLOAT_TO_FIXED(((polyvertex_t *)gr_curline->v1)->x);
-		v1y = FLOAT_TO_FIXED(((polyvertex_t *)gr_curline->v1)->y);
-		v2x = FLOAT_TO_FIXED(((polyvertex_t *)gr_curline->v2)->x);
-		v2y = FLOAT_TO_FIXED(((polyvertex_t *)gr_curline->v2)->y);
 #define SLOPEPARAMS(slope, end1, end2, normalheight) \
 		if (slope) { \
 			end1 = P_GetZAt(slope, v1x, v1y); \
@@ -2813,6 +2948,13 @@ static void HWR_AddLine(seg_t * line)
 			goto clipsolid;
 		}
 
+		// Check for automap fix.
+		if (backc1 <= backf1 && backc2 <= backf2
+		&& ((backc1 >= frontc1 && backc2 >= frontc2) || gr_curline->sidedef->toptexture)
+		&& ((backf1 <= frontf1 && backf2 >= frontf2) || gr_curline->sidedef->bottomtexture)
+		&& (gr_backsector->ceilingpic != skyflatnum || gr_frontsector->ceilingpic != skyflatnum))
+			goto clipsolid;
+
 		// Window.
 		if (backc1 != frontc1 || backc2 != frontc2
 			|| backf1 != frontf1 || backf2 != frontf2)
@@ -2828,6 +2970,13 @@ static void HWR_AddLine(seg_t * line)
 			gr_backsector->floorheight >= gr_frontsector->ceilingheight)
 			goto clipsolid;
 
+		// Check for automap fix.
+		if (gr_backsector->ceilingheight <= gr_backsector->floorheight
+		&& ((gr_backsector->ceilingheight >= gr_frontsector->ceilingheight) || gr_curline->sidedef->toptexture)
+		&& ((gr_backsector->floorheight <= gr_backsector->floorheight) || gr_curline->sidedef->bottomtexture)
+		&& (gr_backsector->ceilingpic != skyflatnum || gr_frontsector->ceilingpic != skyflatnum))
+			goto clipsolid;
+
 		// Window.
 		if (gr_backsector->ceilingheight != gr_frontsector->ceilingheight ||
 			gr_backsector->floorheight != gr_frontsector->floorheight)
@@ -2838,25 +2987,8 @@ static void HWR_AddLine(seg_t * line)
 	// Identical floor and ceiling on both sides,
 	//  identical light levels on both sides,
 	//  and no middle texture.
-	if (
-#ifdef POLYOBJECTS
-		!line->polyseg &&
-#endif
-		gr_backsector->ceilingpic == gr_frontsector->ceilingpic
-		&& gr_backsector->floorpic == gr_frontsector->floorpic
-#ifdef ESLOPE
-		&& gr_backsector->f_slope == gr_frontsector->f_slope
-		&& gr_backsector->c_slope == gr_frontsector->c_slope
-#endif
-	    && gr_backsector->lightlevel == gr_frontsector->lightlevel
-		&& gr_curline->sidedef->midtexture == 0
-		&& !gr_backsector->ffloors && !gr_frontsector->ffloors)
-		// SoM: For 3D sides... Boris, would you like to take a
-		// crack at rendering 3D sides? You would need to add the
-		// above check and add code to HWR_StoreWallRange...
-	{
+	if (R_IsEmptyLine(gr_curline, gr_frontsector, gr_backsector))
 		return;
-	}
 
 clippass:
 	if (x1 == x2)
@@ -2868,6 +3000,7 @@ clipsolid:
 	if (x1 == x2)
 		goto clippass;
 	HWR_ClipSolidWallSegment(x1, x2-1);
+#endif
 }
 
 // HWR_CheckBBox
@@ -2879,9 +3012,13 @@ clipsolid:
 
 static boolean HWR_CheckBBox(fixed_t *bspcoord)
 {
-	INT32 boxpos, sx1, sx2;
+	INT32 boxpos;
 	fixed_t px1, py1, px2, py2;
-	angle_t angle1, angle2, span, tspan;
+	angle_t angle1, angle2;
+#ifndef NEWCLIP
+	INT32 sx1, sx2;
+	angle_t span, tspan;
+#endif
 
 	// Find the corners of the box
 	// that define the edges from current viewpoint.
@@ -2907,6 +3044,11 @@ static boolean HWR_CheckBBox(fixed_t *bspcoord)
 	px2 = bspcoord[checkcoord[boxpos][2]];
 	py2 = bspcoord[checkcoord[boxpos][3]];
 
+#ifdef NEWCLIP
+	angle1 = R_PointToAngle(px1, py1);
+	angle2 = R_PointToAngle(px2, py2);
+	return gld_clipper_SafeCheckRange(angle2, angle1);
+#else
 	// check clip list for an open space
 	angle1 = R_PointToAngle2(dup_viewx>>1, dup_viewy>>1, px1>>1, py1>>1) - dup_viewangle;
 	angle2 = R_PointToAngle2(dup_viewx>>1, dup_viewy>>1, px2>>1, py2>>1) - dup_viewangle;
@@ -2954,6 +3096,7 @@ static boolean HWR_CheckBBox(fixed_t *bspcoord)
 		return false;
 
 	return HWR_ClipToSolidSegs(sx1, sx2 - 1);
+#endif
 }
 
 #ifdef POLYOBJECTS
@@ -2987,8 +3130,8 @@ static inline void HWR_AddPolyObjectSegs(void)
 			pv2->x = FIXED_TO_FLOAT(gr_fakeline->v2->x);
 			pv2->y = FIXED_TO_FLOAT(gr_fakeline->v2->y);
 
-			gr_fakeline->v1 = (vertex_t *)pv1;
-			gr_fakeline->v2 = (vertex_t *)pv2;
+			gr_fakeline->pv1 = pv1;
+			gr_fakeline->pv2 = pv2;
 
 			HWR_AddLine(gr_fakeline);
 		}
@@ -3264,7 +3407,6 @@ static void HWR_Subsector(size_t num)
 
 	if (num < numsubsectors)
 	{
-		sscount++;
 		// subsector
 		sub = &subsectors[num];
 		// sector
@@ -3415,9 +3557,7 @@ static void HWR_Subsector(size_t num)
 #ifndef POLYSKY
 	// Moved here because before, when above the ceiling and the floor does not have the sky flat, it doesn't draw the sky
 	if (gr_frontsector->ceilingpic == skyflatnum || gr_frontsector->floorpic == skyflatnum)
-	{
 		drawsky = true;
-	}
 #endif
 
 #ifdef R_FAKEFLOORS
@@ -5140,8 +5280,10 @@ static void HWR_AddSprites(sector_t *sec)
 
 			approx_dist = P_AproxDistance(viewx-thing->x, viewy-thing->y);
 
-			if (approx_dist <= limit_dist)
-				HWR_ProjectSprite(thing);
+			if (approx_dist > limit_dist)
+				continue;
+
+			HWR_ProjectSprite(thing);
 		}
 	}
 	else
@@ -5163,8 +5305,10 @@ static void HWR_AddSprites(sector_t *sec)
 
 			approx_dist = P_AproxDistance(viewx-precipthing->x, viewy-precipthing->y);
 
-			if (approx_dist <= limit_dist)
-				HWR_ProjectPrecipitationSprite(precipthing);
+			if (approx_dist > limit_dist)
+				continue;
+
+			HWR_ProjectPrecipitationSprite(precipthing);
 		}
 	}
 	else
@@ -5449,6 +5593,16 @@ static void HWR_ProjectPrecipitationSprite(precipmobj_t *thing)
 	x1 = tr_x + x1 * rightcos;
 	x2 = tr_x - x2 * rightcos;
 
+	// okay, we can't return now... this is a hack, but weather isn't networked, so it should be ok
+	if (!(thing->precipflags & PCF_THUNK))
+	{
+		if (thing->precipflags & PCF_RAIN)
+			P_RainThinker(thing);
+		else
+			P_SnowThinker(thing);
+		thing->precipflags |= PCF_THUNK;
+	}
+
 	//
 	// store information in a vissprite
 	//
@@ -5475,7 +5629,7 @@ static void HWR_ProjectPrecipitationSprite(precipmobj_t *thing)
 // ==========================================================================
 //
 // ==========================================================================
-static void HWR_DrawSkyBackground(player_t *player)
+static void HWR_DrawSkyBackground(void)
 {
 	FOutVector v[4];
 	angle_t angle;
@@ -5483,18 +5637,18 @@ static void HWR_DrawSkyBackground(player_t *player)
 	float aspectratio;
 	float angleturn;
 
-//  3--2
-//  | /|
-//  |/ |
-//  0--1
-
-	(void)player;
 	HWR_GetTexture(skytexture);
+	aspectratio = (float)vid.width/(float)vid.height;
 
 	//Hurdler: the sky is the only texture who need 4.0f instead of 1.0
 	//         because it's called just after clearing the screen
 	//         and thus, the near clipping plane is set to 3.99
 	// Sryder: Just use the near clipping plane value then
+
+	//  3--2
+	//  | /|
+	//  |/ |
+	//  0--1
 	v[0].x = v[3].x = -ZCLIP_PLANE-1;
 	v[1].x = v[2].x =  ZCLIP_PLANE+1;
 	v[0].y = v[1].y = -ZCLIP_PLANE-1;
@@ -5509,7 +5663,6 @@ static void HWR_DrawSkyBackground(player_t *player)
 	// The only time this will probably be an issue is when a sky wider than 1024 is used as a sky AND a regular wall texture
 
 	angle = (dup_viewangle + gr_xtoviewangle[0]);
-
 	dimensionmultiply = ((float)textures[skytexture]->width/256.0f);
 
 	v[0].sow = v[3].sow = ((float) angle / ((ANGLE_90-1)*dimensionmultiply));
@@ -5517,10 +5670,13 @@ static void HWR_DrawSkyBackground(player_t *player)
 
 	// Y
 	angle = aimingangle;
-
-	aspectratio = (float)vid.width/(float)vid.height;
 	dimensionmultiply = ((float)textures[skytexture]->height/(128.0f*aspectratio));
-	angleturn = (((float)ANGLE_45-1.0f)*aspectratio)*dimensionmultiply;
+
+	if (splitscreen)
+	{
+		dimensionmultiply *= 2;
+		angle *= 2;
+	}
 
 	// Middle of the sky should always be at angle 0
 	// need to keep correct aspect ratio with X
@@ -5536,6 +5692,8 @@ static void HWR_DrawSkyBackground(player_t *player)
 		v[0].tow = v[1].tow = -(0.5f-(0.5f/dimensionmultiply));
 	}
 
+	angleturn = (((float)ANGLE_45-1.0f)*aspectratio)*dimensionmultiply;
+
 	if (angle > ANGLE_180) // Do this because we don't want the sky to suddenly teleport when crossing over 0 to 360 and vice versa
 	{
 		angle = InvAngle(angle);
@@ -5699,12 +5857,8 @@ if (0)
 		HWD.pfnSetSpecialState(HWD_SET_FOG_MODE, 0); // Turn it off
 }
 
-#ifndef _NDS
 	if (drawsky)
-		HWR_DrawSkyBackground(player);
-#else
-	(void)HWR_DrawSkyBackground;
-#endif
+		HWR_DrawSkyBackground();
 
 	//Hurdler: it doesn't work in splitscreen mode
 	drawsky = splitscreen;
@@ -5714,7 +5868,19 @@ if (0)
 #ifdef SORTING
 	drawcount = 0;
 #endif
+#ifdef NEWCLIP
+	if (rendermode == render_opengl)
+	{
+		angle_t a1 = gld_FrustumAngle();
+		gld_clipper_Clear();
+		gld_clipper_SafeAddClipRange(viewangle + a1, viewangle - a1);
+#ifdef HAVE_SPHEREFRUSTRUM
+		gld_FrustrumSetup();
+#endif
+	}
+#else
 	HWR_ClearClipSegs();
+#endif
 
 	//04/01/2000: Hurdler: added for T&L
 	//                     Actually it only works on Walls and Planes
@@ -5724,6 +5890,7 @@ if (0)
 
 	HWR_RenderBSPNode((INT32)numnodes-1);
 
+#ifndef NEWCLIP
 	// Make a viewangle int so we can render things based on mouselook
 	if (player == &players[consoleplayer])
 		viewangle = localaiming;
@@ -5750,6 +5917,7 @@ if (0)
 
 		dup_viewangle += ANGLE_90;
 	}
+#endif
 
 	// Check for new console commands.
 	NetUpdate();
@@ -5906,12 +6074,8 @@ if (0)
 		HWD.pfnSetSpecialState(HWD_SET_FOG_MODE, 0); // Turn it off
 }
 
-#ifndef _NDS
 	if (!skybox && drawsky) // Don't draw the regular sky if there's a skybox
-		HWR_DrawSkyBackground(player);
-#else
-	(void)HWR_DrawSkyBackground;
-#endif
+		HWR_DrawSkyBackground();
 
 	//Hurdler: it doesn't work in splitscreen mode
 	drawsky = splitscreen;
@@ -5921,7 +6085,19 @@ if (0)
 #ifdef SORTING
 	drawcount = 0;
 #endif
+#ifdef NEWCLIP
+	if (rendermode == render_opengl)
+	{
+		angle_t a1 = gld_FrustumAngle();
+		gld_clipper_Clear();
+		gld_clipper_SafeAddClipRange(viewangle + a1, viewangle - a1);
+#ifdef HAVE_SPHEREFRUSTRUM
+		gld_FrustrumSetup();
+#endif
+	}
+#else
 	HWR_ClearClipSegs();
+#endif
 
 	//04/01/2000: Hurdler: added for T&L
 	//                     Actually it only works on Walls and Planes
@@ -5931,6 +6107,7 @@ if (0)
 
 	HWR_RenderBSPNode((INT32)numnodes-1);
 
+#ifndef NEWCLIP
 	// Make a viewangle int so we can render things based on mouselook
 	if (player == &players[consoleplayer])
 		viewangle = localaiming;
@@ -5957,6 +6134,7 @@ if (0)
 
 		dup_viewangle += ANGLE_90;
 	}
+#endif
 
 	// Check for new console commands.
 	NetUpdate();
@@ -6099,7 +6277,9 @@ static inline void HWR_AddEngineCommands(void)
 {
 	// engine state variables
 	//CV_RegisterVar(&cv_grzbuffer);
+#ifndef NEWCLIP
 	CV_RegisterVar(&cv_grclipwalls);
+#endif
 
 	// engine development mode variables
 	// - usage may vary from version to version..
diff --git a/src/hardware/hw_md2.c b/src/hardware/hw_md2.c
index 756d5a098..cb33562d8 100644
--- a/src/hardware/hw_md2.c
+++ b/src/hardware/hw_md2.c
@@ -304,8 +304,8 @@ static md2_model_t *md2_readModel(const char *filename)
 	// initialize model and read header
 
 	if (fread(&model->header, sizeof (model->header), 1, file) != 1
-		|| model->header.magic !=
-		(INT32)(('2' << 24) + ('P' << 16) + ('D' << 8) + 'I'))
+		|| model->header.magic != MD2_IDENT
+		|| model->header.version != MD2_VERSION)
 	{
 		fclose(file);
 		free(model);
@@ -319,6 +319,7 @@ static md2_model_t *md2_readModel(const char *filename)
 	{ \
 		CONS_Alert(CONS_ERROR, "md2_readModel: %s has too many " msgname " (# found: %d, maximum: %d)\n", filename, field, max); \
 		md2_freeModel (model); \
+		fclose(file); \
 		return 0; \
 	}
 
@@ -340,6 +341,7 @@ static md2_model_t *md2_readModel(const char *filename)
 			fread(model->skins, sizeof (md2_skin_t), model->header.numSkins, file))
 		{
 			md2_freeModel (model);
+			fclose(file);
 			return 0;
 		}
 	}
@@ -353,6 +355,7 @@ static md2_model_t *md2_readModel(const char *filename)
 			fread(model->texCoords, sizeof (md2_textureCoordinate_t), model->header.numTexCoords, file))
 		{
 			md2_freeModel (model);
+			fclose(file);
 			return 0;
 		}
 	}
@@ -366,6 +369,7 @@ static md2_model_t *md2_readModel(const char *filename)
 			fread(model->triangles, sizeof (md2_triangle_t), model->header.numTriangles, file))
 		{
 			md2_freeModel (model);
+			fclose(file);
 			return 0;
 		}
 	}
@@ -378,6 +382,7 @@ static md2_model_t *md2_readModel(const char *filename)
 		if (!model->frames)
 		{
 			md2_freeModel (model);
+			fclose(file);
 			return 0;
 		}
 
@@ -391,6 +396,7 @@ static md2_model_t *md2_readModel(const char *filename)
 				fread(frame, 1, model->header.frameSize, file))
 			{
 				md2_freeModel (model);
+				fclose(file);
 				return 0;
 			}
 
@@ -416,6 +422,7 @@ static md2_model_t *md2_readModel(const char *filename)
 			fread(model->glCommandBuffer, sizeof (INT32), model->header.numGlCommands, file))
 		{
 			md2_freeModel (model);
+			fclose(file);
 			return 0;
 		}
 	}
diff --git a/src/hardware/hw_md2.h b/src/hardware/hw_md2.h
index 5a7e6d2b3..299d12400 100644
--- a/src/hardware/hw_md2.h
+++ b/src/hardware/hw_md2.h
@@ -23,6 +23,11 @@
 
 #include "hw_glob.h"
 
+// magic number "IDP2" or 844121161
+#define MD2_IDENT                       (INT32)(('2' << 24) + ('P' << 16) + ('D' << 8) + 'I')
+// model version
+#define MD2_VERSION                     8
+
 #define MD2_MAX_TRIANGLES               8192
 #define MD2_MAX_VERTICES                4096
 #define MD2_MAX_TEXCOORDS               4096
diff --git a/src/hardware/hw_trick.c b/src/hardware/hw_trick.c
index e9ba19efb..97d86b944 100644
--- a/src/hardware/hw_trick.c
+++ b/src/hardware/hw_trick.c
@@ -107,17 +107,17 @@ static void releaseLineChains(void)
 
 	for (i = 0; i < numsectors; i++)
 	{
-	sector = &sectors[i];
-	nextElem = sector->sectorLines;
+		sector = &sectors[i];
+		nextElem = sector->sectorLines;
 
-	while (nextElem)
-	{
-		thisElem = nextElem;
-		nextElem = thisElem->next;
-		free(thisElem);
-	}
+		while (nextElem)
+		{
+			thisElem = nextElem;
+			nextElem = thisElem->next;
+			free(thisElem);
+		}
 
-	sector->sectorLines = NULL;
+		sector->sectorLines = NULL;
 	}
 }
 
@@ -397,7 +397,7 @@ static void sortStacklist(sector_t *sector)
 		i = 0;
 		finished = true;
 
-		while (NULL != *(list+i+1))
+		while (*(list+i+1))
 		{
 			sec1 = *(list+i);
 			sec2 = *(list+i+1);
@@ -438,7 +438,7 @@ static double calcLineoutLength(sector_t *sector)
 	double length = 0.0L;
 	chain = sector->sectorLines;
 
-	while (NULL != chain) // sum up lengths of all lines
+	while (chain) // sum up lengths of all lines
 	{
 		length += lineLength(chain->line);
 		chain = chain->next;
@@ -454,7 +454,7 @@ static void calcLineouts(sector_t *sector)
 	size_t secCount = 0;
 	sector_t *encSector = *(sector->stackList);
 
-	while (NULL != encSector)
+	while (encSector)
 	{
 		if (encSector->lineoutLength < 0.0L) // if length has not yet been calculated
 		{
@@ -552,7 +552,7 @@ static boolean areBottomtexturesMissing(sector_t *thisSector)
 		if (frontSector == backSector) // skip damn renderer tricks here
 			continue;
 
-		if (frontSector == NULL || backSector == NULL)
+		if (!frontSector || !backSector)
 			continue;
 
 		sider = &sides[thisElem->line->sidenum[0]];
@@ -587,73 +587,12 @@ static boolean areBottomtexturesMissing(sector_t *thisSector)
 static boolean isCeilingFloating(sector_t *thisSector)
 {
 	sector_t *adjSector, *refSector = NULL, *frontSector, *backSector;
-	boolean floating = true;
 	linechain_t *thisElem, *nextElem;
 
 	if (!thisSector)
 		return false;
 
-	nextElem  = thisSector->sectorLines;
-
-	while (NULL != nextElem) // walk through chain
-	{
-		thisElem = nextElem;
-		nextElem = thisElem->next;
-
-		frontSector = thisElem->line->frontsector;
-		backSector  = thisElem->line->backsector;
-
-		if (frontSector == thisSector)
-			adjSector = backSector;
-		else
-			adjSector = frontSector;
-
-		if (!adjSector) // assume floating sectors have surrounding sectors
-		{
-			floating = false;
-			break;
-		}
-
-		if (!refSector)
-		{
-			refSector = adjSector;
-			continue;
-		}
-
-		// if adjacent sector has same height or more than one adjacent sector exists -> stop
-		if (thisSector->ceilingheight == adjSector->ceilingheight ||
-		   refSector != adjSector)
-		{
-			floating = false;
-			break;
-		}
-	}
-
-	// now check for walltextures
-	if (floating)
-	{
-		if (!areToptexturesMissing(thisSector))
-		{
-			floating = false;
-		}
-	}
-	return floating;
-}
-
-//
-// check if no adjacent sector has same ceiling height
-// FIXME: throw that together with isCeilingFloating??
-//
-static boolean isFloorFloating(sector_t *thisSector)
-{
-	sector_t *adjSector, *refSector = NULL, *frontSector, *backSector;
-	boolean floating = true;
-	linechain_t *thisElem, *nextElem;
-
-	if (!thisSector)
-		return false;
-
-	nextElem  = thisSector->sectorLines;
+	nextElem = thisSector->sectorLines;
 
 	while (nextElem) // walk through chain
 	{
@@ -668,36 +607,83 @@ static boolean isFloorFloating(sector_t *thisSector)
 		else
 			adjSector = frontSector;
 
-		if (NULL == adjSector) // assume floating sectors have surrounding sectors
-		{
-			floating = false;
-			break;
-		}
+		if (!adjSector) // assume floating sectors have surrounding sectors
+			return false;
 
-		if (NULL == refSector)
+#ifdef ESLOPE
+		if (adjSector->c_slope) // Don't bother with slopes
+			return false;
+#endif
+
+		if (!refSector)
 		{
 			refSector = adjSector;
 			continue;
 		}
 
 		// if adjacent sector has same height or more than one adjacent sector exists -> stop
-		if (thisSector->floorheight == adjSector->floorheight ||
-		   refSector != adjSector)
-		{
-			floating = false;
-			break;
-		}
+		if (thisSector->ceilingheight == adjSector->ceilingheight || refSector != adjSector)
+			return false;
 	}
 
 	// now check for walltextures
-	if (floating)
+	if (!areToptexturesMissing(thisSector))
+		return false;
+
+	return true;
+}
+
+//
+// check if no adjacent sector has same ceiling height
+// FIXME: throw that together with isCeilingFloating??
+//
+static boolean isFloorFloating(sector_t *thisSector)
+{
+	sector_t *adjSector, *refSector = NULL, *frontSector, *backSector;
+	linechain_t *thisElem, *nextElem;
+
+	if (!thisSector)
+		return false;
+
+	nextElem = thisSector->sectorLines;
+
+	while (nextElem) // walk through chain
 	{
-		if (!areBottomtexturesMissing(thisSector))
+		thisElem = nextElem;
+		nextElem = thisElem->next;
+
+		frontSector = thisElem->line->frontsector;
+		backSector  = thisElem->line->backsector;
+
+		if (frontSector == thisSector)
+			adjSector = backSector;
+		else
+			adjSector = frontSector;
+
+		if (!adjSector) // assume floating sectors have surrounding sectors
+			return false;
+
+#ifdef ESLOPE
+		if (adjSector->f_slope) // Don't bother with slopes
+			return false;
+#endif
+
+		if (!refSector)
 		{
-			floating = false;
+			refSector = adjSector;
+			continue;
 		}
+
+		// if adjacent sector has same height or more than one adjacent sector exists -> stop
+		if (thisSector->floorheight == adjSector->floorheight || refSector != adjSector)
+			return false;
 	}
-	return floating;
+
+	// now check for walltextures
+	if (!areBottomtexturesMissing(thisSector))
+		return false;
+
+	return true;
 }
 
 //
@@ -707,14 +693,12 @@ static fixed_t estimateCeilHeight(sector_t *thisSector)
 {
 	sector_t *adjSector;
 
-	if (!thisSector ||
-	 !thisSector->sectorLines ||
-	  !thisSector->sectorLines->line)
+	if (!thisSector || !thisSector->sectorLines || !thisSector->sectorLines->line)
 		return 0;
 
 	adjSector = thisSector->sectorLines->line->frontsector;
 	if (adjSector == thisSector)
-	adjSector = thisSector->sectorLines->line->backsector;
+		adjSector = thisSector->sectorLines->line->backsector;
 
 	if (!adjSector)
 		return 0;
@@ -729,17 +713,15 @@ static fixed_t estimateFloorHeight(sector_t *thisSector)
 {
 	sector_t *adjSector;
 
-	if (!thisSector ||
-	 !thisSector->sectorLines ||
-	  !thisSector->sectorLines->line)
-	return 0;
+	if (!thisSector || !thisSector->sectorLines || !thisSector->sectorLines->line)
+		return 0;
 
 	adjSector = thisSector->sectorLines->line->frontsector;
 	if (adjSector == thisSector)
-	adjSector = thisSector->sectorLines->line->backsector;
+		adjSector = thisSector->sectorLines->line->backsector;
 
-	if (NULL == adjSector)
-	return 0;
+	if (!adjSector)
+		return 0;
 
 	return adjSector->floorheight;
 }
@@ -845,18 +827,12 @@ void HWR_CorrectSWTricks(void)
 		// correct height of floating sectors
 		if (isCeilingFloating(floatSector))
 		{
-			fixed_t corrheight;
-
-			corrheight = estimateCeilHeight(floatSector);
-			floatSector->virtualCeilingheight = corrheight;
+			floatSector->virtualCeilingheight = estimateCeilHeight(floatSector);
 			floatSector->virtualCeiling = true;
 		}
 		if (isFloorFloating(floatSector))
 		{
-			fixed_t corrheight;
-
-			corrheight = estimateFloorHeight(floatSector);
-			floatSector->virtualFloorheight = corrheight;
+			floatSector->virtualFloorheight = estimateFloorHeight(floatSector);
 			floatSector->virtualFloor = true;
 		}
 	}
diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c
index 8e3ae3e21..2d9f42192 100644
--- a/src/hardware/r_opengl/r_opengl.c
+++ b/src/hardware/r_opengl/r_opengl.c
@@ -1,7 +1,7 @@
 // Emacs style mode select   -*- C++ -*-
 //-----------------------------------------------------------------------------
 //
-// Copyright (C) 1998-2006 by Sonic Team Junior.
+// Copyright (C) 1998-2018 by Sonic Team Junior.
 //
 // This program is free software; you can redistribute it and/or
 // modify it under the terms of the GNU General Public License
diff --git a/src/hu_stuff.c b/src/hu_stuff.c
index 646bdcbad..b735f91b9 100644
--- a/src/hu_stuff.c
+++ b/src/hu_stuff.c
@@ -2,7 +2,7 @@
 //-----------------------------------------------------------------------------
 // Copyright (C) 1993-1996 by id Software, Inc.
 // Copyright (C) 1998-2000 by DooM Legacy Team.
-// Copyright (C) 1999-2016 by Sonic Team Junior.
+// Copyright (C) 1999-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
diff --git a/src/hu_stuff.h b/src/hu_stuff.h
index 7b22f33f1..23e421076 100644
--- a/src/hu_stuff.h
+++ b/src/hu_stuff.h
@@ -2,7 +2,7 @@
 //-----------------------------------------------------------------------------
 // Copyright (C) 1993-1996 by id Software, Inc.
 // Copyright (C) 1998-2000 by DooM Legacy Team.
-// Copyright (C) 1999-2016 by Sonic Team Junior.
+// Copyright (C) 1999-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
@@ -78,16 +78,13 @@ extern boolean chat_on;
 // set true whenever the tab rankings are being shown for any reason
 extern boolean hu_showscores;
 
-// P_DeathThink sets this true to show scores while dead, in multiplayer
-extern boolean playerdeadview;
-
 // init heads up data at game startup.
 void HU_Init(void);
 
 void HU_LoadGraphics(void);
 
 // reset heads up when consoleplayer respawns.
-FUNCMATH void HU_Start(void);
+void HU_Start(void);
 
 boolean HU_Responder(event_t *ev);
 
diff --git a/src/i_addrinfo.c b/src/i_addrinfo.c
index eb29e3608..03edf732d 100644
--- a/src/i_addrinfo.c
+++ b/src/i_addrinfo.c
@@ -1,6 +1,6 @@
 // SONIC ROBO BLAST 2
 //-----------------------------------------------------------------------------
-// Copyright (C) 2011-2016 by Sonic Team Junior.
+// Copyright (C) 2011-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
diff --git a/src/i_addrinfo.h b/src/i_addrinfo.h
index 744ea0cf7..1b8ce9153 100644
--- a/src/i_addrinfo.h
+++ b/src/i_addrinfo.h
@@ -1,6 +1,6 @@
 // SONIC ROBO BLAST 2
 //-----------------------------------------------------------------------------
-// Copyright (C) 2011-2016 by Sonic Team Junior.
+// Copyright (C) 2011-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
diff --git a/src/i_joy.h b/src/i_joy.h
index 5cba1af0a..27013f011 100644
--- a/src/i_joy.h
+++ b/src/i_joy.h
@@ -1,7 +1,7 @@
 // SONIC ROBO BLAST 2
 //-----------------------------------------------------------------------------
 // Copyright (C) 1998-2000 by DooM Legacy Team.
-// Copyright (C) 1999-2016 by Sonic Team Junior.
+// Copyright (C) 1999-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
diff --git a/src/i_net.h b/src/i_net.h
index 2bfa5eac7..0e17077bb 100644
--- a/src/i_net.h
+++ b/src/i_net.h
@@ -2,7 +2,7 @@
 //-----------------------------------------------------------------------------
 // Copyright (C) 1993-1996 by id Software, Inc.
 // Copyright (C) 1998-2000 by DooM Legacy Team.
-// Copyright (C) 1999-2016 by Sonic Team Junior.
+// Copyright (C) 1999-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
diff --git a/src/i_sound.h b/src/i_sound.h
index 084479ee1..fd73d1454 100644
--- a/src/i_sound.h
+++ b/src/i_sound.h
@@ -2,7 +2,7 @@
 //-----------------------------------------------------------------------------
 // Copyright (C) 1993-1996 by id Software, Inc.
 // Copyright (C) 1998-2000 by DooM Legacy Team.
-// Copyright (C) 1999-2016 by Sonic Team Junior.
+// Copyright (C) 1999-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
@@ -18,6 +18,21 @@
 #include "sounds.h"
 #include "command.h"
 
+// copied from SDL mixer, plus GME
+typedef enum {
+	MU_NONE,
+	MU_CMD,
+	MU_WAV,
+	MU_MOD,
+	MU_MID,
+	MU_OGG,
+	MU_MP3,
+	MU_MP3_MAD_UNUSED, // use MU_MP3 instead
+	MU_FLAC,
+	MU_MODPLUG_UNUSED, // use MU_MOD instead
+	MU_GME
+} musictype_t;
+
 /**	\brief Sound subsystem runing and waiting
 */
 extern UINT8 sound_started;
@@ -51,9 +66,9 @@ void I_StartupSound(void);
 */
 void I_ShutdownSound(void);
 
-//
-//  SFX I/O
-//
+/// ------------------------
+///  SFX I/O
+/// ------------------------
 
 /**	\brief	Starts a sound in a particular sound channel.
 	\param	id	sfxid
@@ -64,7 +79,7 @@ void I_ShutdownSound(void);
 
 	\return	sfx handle
 */
-INT32 I_StartSound(sfxenum_t id, UINT8 vol, UINT8 sep, UINT8 pitch, UINT8 priority);
+INT32 I_StartSound(sfxenum_t id, UINT8 vol, UINT8 sep, UINT8 pitch, UINT8 priority, INT32 channel);
 
 /**	\brief	Stops a sound channel.
 
@@ -105,9 +120,10 @@ void I_UpdateSoundParams(INT32 handle, UINT8 vol, UINT8 sep, UINT8 pitch);
 */
 void I_SetSfxVolume(UINT8 volume);
 
-//
-//  MUSIC I/O
-//
+/// ------------------------
+//  MUSIC SYSTEM
+/// ------------------------
+
 /** \brief Init the music systems
 */
 void I_InitMusic(void);
@@ -116,41 +132,23 @@ void I_InitMusic(void);
 */
 void I_ShutdownMusic(void);
 
-/**	\brief	PAUSE game handling.
+/// ------------------------
+//  MUSIC PROPERTIES
+/// ------------------------
 
-	\param	handle	song handle
+musictype_t I_SongType(void);
+boolean I_SongPlaying(void);
+boolean I_SongPaused(void);
 
-	\return	void
-*/
-void I_PauseSong(INT32 handle);
+/// ------------------------
+//  MUSIC EFFECTS
+/// ------------------------
 
-/**	\brief	RESUME game handling
+boolean I_SetSongSpeed(float speed);
 
-	\param	handle	song handle
-
-	\return	void
-*/
-void I_ResumeSong(INT32 handle);
-
-//
-//  MIDI I/O
-//
-
-/**	\brief Startup the MIDI music system
-*/
-void I_InitMIDIMusic(void);
-
-/**	\brief Shutdown the MIDI music system
-*/
-void I_ShutdownMIDIMusic(void);
-
-/**	\brief	The I_SetMIDIMusicVolume function
-
-	\param	volume	volume to set at
-
-	\return	void
-*/
-void I_SetMIDIMusicVolume(UINT8 volume);
+/// ------------------------
+//  MUSIC PLAYBACK
+/// ------------------------
 
 /**	\brief	Registers a song handle to song data.
 
@@ -161,7 +159,16 @@ void I_SetMIDIMusicVolume(UINT8 volume);
 
 	\todo Remove this
 */
-INT32 I_RegisterSong(void *data, size_t len);
+boolean I_LoadSong(char *data, size_t len);
+
+/**	\brief	See ::I_LoadSong, then think backwards
+
+	\param	handle	song handle
+
+	\sa I_LoadSong
+	\todo remove midi handle
+*/
+void I_UnloadSong(void);
 
 /**	\brief	Called by anything that wishes to start music
 
@@ -172,7 +179,7 @@ INT32 I_RegisterSong(void *data, size_t len);
 
 	\todo pass music name, not handle
 */
-boolean I_PlaySong(INT32 handle, boolean looping);
+boolean I_PlaySong(boolean looping);
 
 /**	\brief	Stops a song over 3 seconds
 
@@ -181,58 +188,37 @@ boolean I_PlaySong(INT32 handle, boolean looping);
 
 	/todo drop handle
 */
-void I_StopSong(INT32 handle);
+void I_StopSong(void);
 
-/**	\brief	See ::I_RegisterSong, then think backwards
+/**	\brief	PAUSE game handling.
 
 	\param	handle	song handle
 
-	\sa I_RegisterSong
-	\todo remove midi handle
+	\return	void
 */
-void I_UnRegisterSong(INT32 handle);
+void I_PauseSong(void);
 
-//
-//  DIGMUSIC I/O
-//
+/**	\brief	RESUME game handling
 
-/**	\brief Startup the music system
+	\param	handle	song handle
+
+	\return	void
 */
-void I_InitDigMusic(void);
+void I_ResumeSong(void);
 
-/**	\brief Shutdown the music system
-*/
-void I_ShutdownDigMusic(void);
-
-boolean I_SetSongSpeed(float speed);
-
-boolean I_SetSongTrack(INT32 track);
-
-/**	\brief The I_StartDigSong function
-
-	\param	musicname	music lump name
-	\param	looping	if true, loop the song
-
-	\return	if true, song playing
-*/
-boolean I_StartDigSong(const char *musicname, boolean looping);
-
-/**	\brief stop non-MIDI song
-*/
-void I_StopDigSong(void);
-
-/**	\brief The I_SetDigMusicVolume function
+/**	\brief	The I_SetMusicVolume function
 
 	\param	volume	volume to set at
 
 	\return	void
 */
-void I_SetDigMusicVolume(UINT8 volume);
+void I_SetMusicVolume(UINT8 volume);
 
-//
-// CD MUSIC I/O
-//
+boolean I_SetSongTrack(INT32 track);
 
+/// ------------------------
+//  CD MUSIC I/O
+/// ------------------------
 
 /**	\brief  cd music interface
 */
diff --git a/src/i_system.h b/src/i_system.h
index d61f2d16e..a8d707d16 100644
--- a/src/i_system.h
+++ b/src/i_system.h
@@ -2,7 +2,7 @@
 //-----------------------------------------------------------------------------
 // Copyright (C) 1993-1996 by id Software, Inc.
 // Copyright (C) 1998-2000 by DooM Legacy Team.
-// Copyright (C) 1999-2016 by Sonic Team Junior.
+// Copyright (C) 1999-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
diff --git a/src/i_tcp.c b/src/i_tcp.c
index 6488e9845..279081e72 100644
--- a/src/i_tcp.c
+++ b/src/i_tcp.c
@@ -1,7 +1,7 @@
 // SONIC ROBO BLAST 2
 //-----------------------------------------------------------------------------
 // Copyright (C) 1998-2000 by DooM Legacy Team.
-// Copyright (C) 1999-2016 by Sonic Team Junior.
+// Copyright (C) 1999-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
@@ -262,6 +262,33 @@ static void wattcp_outch(char s)
 }
 #endif
 
+#ifdef USE_WINSOCK
+// stupid microsoft makes things complicated
+static char *get_WSAErrorStr(int e)
+{
+	static char buf[256]; // allow up to 255 bytes
+
+	buf[0] = '\0';
+
+	FormatMessageA(
+		FORMAT_MESSAGE_FROM_SYSTEM |
+		FORMAT_MESSAGE_IGNORE_INSERTS,
+		NULL,
+		(DWORD)e,
+		MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+		(LPTSTR)buf,
+		sizeof (buf),
+		NULL);
+
+	if (!buf[0]) // provide a fallback error message if no message is available for some reason
+		sprintf(buf, "Unknown error");
+
+	return buf;
+}
+#undef strerror
+#define strerror get_WSAErrorStr
+#endif
+
 #ifdef USE_WINSOCK2
 #define inet_ntop inet_ntopA
 #define HAVE_NTOP
@@ -759,9 +786,13 @@ static void SOCK_Send(void)
 			&clientaddress[doomcom->remotenode].any, d);
 	}
 
-	if (c == ERRSOCKET && errno != ECONNREFUSED && errno != EWOULDBLOCK)
-		I_Error("SOCK_Send, error sending to node %d (%s) #%u: %s", doomcom->remotenode,
-			SOCK_GetNodeAddress(doomcom->remotenode), errno, strerror(errno));
+	if (c == ERRSOCKET)
+	{
+		int e = errno; // save error code so it can't be modified later
+		if (e != ECONNREFUSED && e != EWOULDBLOCK)
+			I_Error("SOCK_Send, error sending to node %d (%s) #%u: %s", doomcom->remotenode,
+				SOCK_GetNodeAddress(doomcom->remotenode), e, strerror(e));
+	}
 }
 #endif
 
diff --git a/src/i_tcp.h b/src/i_tcp.h
index a084abb84..06680cd9b 100644
--- a/src/i_tcp.h
+++ b/src/i_tcp.h
@@ -1,7 +1,7 @@
 // SONIC ROBO BLAST 2
 //-----------------------------------------------------------------------------
 // Copyright (C) 1998-2000 by DooM Legacy Team.
-// Copyright (C) 1999-2016 by Sonic Team Junior.
+// Copyright (C) 1999-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
diff --git a/src/i_video.h b/src/i_video.h
index 7ee07f000..4bb2c5829 100644
--- a/src/i_video.h
+++ b/src/i_video.h
@@ -2,7 +2,7 @@
 //-----------------------------------------------------------------------------
 // Copyright (C) 1993-1996 by id Software, Inc.
 // Copyright (C) 1998-2000 by DooM Legacy Team.
-// Copyright (C) 1999-2016 by Sonic Team Junior.
+// Copyright (C) 1999-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
diff --git a/src/info.c b/src/info.c
index c621378e3..84e9cbdc4 100644
--- a/src/info.c
+++ b/src/info.c
@@ -2,7 +2,7 @@
 //-----------------------------------------------------------------------------
 // Copyright (C) 1993-1996 by id Software, Inc.
 // Copyright (C) 1998-2000 by DooM Legacy Team.
-// Copyright (C) 1999-2016 by Sonic Team Junior.
+// Copyright (C) 1999-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
diff --git a/src/info.h b/src/info.h
index 6b943cd93..cba49667d 100644
--- a/src/info.h
+++ b/src/info.h
@@ -2,7 +2,7 @@
 //-----------------------------------------------------------------------------
 // Copyright (C) 1993-1996 by id Software, Inc.
 // Copyright (C) 1998-2000 by DooM Legacy Team.
-// Copyright (C) 1999-2016 by Sonic Team Junior.
+// Copyright (C) 1999-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
diff --git a/src/keys.h b/src/keys.h
index 654aa1d9d..cf3a0d060 100644
--- a/src/keys.h
+++ b/src/keys.h
@@ -1,7 +1,7 @@
 // SONIC ROBO BLAST 2
 //-----------------------------------------------------------------------------
 // Copyright (C) 1998-2000 by DooM Legacy Team.
-// Copyright (C) 1999-2016 by Sonic Team Junior.
+// Copyright (C) 1999-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
diff --git a/src/lua_baselib.c b/src/lua_baselib.c
index e8e8fd020..c07d104c2 100644
--- a/src/lua_baselib.c
+++ b/src/lua_baselib.c
@@ -1,7 +1,7 @@
 // SONIC ROBO BLAST 2
 //-----------------------------------------------------------------------------
 // Copyright (C) 2012-2016 by John "JTE" Muniz.
-// Copyright (C) 2012-2016 by Sonic Team Junior.
+// Copyright (C) 2012-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
diff --git a/src/lua_consolelib.c b/src/lua_consolelib.c
index 3239b7c5e..3f1fea5b1 100644
--- a/src/lua_consolelib.c
+++ b/src/lua_consolelib.c
@@ -1,7 +1,7 @@
 // SONIC ROBO BLAST 2
 //-----------------------------------------------------------------------------
 // Copyright (C) 2012-2016 by John "JTE" Muniz.
-// Copyright (C) 2012-2016 by Sonic Team Junior.
+// Copyright (C) 2012-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
diff --git a/src/lua_hook.h b/src/lua_hook.h
index 53e0a7d8e..db32c42ba 100644
--- a/src/lua_hook.h
+++ b/src/lua_hook.h
@@ -1,7 +1,7 @@
 // SONIC ROBO BLAST 2
 //-----------------------------------------------------------------------------
 // Copyright (C) 2012-2016 by John "JTE" Muniz.
-// Copyright (C) 2012-2016 by Sonic Team Junior.
+// Copyright (C) 2012-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
diff --git a/src/lua_hooklib.c b/src/lua_hooklib.c
index eadd01537..2a98a82e5 100644
--- a/src/lua_hooklib.c
+++ b/src/lua_hooklib.c
@@ -1,7 +1,7 @@
 // SONIC ROBO BLAST 2
 //-----------------------------------------------------------------------------
 // Copyright (C) 2012-2016 by John "JTE" Muniz.
-// Copyright (C) 2012-2016 by Sonic Team Junior.
+// Copyright (C) 2012-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
diff --git a/src/lua_hud.h b/src/lua_hud.h
index ba0a1d894..f96618e07 100644
--- a/src/lua_hud.h
+++ b/src/lua_hud.h
@@ -1,7 +1,7 @@
 // SONIC ROBO BLAST 2
 //-----------------------------------------------------------------------------
 // Copyright (C) 2014-2016 by John "JTE" Muniz.
-// Copyright (C) 2014-2016 by Sonic Team Junior.
+// Copyright (C) 2014-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
diff --git a/src/lua_hudlib.c b/src/lua_hudlib.c
index 60cbbe501..ee470d50c 100644
--- a/src/lua_hudlib.c
+++ b/src/lua_hudlib.c
@@ -1,7 +1,7 @@
 // SONIC ROBO BLAST 2
 //-----------------------------------------------------------------------------
 // Copyright (C) 2014-2016 by John "JTE" Muniz.
-// Copyright (C) 2014-2016 by Sonic Team Junior.
+// Copyright (C) 2014-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
diff --git a/src/lua_infolib.c b/src/lua_infolib.c
index f6bb7d305..9b22170f9 100644
--- a/src/lua_infolib.c
+++ b/src/lua_infolib.c
@@ -1,7 +1,7 @@
 // SONIC ROBO BLAST 2
 //-----------------------------------------------------------------------------
 // Copyright (C) 2012-2016 by John "JTE" Muniz.
-// Copyright (C) 2012-2016 by Sonic Team Junior.
+// Copyright (C) 2012-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
diff --git a/src/lua_libs.h b/src/lua_libs.h
index 931cf62d0..fe3d82200 100644
--- a/src/lua_libs.h
+++ b/src/lua_libs.h
@@ -1,7 +1,7 @@
 // SONIC ROBO BLAST 2
 //-----------------------------------------------------------------------------
 // Copyright (C) 2012-2016 by John "JTE" Muniz.
-// Copyright (C) 2012-2016 by Sonic Team Junior.
+// Copyright (C) 2012-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
diff --git a/src/lua_maplib.c b/src/lua_maplib.c
index 208aebe37..5c1763862 100644
--- a/src/lua_maplib.c
+++ b/src/lua_maplib.c
@@ -1,7 +1,7 @@
 // SONIC ROBO BLAST 2
 //-----------------------------------------------------------------------------
 // Copyright (C) 2012-2016 by John "JTE" Muniz.
-// Copyright (C) 2012-2016 by Sonic Team Junior.
+// Copyright (C) 2012-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
diff --git a/src/lua_mathlib.c b/src/lua_mathlib.c
index 96d50b779..6cc8c0077 100644
--- a/src/lua_mathlib.c
+++ b/src/lua_mathlib.c
@@ -1,7 +1,7 @@
 // SONIC ROBO BLAST 2
 //-----------------------------------------------------------------------------
 // Copyright (C) 2012-2016 by John "JTE" Muniz.
-// Copyright (C) 2012-2016 by Sonic Team Junior.
+// Copyright (C) 2012-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
diff --git a/src/lua_mobjlib.c b/src/lua_mobjlib.c
index 6bb1388fc..4cd952f8d 100644
--- a/src/lua_mobjlib.c
+++ b/src/lua_mobjlib.c
@@ -1,7 +1,7 @@
 // SONIC ROBO BLAST 2
 //-----------------------------------------------------------------------------
 // Copyright (C) 2012-2016 by John "JTE" Muniz.
-// Copyright (C) 2012-2016 by Sonic Team Junior.
+// Copyright (C) 2012-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
diff --git a/src/lua_playerlib.c b/src/lua_playerlib.c
index bd5605f23..dd7439321 100644
--- a/src/lua_playerlib.c
+++ b/src/lua_playerlib.c
@@ -1,7 +1,7 @@
 // SONIC ROBO BLAST 2
 //-----------------------------------------------------------------------------
 // Copyright (C) 2012-2016 by John "JTE" Muniz.
-// Copyright (C) 2012-2016 by Sonic Team Junior.
+// Copyright (C) 2012-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
diff --git a/src/lua_script.c b/src/lua_script.c
index ce96878bf..0ee65c83b 100644
--- a/src/lua_script.c
+++ b/src/lua_script.c
@@ -1,7 +1,7 @@
 // SONIC ROBO BLAST 2
 //-----------------------------------------------------------------------------
 // Copyright (C) 2012-2016 by John "JTE" Muniz.
-// Copyright (C) 2012-2016 by Sonic Team Junior.
+// Copyright (C) 2012-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
@@ -182,19 +182,21 @@ void LUA_LoadLump(UINT16 wad, UINT16 lump)
 {
 	MYFILE f;
 	char *name;
+	size_t len;
 	f.wad = wad;
 	f.size = W_LumpLengthPwad(wad, lump);
 	f.data = Z_Malloc(f.size, PU_LUA, NULL);
 	W_ReadLumpPwad(wad, lump, f.data);
 	f.curpos = f.data;
 
-	name = malloc(strlen(wadfiles[wad]->filename)+10);
+	len = strlen(wadfiles[wad]->filename);
+	name = malloc(len+10);
 	strcpy(name, wadfiles[wad]->filename);
-	if (!fasticmp(&name[strlen(name) - 4], ".lua")) {
+	if (!fasticmp(&name[len - 4], ".lua")) {
 		// If it's not a .lua file, copy the lump name in too.
-		name[strlen(wadfiles[wad]->filename)] = '|';
-		M_Memcpy(name+strlen(wadfiles[wad]->filename)+1, wadfiles[wad]->lumpinfo[lump].name, 8);
-		name[strlen(wadfiles[wad]->filename)+9] = '\0';
+		name[len] = '|';
+		M_Memcpy(name+len+1, wadfiles[wad]->lumpinfo[lump].name, 8);
+		name[len+9] = '\0';
 	}
 
 	LUA_LoadFile(&f, name);
@@ -851,7 +853,7 @@ static UINT8 UnArchiveValue(int TABLESINDEX)
 		LUA_PushUserdata(gL, &sectors[READUINT16(save_p)], META_SECTOR);
 		break;
 	case ARCH_MAPHEADER:
-		LUA_PushUserdata(gL, &sectors[READUINT16(save_p)], META_MAPHEADER);
+		LUA_PushUserdata(gL, mapheaderinfo[READUINT16(save_p)], META_MAPHEADER);
 		break;
 	case ARCH_TEND:
 		return 1;
diff --git a/src/lua_script.h b/src/lua_script.h
index 3b159234a..f944149d7 100644
--- a/src/lua_script.h
+++ b/src/lua_script.h
@@ -1,7 +1,7 @@
 // SONIC ROBO BLAST 2
 //-----------------------------------------------------------------------------
 // Copyright (C) 2012-2016 by John "JTE" Muniz.
-// Copyright (C) 2012-2016 by Sonic Team Junior.
+// Copyright (C) 2012-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
diff --git a/src/lua_skinlib.c b/src/lua_skinlib.c
index 28d5fed23..0fbcb2fd3 100644
--- a/src/lua_skinlib.c
+++ b/src/lua_skinlib.c
@@ -1,7 +1,7 @@
 // SONIC ROBO BLAST 2
 //-----------------------------------------------------------------------------
 // Copyright (C) 2014-2016 by John "JTE" Muniz.
-// Copyright (C) 2014-2016 by Sonic Team Junior.
+// Copyright (C) 2014-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
diff --git a/src/lua_thinkerlib.c b/src/lua_thinkerlib.c
index aaa8435e9..ae859d46e 100644
--- a/src/lua_thinkerlib.c
+++ b/src/lua_thinkerlib.c
@@ -1,7 +1,7 @@
 // SONIC ROBO BLAST 2
 //-----------------------------------------------------------------------------
 // Copyright (C) 2012-2016 by John "JTE" Muniz.
-// Copyright (C) 2012-2016 by Sonic Team Junior.
+// Copyright (C) 2012-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
diff --git a/src/m_aatree.c b/src/m_aatree.c
index 6cb3a32cb..f19fa1dc0 100644
--- a/src/m_aatree.c
+++ b/src/m_aatree.c
@@ -2,7 +2,7 @@
 //-----------------------------------------------------------------------------
 // Copyright (C) 1993-1996 by id Software, Inc.
 // Copyright (C) 1998-2000 by DooM Legacy Team.
-// Copyright (C) 1999-2016 by Sonic Team Junior.
+// Copyright (C) 1999-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
diff --git a/src/m_aatree.h b/src/m_aatree.h
index eeaebca3b..e7f1eba05 100644
--- a/src/m_aatree.h
+++ b/src/m_aatree.h
@@ -2,7 +2,7 @@
 //-----------------------------------------------------------------------------
 // Copyright (C) 1993-1996 by id Software, Inc.
 // Copyright (C) 1998-2000 by DooM Legacy Team.
-// Copyright (C) 1999-2016 by Sonic Team Junior.
+// Copyright (C) 1999-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
diff --git a/src/m_anigif.c b/src/m_anigif.c
index 2540665ad..845099211 100644
--- a/src/m_anigif.c
+++ b/src/m_anigif.c
@@ -2,7 +2,7 @@
 //-----------------------------------------------------------------------------
 // Copyright (C) 2013-2016 by Matthew "Inuyasha" Walsh.
 // Copyright (C) 2013      by "Ninji".
-// Copyright (C) 2013-2016 by Sonic Team Junior.
+// Copyright (C) 2013-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
@@ -492,7 +492,9 @@ static void GIF_framewrite(void)
 
 	// screen regions are handled in GIF_lzw
 	{
-		UINT16 delay = 3; // todo
+		int d1 = (int)((100.0/NEWTICRATE)*(gif_frames+1));
+		int d2 = (int)((100.0/NEWTICRATE)*(gif_frames));
+		UINT16 delay = d1-d2;
 		INT32 startline;
 
 		WRITEMEM(p, gifframe_gchead, 4);
diff --git a/src/m_anigif.h b/src/m_anigif.h
index dbf7b10a2..6d94ecf8c 100644
--- a/src/m_anigif.h
+++ b/src/m_anigif.h
@@ -1,7 +1,7 @@
 // SONIC ROBO BLAST 2
 //-----------------------------------------------------------------------------
 // Copyright (C) 2013-2016 by Matthew "Inuyasha" Walsh.
-// Copyright (C) 2013-2016 by Sonic Team Junior.
+// Copyright (C) 2013-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
diff --git a/src/m_argv.c b/src/m_argv.c
index 859fc9026..5c5dc37cf 100644
--- a/src/m_argv.c
+++ b/src/m_argv.c
@@ -2,7 +2,7 @@
 //-----------------------------------------------------------------------------
 // Copyright (C) 1993-1996 by id Software, Inc.
 // Copyright (C) 1998-2000 by DooM Legacy Team.
-// Copyright (C) 1999-2016 by Sonic Team Junior.
+// Copyright (C) 1999-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
@@ -25,6 +25,10 @@ INT32 myargc;
 */
 char **myargv;
 
+/** \brief did we alloc myargv ourselves?
+*/
+boolean myargmalloc = false;
+
 /**	\brief founded the parm
 */
 static INT32 found;
@@ -176,6 +180,7 @@ void M_FindResponseFile(void)
 				free(file);
 				I_Error("Not enough memory to read response file");
 			}
+			myargmalloc = true; // mark as having been allocated by us
 			memset(myargv, 0, sizeof (char *) * MAXARGVS);
 			myargv[0] = firstargv;
 
@@ -198,17 +203,15 @@ void M_FindResponseFile(void)
 					k++;
 			} while (k < size);
 
-			free(file);
-
 			for (k = 0; k < pindex; k++)
 				myargv[indexinfile++] = moreargs[k];
 			myargc = indexinfile;
 
 			// display arguments
-			CONS_Printf(M_GetText("%d command-line args:\n"), myargc);
+			CONS_Printf(M_GetText("%d command-line args:\n"), myargc-1); // -1 so @ don't actually get counted for
 			for (k = 1; k < myargc; k++)
 				CONS_Printf("%s\n", myargv[k]);
 
 			break;
 		}
-}
+}
\ No newline at end of file
diff --git a/src/m_argv.h b/src/m_argv.h
index 46ef9a2cf..d654dcc19 100644
--- a/src/m_argv.h
+++ b/src/m_argv.h
@@ -2,7 +2,7 @@
 //-----------------------------------------------------------------------------
 // Copyright (C) 1993-1996 by id Software, Inc.
 // Copyright (C) 1998-2000 by DooM Legacy Team.
-// Copyright (C) 1999-2016 by Sonic Team Junior.
+// Copyright (C) 1999-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
@@ -19,6 +19,7 @@
 //
 extern INT32 myargc;
 extern char **myargv;
+extern boolean myargmalloc;
 
 // Returns the position of the given parameter in the arg list (0 if not found).
 INT32 M_CheckParm(const char *check);
diff --git a/src/m_bbox.c b/src/m_bbox.c
index fb44b853e..0c57de43e 100644
--- a/src/m_bbox.c
+++ b/src/m_bbox.c
@@ -2,7 +2,7 @@
 //-----------------------------------------------------------------------------
 // Copyright (C) 1993-1996 by id Software, Inc.
 // Copyright (C) 1998-2000 by DooM Legacy Team.
-// Copyright (C) 1999-2016 by Sonic Team Junior.
+// Copyright (C) 1999-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
diff --git a/src/m_bbox.h b/src/m_bbox.h
index a11257b8a..db5c2b4a7 100644
--- a/src/m_bbox.h
+++ b/src/m_bbox.h
@@ -2,7 +2,7 @@
 //-----------------------------------------------------------------------------
 // Copyright (C) 1993-1996 by id Software, Inc.
 // Copyright (C) 1998-2000 by DooM Legacy Team.
-// Copyright (C) 1999-2016 by Sonic Team Junior.
+// Copyright (C) 1999-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
diff --git a/src/m_cheat.c b/src/m_cheat.c
index 3bbaadc5b..6fa3ea113 100644
--- a/src/m_cheat.c
+++ b/src/m_cheat.c
@@ -2,7 +2,7 @@
 //-----------------------------------------------------------------------------
 // Copyright (C) 1993-1996 by id Software, Inc.
 // Copyright (C) 1998-2000 by DooM Legacy Team.
-// Copyright (C) 1999-2016 by Sonic Team Junior.
+// Copyright (C) 1999-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
diff --git a/src/m_cheat.h b/src/m_cheat.h
index 951c7a16a..bb901af74 100644
--- a/src/m_cheat.h
+++ b/src/m_cheat.h
@@ -2,7 +2,7 @@
 //-----------------------------------------------------------------------------
 // Copyright (C) 1993-1996 by id Software, Inc.
 // Copyright (C) 1998-2000 by DooM Legacy Team.
-// Copyright (C) 1999-2016 by Sonic Team Junior.
+// Copyright (C) 1999-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
diff --git a/src/m_cond.c b/src/m_cond.c
index a56efd3ae..4c824b180 100644
--- a/src/m_cond.c
+++ b/src/m_cond.c
@@ -1,7 +1,7 @@
 // SONIC ROBO BLAST 2
 //-----------------------------------------------------------------------------
 // Copyright (C) 2012-2016 by Matthew "Inuyasha" Walsh.
-// Copyright (C) 2012-2016 by Sonic Team Junior.
+// Copyright (C) 2012-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
diff --git a/src/m_cond.h b/src/m_cond.h
index e61ff1f79..351704064 100644
--- a/src/m_cond.h
+++ b/src/m_cond.h
@@ -1,7 +1,7 @@
 // SONIC ROBO BLAST 2
 //-----------------------------------------------------------------------------
 // Copyright (C) 2012-2016 by Matthew "Inuyasha" Walsh.
-// Copyright (C) 2012-2016 by Sonic Team Junior.
+// Copyright (C) 2012-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
diff --git a/src/m_dllist.h b/src/m_dllist.h
index f19659cca..18f351144 100644
--- a/src/m_dllist.h
+++ b/src/m_dllist.h
@@ -1,7 +1,7 @@
 // SONIC ROBO BLAST 2
 //-----------------------------------------------------------------------------
 // Copyright (C) 2005      by James Haley
-// Copyright (C) 2005-2016 by Sonic Team Junior.
+// Copyright (C) 2005-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
diff --git a/src/m_fixed.c b/src/m_fixed.c
index 014457386..d45bb70bf 100644
--- a/src/m_fixed.c
+++ b/src/m_fixed.c
@@ -2,7 +2,7 @@
 //-----------------------------------------------------------------------------
 // Copyright (C) 1993-1996 by id Software, Inc.
 // Copyright (C) 1998-2000 by DooM Legacy Team.
-// Copyright (C) 1999-2016 by Sonic Team Junior.
+// Copyright (C) 1999-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
@@ -432,7 +432,7 @@ vector3_t *FV3_Cross(const vector3_t *a_1, const vector3_t *a_2, vector3_t *a_o)
 //
 vector3_t *FV3_ClosestPointOnLine(const vector3_t *Line, const vector3_t *p, vector3_t *out)
 {
-	// Determine t (the length of the vector from �Line[0]� to �p�)
+	// Determine t (the length of the vector from �Line[0]� to �p�)
 	vector3_t c, V;
 	fixed_t t, d = 0;
 	FV3_SubEx(p, &Line[0], &c);
@@ -442,7 +442,7 @@ vector3_t *FV3_ClosestPointOnLine(const vector3_t *Line, const vector3_t *p, vec
 	d = FV3_Distance(&Line[0], &Line[1]);
 	t = FV3_Dot(&V, &c);
 
-	// Check to see if �t� is beyond the extents of the line segment
+	// Check to see if �t� is beyond the extents of the line segment
 	if (t < 0)
 	{
 		return FV3_Copy(out, &Line[0]);
@@ -452,7 +452,7 @@ vector3_t *FV3_ClosestPointOnLine(const vector3_t *Line, const vector3_t *p, vec
 		return FV3_Copy(out, &Line[1]);
 	}
 
-	// Return the point between �Line[0]� and �Line[1]�
+	// Return the point between �Line[0]� and �Line[1]�
 	FV3_Mul(&V, t);
 
 	return FV3_AddEx(&Line[0], &V, out);
diff --git a/src/m_fixed.h b/src/m_fixed.h
index 773823988..4609913b7 100644
--- a/src/m_fixed.h
+++ b/src/m_fixed.h
@@ -2,7 +2,7 @@
 //-----------------------------------------------------------------------------
 // Copyright (C) 1993-1996 by id Software, Inc.
 // Copyright (C) 1998-2000 by DooM Legacy Team.
-// Copyright (C) 1999-2016 by Sonic Team Junior.
+// Copyright (C) 1999-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
@@ -75,7 +75,7 @@ typedef INT32 fixed_t;
 			:"=a" (ret)            // eax is always the result and the first operand (%0,%1)
 			:"0" (a), "r" (b)      // and %2 is what we use imull on with what in %1
 			, "I" (FRACBITS)       // %3 holds FRACBITS (normally 16)
-			:"%cc", "%edx"         // edx and condition codes clobbered
+			:"cc", "%edx"         // edx and condition codes clobbered
 		);
 		return ret;
 	}
diff --git a/src/m_menu.c b/src/m_menu.c
index 79ac6800b..dfe8bbeca 100644
--- a/src/m_menu.c
+++ b/src/m_menu.c
@@ -3,7 +3,7 @@
 // Copyright (C) 1993-1996 by id Software, Inc.
 // Copyright (C) 1998-2000 by DooM Legacy Team.
 // Copyright (C) 2011-2016 by Matthew "Inuyasha" Walsh.
-// Copyright (C) 1999-2016 by Sonic Team Junior.
+// Copyright (C) 1999-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
@@ -287,9 +287,6 @@ menu_t OP_VideoOptionsDef, OP_VideoModeDef;
 menu_t OP_OpenGLOptionsDef, OP_OpenGLFogDef, OP_OpenGLColorDef;
 #endif
 menu_t OP_SoundOptionsDef;
-static void M_ToggleSFX(void);
-static void M_ToggleDigital(void);
-static void M_ToggleMIDI(void);
 
 //Misc
 menu_t OP_DataOptionsDef, OP_ScreenshotOptionsDef, OP_EraseDataDef;
@@ -1227,9 +1224,9 @@ static menuitem_t OP_SoundOptionsMenu[] =
                               NULL, "CD Volume"    , &cd_volume,          40},
 #endif
 
-	{IT_STRING    | IT_CALL,  NULL,  "Toggle SFX"   , M_ToggleSFX,        50},
-	{IT_STRING    | IT_CALL,  NULL,  "Toggle Digital Music", M_ToggleDigital,     60},
-	{IT_STRING    | IT_CALL,  NULL,  "Toggle MIDI Music", M_ToggleMIDI,        70},
+	{IT_STRING | IT_CVAR,  NULL,  "SFX"   , &cv_gamesounds,        50},
+	{IT_STRING | IT_CVAR,  NULL,  "Digital Music", &cv_gamedigimusic,     60},
+	{IT_STRING | IT_CVAR,  NULL,  "MIDI Music", &cv_gamemidimusic,        70},
 };
 
 static menuitem_t OP_DataOptionsMenu[] =
@@ -6048,7 +6045,7 @@ void M_SortServerList(void)
 
 #ifndef NONET
 #ifdef UPDATE_ALERT
-static int M_CheckMODVersion(void)
+static boolean M_CheckMODVersion(void)
 {
 	char updatestring[500];
 	const char *updatecheck = GetMODVersion();
@@ -6943,92 +6940,6 @@ static void M_ChangeControl(INT32 choice)
 	M_StartMessage(tmp, M_ChangecontrolResponse, MM_EVENTHANDLER);
 }
 
-// =====
-// SOUND
-// =====
-
-// Toggles sound systems in-game.
-static void M_ToggleSFX(void)
-{
-	if (nosound)
-	{
-		nosound = false;
-		I_StartupSound();
-		if (nosound) return;
-		S_Init(cv_soundvolume.value, cv_digmusicvolume.value, cv_midimusicvolume.value);
-		M_StartMessage(M_GetText("SFX Enabled\n"), NULL, MM_NOTHING);
-	}
-	else
-	{
-		if (sound_disabled)
-		{
-			sound_disabled = false;
-			M_StartMessage(M_GetText("SFX Enabled\n"), NULL, MM_NOTHING);
-		}
-		else
-		{
-			sound_disabled = true;
-			S_StopSounds();
-			M_StartMessage(M_GetText("SFX Disabled\n"), NULL, MM_NOTHING);
-		}
-	}
-}
-
-static void M_ToggleDigital(void)
-{
-	if (nodigimusic)
-	{
-		nodigimusic = false;
-		I_InitDigMusic();
-		if (nodigimusic) return;
-		S_Init(cv_soundvolume.value, cv_digmusicvolume.value, cv_midimusicvolume.value);
-		S_StopMusic();
-		S_ChangeMusicInternal("lclear", false);
-		M_StartMessage(M_GetText("Digital Music Enabled\n"), NULL, MM_NOTHING);
-	}
-	else
-	{
-		if (digital_disabled)
-		{
-			digital_disabled = false;
-			M_StartMessage(M_GetText("Digital Music Enabled\n"), NULL, MM_NOTHING);
-		}
-		else
-		{
-			digital_disabled = true;
-			S_StopMusic();
-			M_StartMessage(M_GetText("Digital Music Disabled\n"), NULL, MM_NOTHING);
-		}
-	}
-}
-
-static void M_ToggleMIDI(void)
-{
-	if (nomidimusic)
-	{
-		nomidimusic = false;
-		I_InitMIDIMusic();
-		if (nomidimusic) return;
-		S_Init(cv_soundvolume.value, cv_digmusicvolume.value, cv_midimusicvolume.value);
-		S_ChangeMusicInternal("lclear", false);
-		M_StartMessage(M_GetText("MIDI Music Enabled\n"), NULL, MM_NOTHING);
-	}
-	else
-	{
-		if (music_disabled)
-		{
-			music_disabled = false;
-			M_StartMessage(M_GetText("MIDI Music Enabled\n"), NULL, MM_NOTHING);
-		}
-		else
-		{
-			music_disabled = true;
-			S_StopMusic();
-			M_StartMessage(M_GetText("MIDI Music Disabled\n"), NULL, MM_NOTHING);
-		}
-	}
-}
-
 // ===============
 // VIDEO MODE MENU
 // ===============
diff --git a/src/m_menu.h b/src/m_menu.h
index 4d6e2fac5..de76a2710 100644
--- a/src/m_menu.h
+++ b/src/m_menu.h
@@ -3,7 +3,7 @@
 // Copyright (C) 1993-1996 by id Software, Inc.
 // Copyright (C) 1998-2000 by DooM Legacy Team.
 // Copyright (C) 2011-2016 by Matthew "Inuyasha" Walsh.
-// Copyright (C) 1999-2016 by Sonic Team Junior.
+// Copyright (C) 1999-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
diff --git a/src/m_misc.c b/src/m_misc.c
index 5c4e7f2f9..cd87c9849 100644
--- a/src/m_misc.c
+++ b/src/m_misc.c
@@ -2,7 +2,7 @@
 //-----------------------------------------------------------------------------
 // Copyright (C) 1993-1996 by id Software, Inc.
 // Copyright (C) 1998-2000 by DooM Legacy Team.
-// Copyright (C) 1999-2016 by Sonic Team Junior.
+// Copyright (C) 1999-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
@@ -58,7 +58,7 @@ typedef off_t off64_t;
 
 #if defined(__MINGW32__) && ((__GNUC__ > 7) || (__GNUC__ == 6 && __GNUC_MINOR__ >= 3))
 #define PRIdS "u"
-#elif defined (_WIN32) 
+#elif defined (_WIN32)
 #define PRIdS "Iu"
 #elif defined (_PSP) || defined (_arch_dreamcast) || defined (DJGPP) || defined (_WII) || defined (_NDS) || defined (_PS3)
 #define PRIdS "u"
@@ -646,11 +646,11 @@ static void M_PNGhdr(png_structp png_ptr, png_infop png_info_ptr, PNG_CONST png_
 static void M_PNGText(png_structp png_ptr, png_infop png_info_ptr, PNG_CONST png_byte movie)
 {
 #ifdef PNG_TEXT_SUPPORTED
-#define SRB2PNGTXT 10 //PNG_KEYWORD_MAX_LENGTH(79) is the max
+#define SRB2PNGTXT 11 //PNG_KEYWORD_MAX_LENGTH(79) is the max
 	png_text png_infotext[SRB2PNGTXT];
 	char keytxt[SRB2PNGTXT][12] = {
 	"Title", "Description", "Playername", "Mapnum", "Mapname",
-	"Location", "Interface", "Revision", "Build Date", "Build Time"};
+	"Location", "Interface", "Render Mode", "Revision", "Build Date", "Build Time"};
 	char titletxt[] = "Sonic Robo Blast 2 " VERSIONSTRING;
 	png_charp playertxt =  cv_playername.zstring;
 	char desctxt[] = "SRB2 Screenshot";
@@ -666,6 +666,7 @@ static void M_PNGText(png_structp png_ptr, png_infop png_info_ptr, PNG_CONST png
 #else
 	 "Unknown";
 #endif
+	char rendermodetxt[9];
 	char maptext[8];
 	char lvlttltext[48];
 	char locationtxt[40];
@@ -673,6 +674,19 @@ static void M_PNGText(png_structp png_ptr, png_infop png_info_ptr, PNG_CONST png
 	char ctdate[40];
 	char cttime[40];
 
+	switch (rendermode)
+	{
+		case render_soft:
+			strcpy(rendermodetxt, "Software");
+			break;
+		case render_opengl:
+			strcpy(rendermodetxt, "OpenGL");
+			break;
+		default: // Just in case
+			strcpy(rendermodetxt, "None");
+			break;
+	}
+
 	if (gamestate == GS_LEVEL)
 		snprintf(maptext, 8, "%s", G_BuildMapName(gamemap));
 	else
@@ -710,9 +724,10 @@ static void M_PNGText(png_structp png_ptr, png_infop png_info_ptr, PNG_CONST png
 	png_infotext[4].text = lvlttltext;
 	png_infotext[5].text = locationtxt;
 	png_infotext[6].text = interfacetxt;
-	png_infotext[7].text = strncpy(ctrevision, comprevision, sizeof(ctrevision)-1);
-	png_infotext[8].text = strncpy(ctdate, compdate, sizeof(ctdate)-1);
-	png_infotext[9].text = strncpy(cttime, comptime, sizeof(cttime)-1);
+	png_infotext[7].text = rendermodetxt;
+	png_infotext[8].text = strncpy(ctrevision, comprevision, sizeof(ctrevision)-1);
+	png_infotext[9].text = strncpy(ctdate, compdate, sizeof(ctdate)-1);
+	png_infotext[10].text = strncpy(cttime, comptime, sizeof(cttime)-1);
 
 	png_set_text(png_ptr, png_info_ptr, png_infotext, SRB2PNGTXT);
 #undef SRB2PNGTXT
diff --git a/src/m_misc.h b/src/m_misc.h
index dc540dc16..7dd8baabf 100644
--- a/src/m_misc.h
+++ b/src/m_misc.h
@@ -2,7 +2,7 @@
 //-----------------------------------------------------------------------------
 // Copyright (C) 1993-1996 by id Software, Inc.
 // Copyright (C) 1998-2000 by DooM Legacy Team.
-// Copyright (C) 1999-2016 by Sonic Team Junior.
+// Copyright (C) 1999-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
@@ -19,6 +19,7 @@
 #include "tables.h"
 
 #include "d_event.h" // Screenshot responder
+#include "command.h"
 
 typedef enum {
 	MM_OFF = 0,
@@ -28,6 +29,12 @@ typedef enum {
 } moviemode_t;
 extern moviemode_t moviemode;
 
+extern consvar_t cv_screenshot_option, cv_screenshot_folder;
+extern consvar_t cv_moviemode;
+extern consvar_t cv_zlib_memory, cv_zlib_level, cv_zlib_strategy, cv_zlib_window_bits;
+extern consvar_t cv_zlib_memorya, cv_zlib_levela, cv_zlib_strategya, cv_zlib_window_bitsa;
+extern consvar_t cv_apng_delay;
+
 void M_StartMovie(void);
 void M_SaveFrame(void);
 void M_StopMovie(void);
diff --git a/src/m_queue.c b/src/m_queue.c
index daa7d7a24..a3aa04871 100644
--- a/src/m_queue.c
+++ b/src/m_queue.c
@@ -1,7 +1,7 @@
 // SONIC ROBO BLAST 2
 //-----------------------------------------------------------------------------
 // Copyright (C) 2003      by James Haley
-// Copyright (C) 2003-2016 by Sonic Team Junior.
+// Copyright (C) 2003-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
diff --git a/src/m_queue.h b/src/m_queue.h
index 7e0d58d39..eebb21468 100644
--- a/src/m_queue.h
+++ b/src/m_queue.h
@@ -1,7 +1,7 @@
 // SONIC ROBO BLAST 2
 //-----------------------------------------------------------------------------
 // Copyright (C) 2003      by James Haley
-// Copyright (C) 2003-2016 by Sonic Team Junior.
+// Copyright (C) 2003-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
diff --git a/src/m_random.c b/src/m_random.c
index 839b06e40..3d46f76b7 100644
--- a/src/m_random.c
+++ b/src/m_random.c
@@ -3,7 +3,7 @@
 // Copyright (C) 1993-1996 by id Software, Inc.
 // Copyright (C) 1998-2000 by DooM Legacy Team.
 // Copyright (C) 2012-2016 by Matthew "Inuyasha" Walsh.
-// Copyright (C) 1999-2016 by Sonic Team Junior.
+// Copyright (C) 1999-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
diff --git a/src/m_random.h b/src/m_random.h
index 76dd9f1db..6187bcf1c 100644
--- a/src/m_random.h
+++ b/src/m_random.h
@@ -3,7 +3,7 @@
 // Copyright (C) 1993-1996 by id Software, Inc.
 // Copyright (C) 1998-2000 by DooM Legacy Team.
 // Copyright (C) 2012-2016 by Matthew "Inuyasha" Walsh.
-// Copyright (C) 1999-2016 by Sonic Team Junior.
+// Copyright (C) 1999-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
diff --git a/src/m_swap.h b/src/m_swap.h
index 2352a0b23..2d42f6138 100644
--- a/src/m_swap.h
+++ b/src/m_swap.h
@@ -2,7 +2,7 @@
 //-----------------------------------------------------------------------------
 // Copyright (C) 1993-1996 by id Software, Inc.
 // Copyright (C) 1998-2000 by DooM Legacy Team.
-// Copyright (C) 1999-2016 by Sonic Team Junior.
+// Copyright (C) 1999-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
diff --git a/src/mserv.c b/src/mserv.c
index 2bb2923d7..3fbb63760 100644
--- a/src/mserv.c
+++ b/src/mserv.c
@@ -1,7 +1,7 @@
 // SONIC ROBO BLAST 2
 //-----------------------------------------------------------------------------
 // Copyright (C) 1998-2000 by DooM Legacy Team.
-// Copyright (C) 1999-2016 by Sonic Team Junior.
+// Copyright (C) 1999-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
@@ -206,7 +206,7 @@ static void ServerName_OnChange(void);
 
 #define DEF_PORT "28900"
 consvar_t cv_masterserver = {"masterserver", "ms.srb2.org:"DEF_PORT, CV_SAVE, NULL, MasterServer_OnChange, 0, NULL, NULL, 0, 0, NULL};
-consvar_t cv_servername = {"servername", "SRB2 server", CV_SAVE, NULL, ServerName_OnChange, 0, NULL, NULL, 0, 0, NULL};
+consvar_t cv_servername = {"servername", "SRB2 server", CV_SAVE|CV_CALL|CV_NOINIT, NULL, ServerName_OnChange, 0, NULL, NULL, 0, 0, NULL};
 
 INT16 ms_RoomId = -1;
 
@@ -557,9 +557,21 @@ const char *GetMODVersion(void)
 	msg.room = MODID; // Might as well use it for something.
 	sprintf(msg.buffer,"%d",MODVERSION);
 	if (MS_Write(&msg) < 0)
+	{
+		CONS_Alert(CONS_ERROR, M_GetText("Could not send to the Master Server\n"));
+		M_StartMessage(M_GetText("Could not send to the Master Server\n"), NULL, MM_NOTHING);
+		CloseConnection();
 		return NULL;
+	}
+
+	if (MS_Read(&msg) < 0)
+	{
+		CONS_Alert(CONS_ERROR, M_GetText("No reply from the Master Server\n"));
+		M_StartMessage(M_GetText("No reply from the Master Server\n"), NULL, MM_NOTHING);
+		CloseConnection();
+		return NULL;
+	}
 
-	MS_Read(&msg);
 	CloseConnection();
 
 	if(strcmp(msg.buffer,"NULL") != 0)
@@ -587,9 +599,19 @@ void GetMODVersion_Console(void)
 	msg.room = MODID; // Might as well use it for something.
 	sprintf(msg.buffer,"%d",MODVERSION);
 	if (MS_Write(&msg) < 0)
+	{
+		CONS_Alert(CONS_ERROR, M_GetText("Could not send to the Master Server\n"));
+		CloseConnection();
 		return;
+	}
+
+	if (MS_Read(&msg) < 0)
+	{
+		CONS_Alert(CONS_ERROR, M_GetText("No reply from the Master Server\n"));
+		CloseConnection();
+		return;
+	}
 
-	MS_Read(&msg);
 	CloseConnection();
 
 	if(strcmp(msg.buffer,"NULL") != 0)
@@ -956,8 +978,8 @@ void MasterClient_Ticker(void)
 
 static void ServerName_OnChange(void)
 {
-	UnregisterServer();
-	RegisterServer();
+	if (con_state == MSCS_REGISTERED)
+		AddToMasterServer(false);
 }
 
 static void MasterServer_OnChange(void)
diff --git a/src/mserv.h b/src/mserv.h
index c28ece264..09cd4f089 100644
--- a/src/mserv.h
+++ b/src/mserv.h
@@ -1,7 +1,7 @@
 // SONIC ROBO BLAST 2
 //-----------------------------------------------------------------------------
 // Copyright (C) 1998-2000 by DooM Legacy Team.
-// Copyright (C) 1999-2016 by Sonic Team Junior.
+// Copyright (C) 1999-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
diff --git a/src/nds/i_sound.c b/src/nds/i_sound.c
index 8dea4ad7d..a17c7f66a 100644
--- a/src/nds/i_sound.c
+++ b/src/nds/i_sound.c
@@ -21,13 +21,14 @@ void I_ShutdownSound(void){}
 //  SFX I/O
 //
 
-INT32 I_StartSound(sfxenum_t id, INT32 vol, INT32 sep, INT32 pitch, INT32 priority)
+INT32 I_StartSound(sfxenum_t id, INT32 vol, INT32 sep, INT32 pitch, INT32 priority, INT32 channel)
 {
 	(void)id;
 	(void)vol;
 	(void)sep;
 	(void)pitch;
 	(void)priority;
+	(void)channel;
 	return -1;
 }
 
diff --git a/src/p_ceilng.c b/src/p_ceilng.c
index 27d739414..757edebae 100644
--- a/src/p_ceilng.c
+++ b/src/p_ceilng.c
@@ -2,7 +2,7 @@
 //-----------------------------------------------------------------------------
 // Copyright (C) 1993-1996 by id Software, Inc.
 // Copyright (C) 1998-2000 by DooM Legacy Team.
-// Copyright (C) 1999-2016 by Sonic Team Junior.
+// Copyright (C) 1999-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
diff --git a/src/p_enemy.c b/src/p_enemy.c
index f2e54a583..7c28854ea 100644
--- a/src/p_enemy.c
+++ b/src/p_enemy.c
@@ -2,7 +2,7 @@
 //-----------------------------------------------------------------------------
 // Copyright (C) 1993-1996 by id Software, Inc.
 // Copyright (C) 1998-2000 by DooM Legacy Team.
-// Copyright (C) 1999-2016 by Sonic Team Junior.
+// Copyright (C) 1999-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
diff --git a/src/p_floor.c b/src/p_floor.c
index 35c743a07..aca92e091 100644
--- a/src/p_floor.c
+++ b/src/p_floor.c
@@ -2,7 +2,7 @@
 //-----------------------------------------------------------------------------
 // Copyright (C) 1993-1996 by id Software, Inc.
 // Copyright (C) 1998-2000 by DooM Legacy Team.
-// Copyright (C) 1999-2016 by Sonic Team Junior.
+// Copyright (C) 1999-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
diff --git a/src/p_inter.c b/src/p_inter.c
index 407e091fa..009a2be1f 100644
--- a/src/p_inter.c
+++ b/src/p_inter.c
@@ -2,7 +2,7 @@
 //-----------------------------------------------------------------------------
 // Copyright (C) 1993-1996 by id Software, Inc.
 // Copyright (C) 1998-2000 by DooM Legacy Team.
-// Copyright (C) 1999-2016 by Sonic Team Junior.
+// Copyright (C) 1999-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
diff --git a/src/p_lights.c b/src/p_lights.c
index 8aa2eedca..2da38d1dc 100644
--- a/src/p_lights.c
+++ b/src/p_lights.c
@@ -2,7 +2,7 @@
 //-----------------------------------------------------------------------------
 // Copyright (C) 1993-1996 by id Software, Inc.
 // Copyright (C) 1998-2000 by DooM Legacy Team.
-// Copyright (C) 1999-2016 by Sonic Team Junior.
+// Copyright (C) 1999-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
diff --git a/src/p_local.h b/src/p_local.h
index 1fd7ada04..e09b49517 100644
--- a/src/p_local.h
+++ b/src/p_local.h
@@ -2,7 +2,7 @@
 //-----------------------------------------------------------------------------
 // Copyright (C) 1993-1996 by id Software, Inc.
 // Copyright (C) 1998-2000 by DooM Legacy Team.
-// Copyright (C) 1999-2016 by Sonic Team Junior.
+// Copyright (C) 1999-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
@@ -68,7 +68,6 @@
 
 // both the head and tail of the thinker list
 extern thinker_t thinkercap;
-extern INT32 runcount;
 
 void P_InitThinkers(void);
 void P_AddThinker(thinker_t *thinker);
diff --git a/src/p_map.c b/src/p_map.c
index f319acea8..865877c90 100644
--- a/src/p_map.c
+++ b/src/p_map.c
@@ -2,7 +2,7 @@
 //-----------------------------------------------------------------------------
 // Copyright (C) 1993-1996 by id Software, Inc.
 // Copyright (C) 1998-2000 by DooM Legacy Team.
-// Copyright (C) 1999-2016 by Sonic Team Junior.
+// Copyright (C) 1999-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
@@ -1700,18 +1700,6 @@ boolean P_CheckCameraPosition(fixed_t x, fixed_t y, camera_t *thiscam)
 	return true;
 }
 
-//
-// CheckMissileImpact
-//
-static void CheckMissileImpact(mobj_t *mobj)
-{
-	if (!(mobj->flags & MF_MISSILE) || !mobj->target)
-		return;
-
-	if (!mobj->target->player)
-		return;
-}
-
 // The highest the camera will "step up" onto another floor.
 #define MAXCAMERASTEPMOVE MAXSTEPMOVE
 
@@ -1932,11 +1920,7 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff)
 		}
 
 		if (!P_CheckPosition(thing, tryx, tryy))
-		{
-			if (!P_MobjWasRemoved(thing))
-				CheckMissileImpact(thing);
 			return false; // solid wall or thing
-		}
 
 		if (!(thing->flags & MF_NOCLIP))
 		{
@@ -1962,7 +1946,6 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff)
 
 			if (tmceilingz - tmfloorz < thing->height)
 			{
-				CheckMissileImpact(thing);
 				if (tmfloorthing)
 					tmhitthing = tmfloorthing;
 				return false; // doesn't fit
@@ -1973,16 +1956,10 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff)
 			if (thing->eflags & MFE_VERTICALFLIP)
 			{
 				if (thing->z < tmfloorz)
-				{
-					CheckMissileImpact(thing);
 					return false; // mobj must raise itself to fit
-				}
 			}
 			else if (tmceilingz < thingtop)
-			{
-				CheckMissileImpact(thing);
 				return false; // mobj must lower itself to fit
-			}
 
 			// Ramp test
 			if (maxstep > 0 && !(
@@ -2030,7 +2007,6 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff)
 			{
 				if (thingtop - tmceilingz > maxstep)
 				{
-					CheckMissileImpact(thing);
 					if (tmfloorthing)
 						tmhitthing = tmfloorthing;
 					return false; // too big a step up
@@ -2038,18 +2014,11 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff)
 			}
 			else if (tmfloorz - thing->z > maxstep)
 			{
-				CheckMissileImpact(thing);
 				if (tmfloorthing)
 					tmhitthing = tmfloorthing;
 				return false; // too big a step up
 			}
 
-			if (tmfloorz > thing->z)
-			{
-				if (thing->flags & MF_MISSILE)
-					CheckMissileImpact(thing);
-			}
-
 			if (!allowdropoff && !(thing->flags & MF_FLOAT) && thing->type != MT_SKIM && !tmfloorthing)
 			{
 				if (thing->eflags & MFE_VERTICALFLIP)
diff --git a/src/p_maputl.c b/src/p_maputl.c
index 46b033386..1be57399c 100644
--- a/src/p_maputl.c
+++ b/src/p_maputl.c
@@ -2,7 +2,7 @@
 //-----------------------------------------------------------------------------
 // Copyright (C) 1993-1996 by id Software, Inc.
 // Copyright (C) 1998-2000 by DooM Legacy Team.
-// Copyright (C) 1999-2016 by Sonic Team Junior.
+// Copyright (C) 1999-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
diff --git a/src/p_maputl.h b/src/p_maputl.h
index 3d74e927b..1fcb68d4c 100644
--- a/src/p_maputl.h
+++ b/src/p_maputl.h
@@ -1,7 +1,7 @@
 // SONIC ROBO BLAST 2
 //-----------------------------------------------------------------------------
 // Copyright (C) 1998-2000 by DooM Legacy Team.
-// Copyright (C) 1999-2016 by Sonic Team Junior.
+// Copyright (C) 1999-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
diff --git a/src/p_mobj.c b/src/p_mobj.c
index 5f85474c6..7fa781153 100644
--- a/src/p_mobj.c
+++ b/src/p_mobj.c
@@ -2,7 +2,7 @@
 //-----------------------------------------------------------------------------
 // Copyright (C) 1993-1996 by id Software, Inc.
 // Copyright (C) 1998-2000 by DooM Legacy Team.
-// Copyright (C) 1999-2016 by Sonic Team Junior.
+// Copyright (C) 1999-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
@@ -3506,14 +3506,15 @@ boolean P_CameraThinker(player_t *player, camera_t *thiscam, boolean resetcalled
 
 	if (player->pflags & PF_FLIPCAM && !(player->pflags & PF_NIGHTSMODE) && player->mo->eflags & MFE_VERTICALFLIP)
 		postimg = postimg_flip;
-	else if (player->awayviewtics)
+	else if (player->awayviewtics && player->awayviewmobj != NULL)	// Camera must obviously exist
 	{
 		camera_t dummycam;
 		dummycam.subsector = player->awayviewmobj->subsector;
 		dummycam.x = player->awayviewmobj->x;
 		dummycam.y = player->awayviewmobj->y;
 		dummycam.z = player->awayviewmobj->z;
-		dummycam.height = 40*FRACUNIT; // alt view height is 20*FRACUNIT
+		//dummycam.height = 40*FRACUNIT; // alt view height is 20*FRACUNIT
+		dummycam.height = 0;			 // Why? Remote viewpoint cameras have no height.
 		// Are we in water?
 		if (P_CameraCheckWater(&dummycam))
 			postimg = postimg_water;
@@ -3840,7 +3841,8 @@ void P_RecalcPrecipInSector(sector_t *sector)
 //
 void P_NullPrecipThinker(precipmobj_t *mobj)
 {
-	(void)mobj;
+	//(void)mobj;
+	mobj->precipflags &= ~PCF_THUNK;
 }
 
 void P_SnowThinker(precipmobj_t *mobj)
@@ -3860,25 +3862,26 @@ void P_RainThinker(precipmobj_t *mobj)
 	{
 		// cycle through states,
 		// calling action functions at transitions
-		if (mobj->tics > 0 && --mobj->tics == 0)
-		{
-			// you can cycle through multiple states in a tic
-			if (!P_SetPrecipMobjState(mobj, mobj->state->nextstate))
-				return; // freed itself
-		}
+		if (mobj->tics <= 0)
+			return;
+
+		if (--mobj->tics)
+			return;
+
+		if (!P_SetPrecipMobjState(mobj, mobj->state->nextstate))
+			return;
+
+		if (mobj->state != &states[S_RAINRETURN])
+			return;
+
+		mobj->z = mobj->ceilingz;
+		P_SetPrecipMobjState(mobj, S_RAIN1);
 
-		if (mobj->state == &states[S_RAINRETURN])
-		{
-			mobj->z = mobj->ceilingz;
-			P_SetPrecipMobjState(mobj, S_RAIN1);
-		}
 		return;
 	}
 
 	// adjust height
-	mobj->z += mobj->momz;
-
-	if (mobj->z <= mobj->floorz)
+	if ((mobj->z += mobj->momz) <= mobj->floorz)
 	{
 		// no splashes on sky or bottomless pits
 		if (mobj->precipflags & PCF_PIT)
@@ -7926,14 +7929,15 @@ static precipmobj_t *P_SpawnPrecipMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype
 static inline precipmobj_t *P_SpawnRainMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type)
 {
 	precipmobj_t *mo = P_SpawnPrecipMobj(x,y,z,type);
-	mo->thinker.function.acp1 = (actionf_p1)P_RainThinker;
+	mo->precipflags |= PCF_RAIN;
+	//mo->thinker.function.acp1 = (actionf_p1)P_RainThinker;
 	return mo;
 }
 
 static inline precipmobj_t *P_SpawnSnowMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type)
 {
 	precipmobj_t *mo = P_SpawnPrecipMobj(x,y,z,type);
-	mo->thinker.function.acp1 = (actionf_p1)P_SnowThinker;
+	//mo->thinker.function.acp1 = (actionf_p1)P_SnowThinker;
 	return mo;
 }
 
@@ -8228,7 +8232,7 @@ void P_PrecipitationEffects(void)
 	if (!playeringame[displayplayer] || !players[displayplayer].mo)
 		return;
 
-	if (nosound || sound_disabled)
+	if (sound_disabled)
 		return; // Sound off? D'aw, no fun.
 
 	if (players[displayplayer].mo->subsector->sector->ceilingpic == skyflatnum)
diff --git a/src/p_mobj.h b/src/p_mobj.h
index 79cffae89..a15a9fc85 100644
--- a/src/p_mobj.h
+++ b/src/p_mobj.h
@@ -2,7 +2,7 @@
 //-----------------------------------------------------------------------------
 // Copyright (C) 1993-1996 by id Software, Inc.
 // Copyright (C) 1998-2000 by DooM Legacy Team.
-// Copyright (C) 1999-2016 by Sonic Team Junior.
+// Copyright (C) 1999-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
@@ -252,6 +252,10 @@ typedef enum {
 	PCF_FOF = 4,
 	// Above MOVING FOF (this means we need to keep floorz up to date...)
 	PCF_MOVINGFOF = 8,
+	// Is rain.
+	PCF_RAIN = 16,
+	// Ran the thinker this tic.
+	PCF_THUNK = 32,
 } precipflag_t;
 // Map Object definition.
 typedef struct mobj_s
@@ -441,7 +445,7 @@ boolean P_SupermanLook4Players(mobj_t *actor);
 void P_DestroyRobots(void);
 void P_SnowThinker(precipmobj_t *mobj);
 void P_RainThinker(precipmobj_t *mobj);
-FUNCMATH void P_NullPrecipThinker(precipmobj_t *mobj);
+void P_NullPrecipThinker(precipmobj_t *mobj);
 void P_RemovePrecipMobj(precipmobj_t *mobj);
 void P_SetScale(mobj_t *mobj, fixed_t newscale);
 void P_XYMovement(mobj_t *mo);
diff --git a/src/p_polyobj.c b/src/p_polyobj.c
index 103b1cb3c..8d0f4dab6 100644
--- a/src/p_polyobj.c
+++ b/src/p_polyobj.c
@@ -1,7 +1,7 @@
 // SONIC ROBO BLAST 2
 //-----------------------------------------------------------------------------
 // Copyright (C) 2006      by James Haley
-// Copyright (C) 2006-2016 by Sonic Team Junior.
+// Copyright (C) 2006-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
diff --git a/src/p_polyobj.h b/src/p_polyobj.h
index 605215c02..60e996cae 100644
--- a/src/p_polyobj.h
+++ b/src/p_polyobj.h
@@ -1,7 +1,7 @@
 // SONIC ROBO BLAST 2
 //-----------------------------------------------------------------------------
 // Copyright (C) 2006      by James Haley
-// Copyright (C) 2006-2016 by Sonic Team Junior.
+// Copyright (C) 2006-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
diff --git a/src/p_pspr.h b/src/p_pspr.h
index 2fb232e73..16708bcb2 100644
--- a/src/p_pspr.h
+++ b/src/p_pspr.h
@@ -2,7 +2,7 @@
 //-----------------------------------------------------------------------------
 // Copyright (C) 1993-1996 by id Software, Inc.
 // Copyright (C) 1998-2000 by DooM Legacy Team.
-// Copyright (C) 1999-2016 by Sonic Team Junior.
+// Copyright (C) 1999-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
diff --git a/src/p_saveg.c b/src/p_saveg.c
index d1ec8e5ab..c8c38d3cb 100644
--- a/src/p_saveg.c
+++ b/src/p_saveg.c
@@ -2,7 +2,7 @@
 //-----------------------------------------------------------------------------
 // Copyright (C) 1993-1996 by id Software, Inc.
 // Copyright (C) 1998-2000 by DooM Legacy Team.
-// Copyright (C) 1999-2016 by Sonic Team Junior.
+// Copyright (C) 1999-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
@@ -1661,8 +1661,7 @@ static void P_NetArchiveThinkers(void)
 	for (th = thinkercap.next; th != &thinkercap; th = th->next)
 	{
 		if (!(th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed
-		 || th->function.acp1 == (actionf_p1)P_RainThinker
-		 || th->function.acp1 == (actionf_p1)P_SnowThinker))
+		 || th->function.acp1 == (actionf_p1)P_NullPrecipThinker))
 			numsaved++;
 
 		if (th->function.acp1 == (actionf_p1)P_MobjThinker)
@@ -1671,8 +1670,7 @@ static void P_NetArchiveThinkers(void)
 			continue;
 		}
 #ifdef PARANOIA
-		else if (th->function.acp1 == (actionf_p1)P_RainThinker
-			|| th->function.acp1 == (actionf_p1)P_SnowThinker);
+		else if (th->function.acp1 == (actionf_p1)P_NullPrecipThinker);
 #endif
 		else if (th->function.acp1 == (actionf_p1)T_MoveCeiling)
 		{
diff --git a/src/p_saveg.h b/src/p_saveg.h
index 3670d3503..0992f1185 100644
--- a/src/p_saveg.h
+++ b/src/p_saveg.h
@@ -2,7 +2,7 @@
 //-----------------------------------------------------------------------------
 // Copyright (C) 1993-1996 by id Software, Inc.
 // Copyright (C) 1998-2000 by DooM Legacy Team.
-// Copyright (C) 1999-2016 by Sonic Team Junior.
+// Copyright (C) 1999-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
diff --git a/src/p_setup.c b/src/p_setup.c
index 17a6797f4..49b98e724 100644
--- a/src/p_setup.c
+++ b/src/p_setup.c
@@ -2,7 +2,7 @@
 //-----------------------------------------------------------------------------
 // Copyright (C) 1993-1996 by id Software, Inc.
 // Copyright (C) 1998-2000 by DooM Legacy Team.
-// Copyright (C) 1999-2016 by Sonic Team Junior.
+// Copyright (C) 1999-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
@@ -451,6 +451,7 @@ static void P_LoadSegs(lumpnum_t lumpnum)
 			//Hurdler: 04/12/2000: for now, only used in hardware mode
 			li->lightmaps = NULL; // list of static lightmap for this seg
 		}
+		li->pv1 = li->pv2 = NULL;
 #endif
 
 		li->angle = (SHORT(ml->angle))<<FRACBITS;
@@ -2476,6 +2477,43 @@ static void P_LoadNightsGhosts(void)
 	free(gpath);
 }
 
+static void P_SetupCamera(void)
+{
+	if (players[displayplayer].mo && (server || addedtogame))
+	{
+		camera.x = players[displayplayer].mo->x;
+		camera.y = players[displayplayer].mo->y;
+		camera.z = players[displayplayer].mo->z;
+		camera.angle = players[displayplayer].mo->angle;
+		camera.subsector = R_PointInSubsector(camera.x, camera.y); // make sure camera has a subsector set -- Monster Iestyn (12/11/18)
+	}
+	else
+	{
+		mapthing_t *thing;
+
+		switch (gametype)
+		{
+		case GT_MATCH:
+		case GT_TAG:
+			thing = deathmatchstarts[0];
+			break;
+
+		default:
+			thing = playerstarts[0];
+			break;
+		}
+
+		if (thing)
+		{
+			camera.x = thing->x;
+			camera.y = thing->y;
+			camera.z = thing->z;
+			camera.angle = FixedAngle((fixed_t)thing->angle << FRACBITS);
+			camera.subsector = R_PointInSubsector(camera.x, camera.y); // make sure camera has a subsector set -- Monster Iestyn (12/11/18)
+		}
+	}
+}
+
 /** Loads a level from a lump or external wad.
   *
   * \param skipprecip If true, don't spawn precipitation.
@@ -2813,37 +2851,7 @@ boolean P_SetupLevel(boolean skipprecip)
 
 	if (!dedicated)
 	{
-		if (players[displayplayer].mo && (server || addedtogame))
-		{
-			camera.x = players[displayplayer].mo->x;
-			camera.y = players[displayplayer].mo->y;
-			camera.z = players[displayplayer].mo->z;
-			camera.angle = players[displayplayer].mo->angle;
-		}
-		else
-		{
-			mapthing_t *thing;
-
-			switch (gametype)
-			{
-			case GT_MATCH:
-			case GT_TAG:
-				thing = deathmatchstarts[0];
-				break;
-
-			default:
-				thing = playerstarts[0];
-				break;
-			}
-
-			if (thing)
-			{
-				camera.x = thing->x;
-				camera.y = thing->y;
-				camera.z = thing->z;
-				camera.angle = FixedAngle((fixed_t)thing->angle << FRACBITS);
-			}
-		}
+		P_SetupCamera();
 
 		if (!cv_cam_height.changed)
 			CV_Set(&cv_cam_height, cv_cam_height.defaultvalue);
diff --git a/src/p_setup.h b/src/p_setup.h
index 3bca11047..add786f49 100644
--- a/src/p_setup.h
+++ b/src/p_setup.h
@@ -2,7 +2,7 @@
 //-----------------------------------------------------------------------------
 // Copyright (C) 1993-1996 by id Software, Inc.
 // Copyright (C) 1998-2000 by DooM Legacy Team.
-// Copyright (C) 1999-2016 by Sonic Team Junior.
+// Copyright (C) 1999-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
diff --git a/src/p_sight.c b/src/p_sight.c
index bd6ab4d73..626f8bbef 100644
--- a/src/p_sight.c
+++ b/src/p_sight.c
@@ -2,7 +2,7 @@
 //-----------------------------------------------------------------------------
 // Copyright (C) 1993-1996 by id Software, Inc.
 // Copyright (C) 1998-2000 by DooM Legacy Team.
-// Copyright (C) 1999-2016 by Sonic Team Junior.
+// Copyright (C) 1999-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
diff --git a/src/p_slopes.c b/src/p_slopes.c
index d939fee98..2d7f13319 100644
--- a/src/p_slopes.c
+++ b/src/p_slopes.c
@@ -1,7 +1,7 @@
 // SONIC ROBO BLAST 2
 //-----------------------------------------------------------------------------
 // Copyright (C) 2004      by Stephen McGranahan
-// Copyright (C) 2015-2016 by Sonic Team Junior.
+// Copyright (C) 2015-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
diff --git a/src/p_slopes.h b/src/p_slopes.h
index de38f1d9e..f083024dd 100644
--- a/src/p_slopes.h
+++ b/src/p_slopes.h
@@ -1,7 +1,7 @@
 // SONIC ROBO BLAST 2
 //-----------------------------------------------------------------------------
 // Copyright (C) 2004      by Stephen McGranahan
-// Copyright (C) 2015-2016 by Sonic Team Junior.
+// Copyright (C) 2015-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
diff --git a/src/p_spec.c b/src/p_spec.c
index c62c3b209..198d87e56 100644
--- a/src/p_spec.c
+++ b/src/p_spec.c
@@ -2,7 +2,7 @@
 //-----------------------------------------------------------------------------
 // Copyright (C) 1993-1996 by id Software, Inc.
 // Copyright (C) 1998-2000 by DooM Legacy Team.
-// Copyright (C) 1999-2016 by Sonic Team Junior.
+// Copyright (C) 1999-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
@@ -2039,8 +2039,7 @@ void P_SwitchWeather(INT32 weathernum)
 
 		for (think = thinkercap.next; think != &thinkercap; think = think->next)
 		{
-			if ((think->function.acp1 != (actionf_p1)P_SnowThinker)
-				&& (think->function.acp1 != (actionf_p1)P_RainThinker))
+			if (think->function.acp1 != (actionf_p1)P_NullPrecipThinker)
 				continue; // not a precipmobj thinker
 
 			precipmobj = (precipmobj_t *)think;
@@ -2056,14 +2055,12 @@ void P_SwitchWeather(INT32 weathernum)
 
 		for (think = thinkercap.next; think != &thinkercap; think = think->next)
 		{
+			if (think->function.acp1 != (actionf_p1)P_NullPrecipThinker)
+				continue; // not a precipmobj thinker
+			precipmobj = (precipmobj_t *)think;
+
 			if (swap == PRECIP_RAIN) // Snow To Rain
 			{
-				if (!(think->function.acp1 == (actionf_p1)P_SnowThinker
-					|| think->function.acp1 == (actionf_p1)P_NullPrecipThinker))
-					continue; // not a precipmobj thinker
-
-				precipmobj = (precipmobj_t *)think;
-
 				precipmobj->flags = mobjinfo[MT_RAIN].flags;
 				st = &states[mobjinfo[MT_RAIN].spawnstate];
 				precipmobj->state = st;
@@ -2074,18 +2071,13 @@ void P_SwitchWeather(INT32 weathernum)
 
 				precipmobj->precipflags &= ~PCF_INVISIBLE;
 
-				think->function.acp1 = (actionf_p1)P_RainThinker;
+				precipmobj->precipflags |= PCF_RAIN;
+				//think->function.acp1 = (actionf_p1)P_RainThinker;
 			}
 			else if (swap == PRECIP_SNOW) // Rain To Snow
 			{
 				INT32 z;
 
-				if (!(think->function.acp1 == (actionf_p1)P_RainThinker
-					|| think->function.acp1 == (actionf_p1)P_NullPrecipThinker))
-					continue; // not a precipmobj thinker
-
-				precipmobj = (precipmobj_t *)think;
-
 				precipmobj->flags = mobjinfo[MT_SNOWFLAKE].flags;
 				z = M_RandomByte();
 
@@ -2103,19 +2095,13 @@ void P_SwitchWeather(INT32 weathernum)
 				precipmobj->frame = st->frame;
 				precipmobj->momz = mobjinfo[MT_SNOWFLAKE].speed;
 
-				precipmobj->precipflags &= ~PCF_INVISIBLE;
+				precipmobj->precipflags &= ~(PCF_INVISIBLE|PCF_RAIN);
 
-				think->function.acp1 = (actionf_p1)P_SnowThinker;
+				//think->function.acp1 = (actionf_p1)P_SnowThinker;
 			}
 			else if (swap == PRECIP_BLANK || swap == PRECIP_STORM_NORAIN) // Remove precip, but keep it around for reuse.
 			{
-				if (!(think->function.acp1 == (actionf_p1)P_RainThinker
-					|| think->function.acp1 == (actionf_p1)P_SnowThinker))
-					continue;
-
-				precipmobj = (precipmobj_t *)think;
-
-				think->function.acp1 = (actionf_p1)P_NullPrecipThinker;
+				//think->function.acp1 = (actionf_p1)P_NullPrecipThinker;
 
 				precipmobj->precipflags |= PCF_INVISIBLE;
 			}
diff --git a/src/p_spec.h b/src/p_spec.h
index a8f9ac492..17d9c7bd2 100644
--- a/src/p_spec.h
+++ b/src/p_spec.h
@@ -2,7 +2,7 @@
 //-----------------------------------------------------------------------------
 // Copyright (C) 1993-1996 by id Software, Inc.
 // Copyright (C) 1998-2000 by DooM Legacy Team.
-// Copyright (C) 1999-2016 by Sonic Team Junior.
+// Copyright (C) 1999-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
diff --git a/src/p_telept.c b/src/p_telept.c
index 4921040b4..4ca54a8f2 100644
--- a/src/p_telept.c
+++ b/src/p_telept.c
@@ -2,7 +2,7 @@
 //-----------------------------------------------------------------------------
 // Copyright (C) 1993-1996 by id Software, Inc.
 // Copyright (C) 1998-2000 by DooM Legacy Team.
-// Copyright (C) 1999-2016 by Sonic Team Junior.
+// Copyright (C) 1999-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
diff --git a/src/p_tick.c b/src/p_tick.c
index f4bc59323..89cd218e3 100644
--- a/src/p_tick.c
+++ b/src/p_tick.c
@@ -2,7 +2,7 @@
 //-----------------------------------------------------------------------------
 // Copyright (C) 1993-1996 by id Software, Inc.
 // Copyright (C) 1998-2000 by DooM Legacy Team.
-// Copyright (C) 1999-2016 by Sonic Team Junior.
+// Copyright (C) 1999-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
@@ -56,12 +56,12 @@ void Command_Numthinkers_f(void)
 		CONS_Printf(M_GetText("numthinkers <#>: Count number of thinkers\n"));
 		CONS_Printf(
 			"\t1: P_MobjThinker\n"
-			"\t2: P_RainThinker\n"
-			"\t3: P_SnowThinker\n"
-			"\t4: P_NullPrecipThinker\n"
-			"\t5: T_Friction\n"
-			"\t6: T_Pusher\n"
-			"\t7: P_RemoveThinkerDelayed\n");
+			/*"\t2: P_RainThinker\n"
+			"\t3: P_SnowThinker\n"*/
+			"\t2: P_NullPrecipThinker\n"
+			"\t3: T_Friction\n"
+			"\t4: T_Pusher\n"
+			"\t5: P_RemoveThinkerDelayed\n");
 		return;
 	}
 
@@ -73,27 +73,27 @@ void Command_Numthinkers_f(void)
 			action = (actionf_p1)P_MobjThinker;
 			CONS_Printf(M_GetText("Number of %s: "), "P_MobjThinker");
 			break;
-		case 2:
+		/*case 2:
 			action = (actionf_p1)P_RainThinker;
 			CONS_Printf(M_GetText("Number of %s: "), "P_RainThinker");
 			break;
 		case 3:
 			action = (actionf_p1)P_SnowThinker;
 			CONS_Printf(M_GetText("Number of %s: "), "P_SnowThinker");
-			break;
-		case 4:
+			break;*/
+		case 2:
 			action = (actionf_p1)P_NullPrecipThinker;
 			CONS_Printf(M_GetText("Number of %s: "), "P_NullPrecipThinker");
 			break;
-		case 5:
+		case 3:
 			action = (actionf_p1)T_Friction;
 			CONS_Printf(M_GetText("Number of %s: "), "T_Friction");
 			break;
-		case 6:
+		case 4:
 			action = (actionf_p1)T_Pusher;
 			CONS_Printf(M_GetText("Number of %s: "), "T_Pusher");
 			break;
-		case 7:
+		case 5:
 			action = (actionf_p1)P_RemoveThinkerDelayed;
 			CONS_Printf(M_GetText("Number of %s: "), "P_RemoveThinkerDelayed");
 			break;
diff --git a/src/p_tick.h b/src/p_tick.h
index 75868fdd8..169c54c8e 100644
--- a/src/p_tick.h
+++ b/src/p_tick.h
@@ -2,7 +2,7 @@
 //-----------------------------------------------------------------------------
 // Copyright (C) 1993-1996 by id Software, Inc.
 // Copyright (C) 1998-2000 by DooM Legacy Team.
-// Copyright (C) 1999-2016 by Sonic Team Junior.
+// Copyright (C) 1999-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
diff --git a/src/p_user.c b/src/p_user.c
index 7abf85347..1ac2cbd2a 100644
--- a/src/p_user.c
+++ b/src/p_user.c
@@ -2,7 +2,7 @@
 //-----------------------------------------------------------------------------
 // Copyright (C) 1993-1996 by id Software, Inc.
 // Copyright (C) 1998-2000 by DooM Legacy Team.
-// Copyright (C) 1999-2016 by Sonic Team Junior.
+// Copyright (C) 1999-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
@@ -8365,16 +8365,12 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
 	// Make player translucent if camera is too close (only in single player).
 	if (!(multiplayer || netgame) && !splitscreen)
 	{
-		fixed_t vx = 0, vy = 0;
-		if (player->awayviewtics) {
+		fixed_t vx = thiscam->x, vy = thiscam->y;
+		if (player->awayviewtics && player->awayviewmobj != NULL)		// Camera must obviously exist
+		{
 			vx = player->awayviewmobj->x;
 			vy = player->awayviewmobj->y;
 		}
-		else
-		{
-			vx = thiscam->x;
-			vy = thiscam->y;
-		}
 
 		if (P_AproxDistance(vx - player->mo->x, vy - player->mo->y) < FixedMul(48*FRACUNIT, mo->scale))
 			player->mo->flags2 |= MF2_SHADOW;
@@ -8648,8 +8644,6 @@ void P_DoPityCheck(player_t *player)
 // P_PlayerThink
 //
 
-boolean playerdeadview; // show match/chaos/tag/capture the flag rankings while in death view
-
 void P_PlayerThink(player_t *player)
 {
 	ticcmd_t *cmd;
@@ -8712,8 +8706,9 @@ void P_PlayerThink(player_t *player)
 	if (player->flashcount)
 		player->flashcount--;
 
-	if (player->awayviewtics)
-		player->awayviewtics--;
+	// By the time P_MoveChaseCamera is called, this might be zero. Do not do it here.
+	//if (player->awayviewtics)
+	//	player->awayviewtics--;
 
 	/// \note do this in the cheat code
 	if (player->pflags & PF_NOCLIP)
@@ -8838,10 +8833,6 @@ void P_PlayerThink(player_t *player)
 	if (player->playerstate == PST_DEAD)
 	{
 		player->mo->flags2 &= ~MF2_SHADOW;
-		// show the multiplayer rankings while dead
-		if (player == &players[displayplayer])
-			playerdeadview = true;
-
 		P_DeathThink(player);
 
 		return;
@@ -8862,9 +8853,6 @@ void P_PlayerThink(player_t *player)
 		player->lives = cv_startinglives.value;
 	}
 
-	if (player == &players[displayplayer])
-		playerdeadview = false;
-
 	if ((gametype == GT_RACE || gametype == GT_COMPETITION) && leveltime < 4*TICRATE)
 	{
 		cmd->buttons &= BT_USE; // Remove all buttons except BT_USE
@@ -9498,6 +9486,9 @@ void P_PlayerAfterThink(player_t *player)
 		}
 	}
 
+	if (player->awayviewtics)
+		player->awayviewtics--;
+
 	// spectator invisibility and nogravity.
 	if ((netgame || multiplayer) && player->spectator)
 	{
diff --git a/src/r_bsp.c b/src/r_bsp.c
index abb11204a..355438272 100644
--- a/src/r_bsp.c
+++ b/src/r_bsp.c
@@ -2,7 +2,7 @@
 //-----------------------------------------------------------------------------
 // Copyright (C) 1993-1996 by id Software, Inc.
 // Copyright (C) 1998-2000 by DooM Legacy Team.
-// Copyright (C) 1999-2016 by Sonic Team Junior.
+// Copyright (C) 1999-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
@@ -365,6 +365,36 @@ sector_t *R_FakeFlat(sector_t *sec, sector_t *tempsec, INT32 *floorlightlevel,
 	return sec;
 }
 
+boolean R_IsEmptyLine(seg_t *line, sector_t *front, sector_t *back)
+{
+	return (
+#ifdef POLYOBJECTS
+		!line->polyseg &&
+#endif
+		back->ceilingpic == front->ceilingpic
+		&& back->floorpic == front->floorpic
+#ifdef ESLOPE
+		&& back->f_slope == front->f_slope
+		&& back->c_slope == front->c_slope
+#endif
+		&& back->lightlevel == front->lightlevel
+		&& !line->sidedef->midtexture
+		// Check offsets too!
+		&& back->floor_xoffs == front->floor_xoffs
+		&& back->floor_yoffs == front->floor_yoffs
+		&& back->floorpic_angle == front->floorpic_angle
+		&& back->ceiling_xoffs == front->ceiling_xoffs
+		&& back->ceiling_yoffs == front->ceiling_yoffs
+		&& back->ceilingpic_angle == front->ceilingpic_angle
+		// Consider altered lighting.
+		&& back->floorlightsec == front->floorlightsec
+		&& back->ceilinglightsec == front->ceilinglightsec
+		// Consider colormaps
+		&& back->extra_colormap == front->extra_colormap
+		&& ((!front->ffloors && !back->ffloors)
+		|| front->tag == back->tag));
+}
+
 //
 // R_AddLine
 // Clips the given segment and adds any visible pieces to the line list.
@@ -526,36 +556,8 @@ static void R_AddLine(seg_t *line)
 	// Identical floor and ceiling on both sides, identical light levels on both sides,
 	// and no middle texture.
 
-	if (
-#ifdef POLYOBJECTS
-		!line->polyseg &&
-#endif
-		backsector->ceilingpic == frontsector->ceilingpic
-		&& backsector->floorpic == frontsector->floorpic
-#ifdef ESLOPE
-		&& backsector->f_slope == frontsector->f_slope
-		&& backsector->c_slope == frontsector->c_slope
-#endif
-		&& backsector->lightlevel == frontsector->lightlevel
-		&& !curline->sidedef->midtexture
-		// Check offsets too!
-		&& backsector->floor_xoffs == frontsector->floor_xoffs
-		&& backsector->floor_yoffs == frontsector->floor_yoffs
-		&& backsector->floorpic_angle == frontsector->floorpic_angle
-		&& backsector->ceiling_xoffs == frontsector->ceiling_xoffs
-		&& backsector->ceiling_yoffs == frontsector->ceiling_yoffs
-		&& backsector->ceilingpic_angle == frontsector->ceilingpic_angle
-		// Consider altered lighting.
-		&& backsector->floorlightsec == frontsector->floorlightsec
-		&& backsector->ceilinglightsec == frontsector->ceilinglightsec
-		// Consider colormaps
-		&& backsector->extra_colormap == frontsector->extra_colormap
-		&& ((!frontsector->ffloors && !backsector->ffloors)
-		|| frontsector->tag == backsector->tag))
-	{
+	if (R_IsEmptyLine(line, frontsector, backsector))
 		return;
-	}
-
 
 clippass:
 	R_ClipPassWallSegment(x1, x2 - 1);
diff --git a/src/r_bsp.h b/src/r_bsp.h
index e871b5dde..e3662e2e6 100644
--- a/src/r_bsp.h
+++ b/src/r_bsp.h
@@ -2,7 +2,7 @@
 //-----------------------------------------------------------------------------
 // Copyright (C) 1993-1996 by id Software, Inc.
 // Copyright (C) 1998-2000 by DooM Legacy Team.
-// Copyright (C) 1999-2016 by Sonic Team Junior.
+// Copyright (C) 1999-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
@@ -50,6 +50,7 @@ extern polyobj_t **po_ptrs; // temp ptr array to sort polyobject pointers
 
 sector_t *R_FakeFlat(sector_t *sec, sector_t *tempsec, INT32 *floorlightlevel,
 	INT32 *ceilinglightlevel, boolean back);
+boolean R_IsEmptyLine(seg_t *line, sector_t *front, sector_t *back);
 
 INT32 R_GetPlaneLight(sector_t *sector, fixed_t planeheight, boolean underside);
 void R_Prep3DFloors(sector_t *sector);
diff --git a/src/r_data.c b/src/r_data.c
index f2c9b1466..96c89915a 100644
--- a/src/r_data.c
+++ b/src/r_data.c
@@ -2,7 +2,7 @@
 //-----------------------------------------------------------------------------
 // Copyright (C) 1993-1996 by id Software, Inc.
 // Copyright (C) 1998-2000 by DooM Legacy Team.
-// Copyright (C) 1999-2016 by Sonic Team Junior.
+// Copyright (C) 1999-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
diff --git a/src/r_data.h b/src/r_data.h
index a656e5db7..5de51ccd4 100644
--- a/src/r_data.h
+++ b/src/r_data.h
@@ -2,7 +2,7 @@
 //-----------------------------------------------------------------------------
 // Copyright (C) 1993-1996 by id Software, Inc.
 // Copyright (C) 1998-2000 by DooM Legacy Team.
-// Copyright (C) 1999-2016 by Sonic Team Junior.
+// Copyright (C) 1999-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
diff --git a/src/r_defs.h b/src/r_defs.h
index b8c21764e..b936c7e7d 100644
--- a/src/r_defs.h
+++ b/src/r_defs.h
@@ -2,7 +2,7 @@
 //-----------------------------------------------------------------------------
 // Copyright (C) 1993-1996 by id Software, Inc.
 // Copyright (C) 1998-2000 by DooM Legacy Team.
-// Copyright (C) 1999-2016 by Sonic Team Junior.
+// Copyright (C) 1999-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
@@ -574,6 +574,9 @@ typedef struct seg_s
 	sector_t *backsector;
 
 #ifdef HWRENDER
+	// new pointers so that AdjustSegs doesn't mess with v1/v2
+	void *pv1; // polyvertex_t
+	void *pv2; // polyvertex_t
 	float flength; // length of the seg, used by hardware renderer
 
 	lightmap_t *lightmaps; // for static lightmap
diff --git a/src/r_draw.c b/src/r_draw.c
index c7bd077e4..bbc9a79b0 100644
--- a/src/r_draw.c
+++ b/src/r_draw.c
@@ -2,7 +2,7 @@
 //-----------------------------------------------------------------------------
 // Copyright (C) 1993-1996 by id Software, Inc.
 // Copyright (C) 1998-2000 by DooM Legacy Team.
-// Copyright (C) 1999-2016 by Sonic Team Junior.
+// Copyright (C) 1999-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
diff --git a/src/r_draw.h b/src/r_draw.h
index 6d85bd6a5..12f556b7a 100644
--- a/src/r_draw.h
+++ b/src/r_draw.h
@@ -2,7 +2,7 @@
 //-----------------------------------------------------------------------------
 // Copyright (C) 1993-1996 by id Software, Inc.
 // Copyright (C) 1998-2000 by DooM Legacy Team.
-// Copyright (C) 1999-2016 by Sonic Team Junior.
+// Copyright (C) 1999-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
@@ -161,6 +161,7 @@ void R_DrawSplat_8(void);
 void R_DrawTranslucentSplat_8(void);
 void R_DrawTranslucentSpan_8(void);
 void R_Draw2sMultiPatchColumn_8(void);
+void R_Draw2sMultiPatchTranslucentColumn_8(void);
 void R_DrawFogSpan_8(void);
 void R_DrawFogColumn_8(void);
 void R_DrawColumnShadowed_8(void);
diff --git a/src/r_draw16.c b/src/r_draw16.c
index a922f4d0a..918dd356c 100644
--- a/src/r_draw16.c
+++ b/src/r_draw16.c
@@ -1,7 +1,7 @@
 // SONIC ROBO BLAST 2
 //-----------------------------------------------------------------------------
 // Copyright (C) 1998-2000 by DooM Legacy Team.
-// Copyright (C) 1999-2016 by Sonic Team Junior.
+// Copyright (C) 1999-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
diff --git a/src/r_draw8.c b/src/r_draw8.c
index 800f28b6b..886b72dae 100644
--- a/src/r_draw8.c
+++ b/src/r_draw8.c
@@ -1,7 +1,7 @@
 // SONIC ROBO BLAST 2
 //-----------------------------------------------------------------------------
 // Copyright (C) 1998-2000 by DooM Legacy Team.
-// Copyright (C) 1999-2016 by Sonic Team Junior.
+// Copyright (C) 1999-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
@@ -203,6 +203,103 @@ void R_Draw2sMultiPatchColumn_8(void)
 	}
 }
 
+void R_Draw2sMultiPatchTranslucentColumn_8(void)
+{
+	INT32 count;
+	register UINT8 *dest;
+	register fixed_t frac;
+	fixed_t fracstep;
+
+	count = dc_yh - dc_yl;
+
+	if (count < 0) // Zero length, column does not exceed a pixel.
+		return;
+
+#ifdef RANGECHECK
+	if ((unsigned)dc_x >= (unsigned)vid.width || dc_yl < 0 || dc_yh >= vid.height)
+		return;
+#endif
+
+	// Framebuffer destination address.
+	// Use ylookup LUT to avoid multiply with ScreenWidth.
+	// Use columnofs LUT for subwindows?
+
+	//dest = ylookup[dc_yl] + columnofs[dc_x];
+	dest = &topleft[dc_yl*vid.width + dc_x];
+
+	count++;
+
+	// Determine scaling, which is the only mapping to be done.
+	fracstep = dc_iscale;
+	//frac = dc_texturemid + (dc_yl - centery)*fracstep;
+	frac = (dc_texturemid + FixedMul((dc_yl << FRACBITS) - centeryfrac, fracstep))*(!dc_hires);
+
+	// Inner loop that does the actual texture mapping, e.g. a DDA-like scaling.
+	// This is as fast as it gets.
+	{
+		register const UINT8 *source = dc_source;
+		register const UINT8 *transmap = dc_transmap;
+		register const lighttable_t *colormap = dc_colormap;
+		register INT32 heightmask = dc_texheight-1;
+		register UINT8 val;
+		if (dc_texheight & heightmask)   // not a power of 2 -- killough
+		{
+			heightmask++;
+			heightmask <<= FRACBITS;
+
+			if (frac < 0)
+				while ((frac += heightmask) <  0);
+			else
+				while (frac >= heightmask)
+					frac -= heightmask;
+
+			do
+			{
+				// Re-map color indices from wall texture column
+				//  using a lighting/special effects LUT.
+				// heightmask is the Tutti-Frutti fix
+				val = source[frac>>FRACBITS];
+
+				if (val != TRANSPARENTPIXEL)
+					*dest = *(transmap + (colormap[val]<<8) + (*dest));
+
+				dest += vid.width;
+
+				// Avoid overflow.
+				if (fracstep > 0x7FFFFFFF - frac)
+					frac += fracstep - heightmask;
+				else
+					frac += fracstep;
+
+				while (frac >= heightmask)
+					frac -= heightmask;
+			} while (--count);
+		}
+		else
+		{
+			while ((count -= 2) >= 0) // texture height is a power of 2
+			{
+				val = source[(frac>>FRACBITS) & heightmask];
+				if (val != TRANSPARENTPIXEL)
+					*dest = *(transmap + (colormap[val]<<8) + (*dest));
+				dest += vid.width;
+				frac += fracstep;
+				val = source[(frac>>FRACBITS) & heightmask];
+				if (val != TRANSPARENTPIXEL)
+					*dest = *(transmap + (colormap[val]<<8) + (*dest));
+				dest += vid.width;
+				frac += fracstep;
+			}
+			if (count & 1)
+			{
+				val = source[(frac>>FRACBITS) & heightmask];
+				if (val != TRANSPARENTPIXEL)
+					*dest = *(transmap + (colormap[val]<<8) + (*dest));
+			}
+		}
+	}
+}
+
 /**	\brief The R_DrawShadeColumn_8 function
 	Experiment to make software go faster. Taken from the Boom source
 */
diff --git a/src/r_local.h b/src/r_local.h
index a3dfe7df6..1d3187750 100644
--- a/src/r_local.h
+++ b/src/r_local.h
@@ -2,7 +2,7 @@
 //-----------------------------------------------------------------------------
 // Copyright (C) 1993-1996 by id Software, Inc.
 // Copyright (C) 1998-2000 by DooM Legacy Team.
-// Copyright (C) 1999-2016 by Sonic Team Junior.
+// Copyright (C) 1999-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
diff --git a/src/r_main.c b/src/r_main.c
index f2a0c8894..23eff452c 100644
--- a/src/r_main.c
+++ b/src/r_main.c
@@ -2,7 +2,7 @@
 //-----------------------------------------------------------------------------
 // Copyright (C) 1993-1996 by id Software, Inc.
 // Copyright (C) 1998-2000 by DooM Legacy Team.
-// Copyright (C) 1999-2016 by Sonic Team Junior.
+// Copyright (C) 1999-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
@@ -60,7 +60,6 @@ fixed_t projectiony; // aspect ratio
 // just for profiling purposes
 size_t framecount;
 
-size_t sscount;
 size_t loopcount;
 
 fixed_t viewx, viewy, viewz;
@@ -222,21 +221,11 @@ static void ChaseCam2_OnChange(void)
 
 static void FlipCam_OnChange(void)
 {
-	if (cv_flipcam.value)
-		players[consoleplayer].pflags |= PF_FLIPCAM;
-	else
-		players[consoleplayer].pflags &= ~PF_FLIPCAM;
-
 	SendWeaponPref();
 }
 
 static void FlipCam2_OnChange(void)
 {
-	if (cv_flipcam2.value)
-		players[secondarydisplayplayer].pflags |= PF_FLIPCAM;
-	else
-		players[secondarydisplayplayer].pflags &= ~PF_FLIPCAM;
-
 	SendWeaponPref2();
 }
 
@@ -492,9 +481,6 @@ static void R_InitTextureMapping(void)
 	// Take out the fencepost cases from viewangletox.
 	for (i = 0; i < FINEANGLES/2; i++)
 	{
-		t = FixedMul(FINETANGENT(i), focallength);
-		t = centerx - t;
-
 		if (viewangletox[i] == -1)
 			viewangletox[i] = 0;
 		else if (viewangletox[i] == viewwidth+1)
@@ -621,7 +607,7 @@ void R_ExecuteSetViewSize(void)
 	if (rendermode == render_soft)
 	{
 		// this is only used for planes rendering in software mode
-		j = viewheight*4;
+		j = viewheight*8;
 		for (i = 0; i < j; i++)
 		{
 			dy = ((i - viewheight*2)<<FRACBITS) + FRACUNIT/2;
@@ -964,10 +950,9 @@ void R_SkyboxFrame(player_t *player)
 	viewsin = FINESINE(viewangle>>ANGLETOFINESHIFT);
 	viewcos = FINECOSINE(viewangle>>ANGLETOFINESHIFT);
 
-	sscount = 0;
-
 	// recalc necessary stuff for mouseaiming
 	// slopes are already calculated for the full possible view (which is 4*viewheight).
+	// 18/08/18: (No it's actually 8*viewheight, thanks MPC aka Jimita for finding this out)
 
 	if (rendermode == render_soft)
 	{
@@ -1089,10 +1074,9 @@ void R_SetupFrame(player_t *player, boolean skybox)
 	viewsin = FINESINE(viewangle>>ANGLETOFINESHIFT);
 	viewcos = FINECOSINE(viewangle>>ANGLETOFINESHIFT);
 
-	sscount = 0;
-
 	// recalc necessary stuff for mouseaiming
 	// slopes are already calculated for the full possible view (which is 4*viewheight).
+	// 18/08/18: (No it's actually 8*viewheight, thanks MPC aka Jimita for finding this out)
 
 	if (rendermode == render_soft)
 	{
diff --git a/src/r_main.h b/src/r_main.h
index 2e768cb9c..81fa13dea 100644
--- a/src/r_main.h
+++ b/src/r_main.h
@@ -2,7 +2,7 @@
 //-----------------------------------------------------------------------------
 // Copyright (C) 1993-1996 by id Software, Inc.
 // Copyright (C) 1998-2000 by DooM Legacy Team.
-// Copyright (C) 1999-2016 by Sonic Team Junior.
+// Copyright (C) 1999-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
diff --git a/src/r_plane.c b/src/r_plane.c
index 2c4a13290..b09ac4843 100644
--- a/src/r_plane.c
+++ b/src/r_plane.c
@@ -2,7 +2,7 @@
 //-----------------------------------------------------------------------------
 // Copyright (C) 1993-1996 by id Software, Inc.
 // Copyright (C) 1998-2000 by DooM Legacy Team.
-// Copyright (C) 1999-2016 by Sonic Team Junior.
+// Copyright (C) 1999-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
@@ -89,7 +89,7 @@ static fixed_t planeheight;
 //                (this is to calculate yslopes only when really needed)
 //                (when mouselookin', yslope is moving into yslopetab)
 //                Check R_SetupFrame, R_SetViewSize for more...
-fixed_t yslopetab[MAXVIDHEIGHT*4];
+fixed_t yslopetab[MAXVIDHEIGHT*8];
 fixed_t *yslope;
 
 fixed_t distscale[MAXVIDWIDTH];
diff --git a/src/r_plane.h b/src/r_plane.h
index 16c8c12a4..2ab1e83f5 100644
--- a/src/r_plane.h
+++ b/src/r_plane.h
@@ -2,7 +2,7 @@
 //-----------------------------------------------------------------------------
 // Copyright (C) 1993-1996 by id Software, Inc.
 // Copyright (C) 1998-2000 by DooM Legacy Team.
-// Copyright (C) 1999-2016 by Sonic Team Junior.
+// Copyright (C) 1999-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
@@ -75,7 +75,7 @@ extern INT16 *lastopening, *openings;
 extern size_t maxopenings;
 
 extern INT16 floorclip[MAXVIDWIDTH], ceilingclip[MAXVIDWIDTH];
-extern fixed_t frontscale[MAXVIDWIDTH], yslopetab[MAXVIDHEIGHT*4];
+extern fixed_t frontscale[MAXVIDWIDTH], yslopetab[MAXVIDHEIGHT*8];
 extern fixed_t cachedheight[MAXVIDHEIGHT];
 extern fixed_t cacheddistance[MAXVIDHEIGHT];
 extern fixed_t cachedxstep[MAXVIDHEIGHT];
@@ -87,7 +87,7 @@ extern lighttable_t **planezlight;
 extern fixed_t *yslope;
 extern fixed_t distscale[MAXVIDWIDTH];
 
-FUNCMATH void R_InitPlanes(void);
+void R_InitPlanes(void);
 void R_PortalStoreClipValues(INT32 start, INT32 end, INT16 *ceil, INT16 *floor, fixed_t *scale);
 void R_PortalRestoreClipValues(INT32 start, INT32 end, INT16 *ceil, INT16 *floor, fixed_t *scale);
 void R_ClearPlanes(void);
diff --git a/src/r_segs.c b/src/r_segs.c
index 502ff3304..2122cba17 100644
--- a/src/r_segs.c
+++ b/src/r_segs.c
@@ -2,7 +2,7 @@
 //-----------------------------------------------------------------------------
 // Copyright (C) 1993-1996 by id Software, Inc.
 // Copyright (C) 1998-2000 by DooM Legacy Team.
-// Copyright (C) 1999-2016 by Sonic Team Junior.
+// Copyright (C) 1999-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
@@ -271,6 +271,8 @@ static void R_Render2sidedMultiPatchColumn(column_t *column)
 
 		if (colfunc == wallcolfunc)
 			twosmultipatchfunc();
+		else if (colfunc == fuzzcolfunc)
+			twosmultipatchtransfunc();
 		else
 			colfunc();
 	}
@@ -590,8 +592,8 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2)
 						else
 							rlight->rcolormap = xwalllights[pindex];
 
-						rlight->height += rlight->heightstep;
 						height = rlight->height;
+						rlight->height += rlight->heightstep;
 
 						if (height <= windowtop)
 						{
@@ -743,6 +745,12 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
 	// Render FOF sides kinda like normal sides, with the frac and step and everything
 	// NOTE: INT64 instead of fixed_t because overflow concerns
 	INT64         top_frac, top_step, bottom_frac, bottom_step;
+	// skew FOF walls with slopes?
+	boolean	      slopeskew = false;
+	fixed_t       ffloortextureslide = 0;
+	INT32         oldx = -1;
+	fixed_t       left_top, left_bottom; // needed here for slope skewing
+	pslope_t      *skewslope = NULL;
 #endif
 
 	void (*colfunc_2s) (column_t *);
@@ -827,26 +835,21 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
 			light = &frontsector->lightlist[i];
 			rlight = &dc_lightlist[p];
 #ifdef ESLOPE
-			if (light->slope) {
-				leftheight = P_GetZAt(light->slope, ds->leftpos.x, ds->leftpos.y);
-				rightheight = P_GetZAt(light->slope, ds->rightpos.x, ds->rightpos.y);
-			} else
-				leftheight = rightheight = light->height;
 
-			if (*pfloor->b_slope) {
-				pfloorleft = P_GetZAt(*pfloor->b_slope, ds->leftpos.x, ds->leftpos.y);
-				pfloorright = P_GetZAt(*pfloor->b_slope, ds->rightpos.x, ds->rightpos.y);
-			} else
-				pfloorleft = pfloorright = *pfloor->bottomheight;
+#define SLOPEPARAMS(slope, end1, end2, normalheight) \
+	if (slope) { \
+		end1 = P_GetZAt(slope, ds->leftpos.x, ds->leftpos.y); \
+		end2 = P_GetZAt(slope, ds->rightpos.x, ds->rightpos.y); \
+	} else \
+		end1 = end2 = normalheight;
+
+			SLOPEPARAMS(light->slope,     leftheight, rightheight, light->height)
+			SLOPEPARAMS(*pfloor->b_slope, pfloorleft, pfloorright, *pfloor->bottomheight)
 
 			if (leftheight < pfloorleft && rightheight < pfloorright)
 				continue;
 
-			if (*pfloor->t_slope) {
-				pfloorleft = P_GetZAt(*pfloor->t_slope, ds->leftpos.x, ds->leftpos.y);
-				pfloorright = P_GetZAt(*pfloor->t_slope, ds->rightpos.x, ds->rightpos.y);
-			} else
-				pfloorleft = pfloorright = *pfloor->topheight;
+			SLOPEPARAMS(*pfloor->t_slope, pfloorleft, pfloorright, *pfloor->topheight)
 
 			if (leftheight > pfloorleft && rightheight > pfloorright && i+1 < dc_numlights)
 			{
@@ -859,17 +862,17 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
 			leftheight -= viewz;
 			rightheight -= viewz;
 
-			overflow_test = (INT64)centeryfrac - (((INT64)leftheight*ds->scale1)>>FRACBITS);
-			if (overflow_test < 0) overflow_test = -overflow_test;
-			if ((UINT64)overflow_test&0xFFFFFFFF80000000ULL) continue;
-			overflow_test = (INT64)centeryfrac - (((INT64)rightheight*ds->scale2)>>FRACBITS);
-			if (overflow_test < 0) overflow_test = -overflow_test;
-			if ((UINT64)overflow_test&0xFFFFFFFF80000000ULL) continue;
+#define OVERFLOWTEST(height, scale) \
+	overflow_test = (INT64)centeryfrac - (((INT64)height*scale)>>FRACBITS); \
+	if (overflow_test < 0) overflow_test = -overflow_test; \
+	if ((UINT64)overflow_test&0xFFFFFFFF80000000ULL) continue;
+
+			OVERFLOWTEST(leftheight, ds->scale1)
+			OVERFLOWTEST(rightheight, ds->scale2)
 
 			rlight->height = (centeryfrac) - FixedMul(leftheight, ds->scale1);
 			rlight->heightstep = (centeryfrac) - FixedMul(rightheight, ds->scale2);
 			rlight->heightstep = (rlight->heightstep-rlight->height)/(range);
-			rlight->height -= rlight->heightstep;
 #else
 			if (light->height < *pfloor->bottomheight)
 				continue;
@@ -879,36 +882,28 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
 
 			lheight = light->height;// > *pfloor->topheight ? *pfloor->topheight + FRACUNIT : light->height;
 			rlight->heightstep = -FixedMul (rw_scalestep, (lheight - viewz));
-			rlight->height = (centeryfrac) - FixedMul((lheight - viewz), spryscale) - rlight->heightstep;
+			rlight->height = (centeryfrac) - FixedMul((lheight - viewz), spryscale);
 #endif
 			rlight->flags = light->flags;
 			if (light->flags & FF_CUTLEVEL)
 			{
 #ifdef ESLOPE
-				if (*light->caster->b_slope) {
-					leftheight = P_GetZAt(*light->caster->b_slope, ds->leftpos.x, ds->leftpos.y);
-					rightheight = P_GetZAt(*light->caster->b_slope, ds->rightpos.x, ds->rightpos.y);
-				} else
-					leftheight = rightheight = *light->caster->bottomheight;
-
+				SLOPEPARAMS(*light->caster->b_slope, leftheight, rightheight, *light->caster->bottomheight)
+#undef SLOPEPARAMS
 				leftheight -= viewz;
 				rightheight -= viewz;
 
-				overflow_test = (INT64)centeryfrac - (((INT64)leftheight*ds->scale1)>>FRACBITS);
-				if (overflow_test < 0) overflow_test = -overflow_test;
-				if ((UINT64)overflow_test&0xFFFFFFFF80000000ULL) continue;
-				overflow_test = (INT64)centeryfrac - (((INT64)rightheight*ds->scale2)>>FRACBITS);
-				if (overflow_test < 0) overflow_test = -overflow_test;
-				if ((UINT64)overflow_test&0xFFFFFFFF80000000ULL) continue;
+				OVERFLOWTEST(leftheight, ds->scale1)
+				OVERFLOWTEST(rightheight, ds->scale2)
+#undef OVERFLOWTEST
 
 				rlight->botheight = (centeryfrac) - FixedMul(leftheight, ds->scale1);
 				rlight->botheightstep = (centeryfrac) - FixedMul(rightheight, ds->scale2);
 				rlight->botheightstep = (rlight->botheightstep-rlight->botheight)/(range);
-				rlight->botheight -= rlight->botheightstep;
 #else
 				lheight = *light->caster->bottomheight;// > *pfloor->topheight ? *pfloor->topheight + FRACUNIT : *light->caster->bottomheight;
 				rlight->botheightstep = -FixedMul (rw_scalestep, (lheight - viewz));
-				rlight->botheight = (centeryfrac) - FixedMul((lheight - viewz), spryscale) - rlight->botheightstep;
+				rlight->botheight = (centeryfrac) - FixedMul((lheight - viewz), spryscale);
 #endif
 			}
 
@@ -966,21 +961,71 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
 	mceilingclip = ds->sprtopclip;
 	dc_texheight = textureheight[texnum]>>FRACBITS;
 
+#ifdef ESLOPE
+	// calculate both left ends
+	if (*pfloor->t_slope)
+		left_top = P_GetZAt(*pfloor->t_slope, ds->leftpos.x, ds->leftpos.y) - viewz;
+	else
+		left_top = *pfloor->topheight - viewz;
+
+	if (*pfloor->b_slope)
+		left_bottom = P_GetZAt(*pfloor->b_slope, ds->leftpos.x, ds->leftpos.y) - viewz;
+	else
+		left_bottom = *pfloor->bottomheight - viewz;
+	skewslope = *pfloor->t_slope; // skew using top slope by default
+	if (newline)
+	{
+		if (newline->flags & ML_DONTPEGTOP)
+			slopeskew = true;
+	}
+	else if (pfloor->master->flags & ML_DONTPEGTOP)
+		slopeskew = true;
+
+	if (slopeskew)
+		dc_texturemid = left_top;
+	else
+#endif
 	dc_texturemid = *pfloor->topheight - viewz;
 
 	if (newline)
 	{
 		offsetvalue = sides[newline->sidenum[0]].rowoffset;
 		if (newline->flags & ML_DONTPEGBOTTOM)
+		{
+#ifdef ESLOPE
+			skewslope = *pfloor->b_slope; // skew using bottom slope
+			if (slopeskew)
+				dc_texturemid = left_bottom;
+			else
+#endif
 			offsetvalue -= *pfloor->topheight - *pfloor->bottomheight;
+		}
 	}
 	else
 	{
 		offsetvalue = sides[pfloor->master->sidenum[0]].rowoffset;
 		if (curline->linedef->flags & ML_DONTPEGBOTTOM)
+		{
+#ifdef ESLOPE
+			skewslope = *pfloor->b_slope; // skew using bottom slope
+			if (slopeskew)
+				dc_texturemid = left_bottom;
+			else
+#endif
 			offsetvalue -= *pfloor->topheight - *pfloor->bottomheight;
+		}
 	}
 
+#ifdef ESLOPE
+	if (slopeskew)
+	{
+		angle_t lineangle = R_PointToAngle2(curline->v1->x, curline->v1->y, curline->v2->x, curline->v2->y);
+
+		if (skewslope)
+			ffloortextureslide = FixedMul(skewslope->zdelta, FINECOSINE((lineangle-skewslope->xydirection)>>ANGLETOFINESHIFT));
+	}
+#endif
+
 	dc_texturemid += offsetvalue;
 
 	// Texture must be cached before setting colfunc_2s,
@@ -999,23 +1044,18 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
 #ifdef ESLOPE
 	// Set heights according to plane, or slope, whichever
 	{
-		fixed_t left_top, right_top, left_bottom, right_bottom;
+		fixed_t right_top, right_bottom;
 
+		// calculate right ends now
 		if (*pfloor->t_slope)
-		{
-			left_top = P_GetZAt(*pfloor->t_slope, ds->leftpos.x, ds->leftpos.y) - viewz;
 			right_top = P_GetZAt(*pfloor->t_slope, ds->rightpos.x, ds->rightpos.y) - viewz;
-		}
 		else
-			left_top = right_top = *pfloor->topheight - viewz;
+			right_top = *pfloor->topheight - viewz;
 
 		if (*pfloor->b_slope)
-		{
-			left_bottom = P_GetZAt(*pfloor->b_slope, ds->leftpos.x, ds->leftpos.y) - viewz;
 			right_bottom = P_GetZAt(*pfloor->b_slope, ds->rightpos.x, ds->rightpos.y) - viewz;
-		}
 		else
-			left_bottom = right_bottom = *pfloor->bottomheight - viewz;
+			right_bottom = *pfloor->bottomheight - viewz;
 
 		// using INT64 to avoid 32bit overflow
 		top_frac =    (INT64)centeryfrac - (((INT64)left_top     * ds->scale1) >> FRACBITS);
@@ -1039,6 +1079,53 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
 	{
 		if (maskedtexturecol[dc_x] != INT16_MAX)
 		{
+#ifdef ESLOPE
+			if (ffloortextureslide) { // skew FOF walls
+				if (oldx != -1)
+					dc_texturemid += FixedMul(ffloortextureslide, (maskedtexturecol[oldx]-maskedtexturecol[dc_x])<<FRACBITS);
+				oldx = dc_x;
+			}
+#endif
+			// Calculate bounds
+			// clamp the values if necessary to avoid overflows and rendering glitches caused by them
+
+#ifdef ESLOPE
+			if      (top_frac > (INT64)CLAMPMAX) sprtopscreen = windowtop = CLAMPMAX;
+			else if (top_frac > (INT64)CLAMPMIN) sprtopscreen = windowtop = (fixed_t)top_frac;
+			else                                 sprtopscreen = windowtop = CLAMPMIN;
+			if      (bottom_frac > (INT64)CLAMPMAX) sprbotscreen = windowbottom = CLAMPMAX;
+			else if (bottom_frac > (INT64)CLAMPMIN) sprbotscreen = windowbottom = (fixed_t)bottom_frac;
+			else                                    sprbotscreen = windowbottom = CLAMPMIN;
+
+			top_frac += top_step;
+			bottom_frac += bottom_step;
+#else
+			sprtopscreen = windowtop = (centeryfrac - FixedMul((dc_texturemid - offsetvalue), spryscale));
+			sprbotscreen = windowbottom = FixedMul(*pfloor->topheight - *pfloor->bottomheight, spryscale) + sprtopscreen;
+#endif
+
+			// SoM: If column is out of range, why bother with it??
+			if (windowbottom < topbounds || windowtop > bottombounds)
+			{
+				if (dc_numlights)
+				{
+					for (i = 0; i < dc_numlights; i++)
+					{
+						rlight = &dc_lightlist[i];
+						rlight->height += rlight->heightstep;
+						if (rlight->flags & FF_CUTLEVEL)
+							rlight->botheight += rlight->botheightstep;
+					}
+				}
+				spryscale += rw_scalestep;
+				continue;
+			}
+
+			dc_iscale = 0xffffffffu / (unsigned)spryscale;
+
+			// Get data for the column
+			col = (column_t *)((UINT8 *)R_GetColumn(texnum,maskedtexturecol[dc_x]) - 3);
+
 			// SoM: New code does not rely on R_DrawColumnShadowed_8 which
 			// will (hopefully) put less strain on the stack.
 			if (dc_numlights)
@@ -1049,40 +1136,6 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
 				INT32 solid = 0;
 				INT32 lighteffect = 0;
 
-#ifdef ESLOPE
-				if      (top_frac > (INT64)CLAMPMAX) sprtopscreen = windowtop = CLAMPMAX;
-				else if (top_frac > (INT64)CLAMPMIN) sprtopscreen = windowtop = (fixed_t)top_frac;
-				else                                 sprtopscreen = windowtop = CLAMPMIN;
-				if      (bottom_frac > (INT64)CLAMPMAX) sprbotscreen = windowbottom = CLAMPMAX;
-				else if (bottom_frac > (INT64)CLAMPMIN) sprbotscreen = windowbottom = (fixed_t)bottom_frac;
-				else                                    sprbotscreen = windowbottom = CLAMPMIN;
-
-				top_frac += top_step;
-				bottom_frac += bottom_step;
-#else
-				sprtopscreen = windowtop = (centeryfrac - FixedMul((dc_texturemid - offsetvalue), spryscale));
-				sprbotscreen = windowbottom = FixedMul(*pfloor->topheight - *pfloor->bottomheight, spryscale) + sprtopscreen;
-#endif
-
-				// SoM: If column is out of range, why bother with it??
-				if (windowbottom < topbounds || windowtop > bottombounds)
-				{
-					for (i = 0; i < dc_numlights; i++)
-					{
-						rlight = &dc_lightlist[i];
-						rlight->height += rlight->heightstep;
-						if (rlight->flags & FF_CUTLEVEL)
-							rlight->botheight += rlight->botheightstep;
-					}
-					spryscale += rw_scalestep;
-					continue;
-				}
-
-				dc_iscale = 0xffffffffu / (unsigned)spryscale;
-
-				// draw the texture
-				col = (column_t *)((UINT8 *)R_GetColumn(texnum,maskedtexturecol[dc_x]) - 3);
-
 				for (i = 0; i < dc_numlights; i++)
 				{
 					// Check if the current light effects the colormap/lightlevel
@@ -1101,7 +1154,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
 
 						pindex = FixedMul(spryscale, FixedDiv(640, vid.width))>>LIGHTSCALESHIFT;
 
-						if (pindex >=  MAXLIGHTSCALE)
+						if (pindex >= MAXLIGHTSCALE)
 							pindex = MAXLIGHTSCALE-1;
 
 						if (pfloor->flags & FF_FOG)
@@ -1140,13 +1193,13 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
 					else
 						solid = 0;
 
-					rlight->height += rlight->heightstep;
 					height = rlight->height;
+					rlight->height += rlight->heightstep;
 
 					if (solid)
 					{
-						rlight->botheight += rlight->botheightstep;
 						bheight = rlight->botheight - (FRACUNIT >> 1);
+						rlight->botheight += rlight->botheightstep;
 					}
 
 					if (height <= windowtop)
@@ -1162,6 +1215,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
 					if (windowbottom >= sprbotscreen)
 					{
 						windowbottom = sprbotscreen;
+						// draw the texture
 						colfunc_2s (col);
 						for (i++; i < dc_numlights; i++)
 						{
@@ -1172,6 +1226,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
 						}
 						continue;
 					}
+					// draw the texture
 					colfunc_2s (col);
 					if (solid)
 						windowtop = bheight;
@@ -1181,6 +1236,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
 						dc_colormap = rlight->rcolormap;
 				}
 				windowbottom = sprbotscreen;
+				// draw the texture, if there is any space left
 				if (windowtop < windowbottom)
 					colfunc_2s (col);
 
@@ -1195,31 +1251,13 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
 				pindex = MAXLIGHTSCALE - 1;
 
 			dc_colormap = walllights[pindex];
-			if (frontsector->extra_colormap)
-				dc_colormap = frontsector->extra_colormap->colormap + (dc_colormap - colormaps);
+
 			if (pfloor->flags & FF_FOG && pfloor->master->frontsector->extra_colormap)
 				dc_colormap = pfloor->master->frontsector->extra_colormap->colormap + (dc_colormap - colormaps);
-
-#ifdef ESLOPE
-			if      (top_frac > (INT64)CLAMPMAX) sprtopscreen = windowtop = CLAMPMAX;
-			else if (top_frac > (INT64)CLAMPMIN) sprtopscreen = windowtop = (fixed_t)top_frac;
-			else                                 sprtopscreen = windowtop = CLAMPMIN;
-			if      (bottom_frac > (INT64)CLAMPMAX) sprbotscreen = windowbottom = CLAMPMAX;
-			else if (bottom_frac > (INT64)CLAMPMIN) sprbotscreen = windowbottom = (fixed_t)bottom_frac;
-			else                                    sprbotscreen = windowbottom = CLAMPMIN;
-
-			top_frac += top_step;
-			bottom_frac += bottom_step;
-#else
-			sprtopscreen = windowtop = (centeryfrac - FixedMul((dc_texturemid - offsetvalue), spryscale));
-			sprbotscreen = windowbottom = FixedMul(*pfloor->topheight - *pfloor->bottomheight, spryscale) + sprtopscreen;
-#endif
-
-			dc_iscale = 0xffffffffu / (unsigned)spryscale;
+			else if (frontsector->extra_colormap)
+				dc_colormap = frontsector->extra_colormap->colormap + (dc_colormap - colormaps);
 
 			// draw the texture
-			col = (column_t *)((UINT8 *)R_GetColumn(texnum,maskedtexturecol[dc_x]) - 3);
-
 			colfunc_2s (col);
 			spryscale += rw_scalestep;
 		}
diff --git a/src/r_segs.h b/src/r_segs.h
index 4187d36e0..92d0100e2 100644
--- a/src/r_segs.h
+++ b/src/r_segs.h
@@ -2,7 +2,7 @@
 //-----------------------------------------------------------------------------
 // Copyright (C) 1993-1996 by id Software, Inc.
 // Copyright (C) 1998-2000 by DooM Legacy Team.
-// Copyright (C) 1999-2016 by Sonic Team Junior.
+// Copyright (C) 1999-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
diff --git a/src/r_sky.c b/src/r_sky.c
index 5162518cb..2df6e4cd8 100644
--- a/src/r_sky.c
+++ b/src/r_sky.c
@@ -2,7 +2,7 @@
 //-----------------------------------------------------------------------------
 // Copyright (C) 1993-1996 by id Software, Inc.
 // Copyright (C) 1998-2000 by DooM Legacy Team.
-// Copyright (C) 1999-2016 by Sonic Team Junior.
+// Copyright (C) 1999-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
diff --git a/src/r_sky.h b/src/r_sky.h
index aa4bda375..86b615595 100644
--- a/src/r_sky.h
+++ b/src/r_sky.h
@@ -2,7 +2,7 @@
 //-----------------------------------------------------------------------------
 // Copyright (C) 1993-1996 by id Software, Inc.
 // Copyright (C) 1998-2000 by DooM Legacy Team.
-// Copyright (C) 1999-2016 by Sonic Team Junior.
+// Copyright (C) 1999-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
diff --git a/src/r_splats.c b/src/r_splats.c
index f6d7e78f3..8d0a84fa4 100644
--- a/src/r_splats.c
+++ b/src/r_splats.c
@@ -1,7 +1,7 @@
 // SONIC ROBO BLAST 2
 //-----------------------------------------------------------------------------
 // Copyright (C) 1998-2000 by DooM Legacy Team.
-// Copyright (C) 1999-2016 by Sonic Team Junior.
+// Copyright (C) 1999-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
diff --git a/src/r_splats.h b/src/r_splats.h
index c0ba6881c..387b29582 100644
--- a/src/r_splats.h
+++ b/src/r_splats.h
@@ -1,7 +1,7 @@
 // SONIC ROBO BLAST 2
 //-----------------------------------------------------------------------------
 // Copyright (C) 1998-2000 by DooM Legacy Team.
-// Copyright (C) 1999-2016 by Sonic Team Junior.
+// Copyright (C) 1999-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
@@ -63,11 +63,7 @@ typedef struct floorsplat_s
 fixed_t P_SegLength(seg_t *seg);
 
 // call at P_SetupLevel()
-#if !(defined (WALLSPLATS) || defined (FLOORSPLATS))
-FUNCMATH void R_ClearLevelSplats(void);
-#else
 void R_ClearLevelSplats(void);
-#endif
 
 #ifdef WALLSPLATS
 void R_AddWallSplat(line_t *wallline, INT16 sectorside, const char *patchname, fixed_t top,
diff --git a/src/r_state.h b/src/r_state.h
index 49d0457b2..3675d7f2e 100644
--- a/src/r_state.h
+++ b/src/r_state.h
@@ -2,7 +2,7 @@
 //-----------------------------------------------------------------------------
 // Copyright (C) 1993-1996 by id Software, Inc.
 // Copyright (C) 1998-2000 by DooM Legacy Team.
-// Copyright (C) 1999-2016 by Sonic Team Junior.
+// Copyright (C) 1999-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
@@ -108,7 +108,4 @@ extern angle_t rw_normalangle;
 // angle to line origin
 extern angle_t rw_angle1;
 
-// Segs count?
-extern size_t sscount;
-
 #endif
diff --git a/src/r_things.c b/src/r_things.c
index 0b1764167..734179f66 100644
--- a/src/r_things.c
+++ b/src/r_things.c
@@ -2,7 +2,7 @@
 //-----------------------------------------------------------------------------
 // Copyright (C) 1993-1996 by id Software, Inc.
 // Copyright (C) 1998-2000 by DooM Legacy Team.
-// Copyright (C) 1999-2016 by Sonic Team Junior.
+// Copyright (C) 1999-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
@@ -1451,6 +1451,17 @@ static void R_ProjectPrecipitationSprite(precipmobj_t *thing)
 			return;
 	}
 
+	// okay, we can't return now except for vertical clipping... this is a hack, but weather isn't networked, so it should be ok
+	if (!(thing->precipflags & PCF_THUNK))
+	{
+		if (thing->precipflags & PCF_RAIN)
+			P_RainThinker(thing);
+		else
+			P_SnowThinker(thing);
+		thing->precipflags |= PCF_THUNK;
+	}
+
+
 	//SoM: 3/17/2000: Disregard sprites that are out of view..
 	gzt = thing->z + spritecachedinfo[lump].topoffset;
 	gz = gzt - spritecachedinfo[lump].height;
@@ -1569,8 +1580,10 @@ void R_AddSprites(sector_t *sec, INT32 lightlevel)
 
 			approx_dist = P_AproxDistance(viewx-thing->x, viewy-thing->y);
 
-			if (approx_dist <= limit_dist)
-				R_ProjectSprite(thing);
+			if (approx_dist > limit_dist)
+				continue;
+
+			R_ProjectSprite(thing);
 		}
 	}
 	else
@@ -1591,8 +1604,10 @@ void R_AddSprites(sector_t *sec, INT32 lightlevel)
 
 			approx_dist = P_AproxDistance(viewx-precipthing->x, viewy-precipthing->y);
 
-			if (approx_dist <= limit_dist)
-				R_ProjectPrecipitationSprite(precipthing);
+			if (approx_dist > limit_dist)
+				continue;
+
+			R_ProjectPrecipitationSprite(precipthing);
 		}
 	}
 	else
@@ -2308,7 +2323,7 @@ static void Sk_SetDefaultValue(skin_t *skin)
 
 	strcpy(skin->realname, "Someone");
 	strcpy(skin->hudname, "???");
-	strncpy(skin->charsel, "CHRSONIC", 8);
+	strncpy(skin->charsel, "CHRSONIC", 9);
 	strncpy(skin->face, "MISSING", 8);
 	strncpy(skin->superface, "MISSING", 8);
 
@@ -2369,9 +2384,9 @@ void R_InitSkins(void)
 	strcpy(skin->realname,   "Sonic");
 	strcpy(skin->hudname,    "SONIC");
 
-	strncpy(skin->charsel,   "CHRSONIC", 8);
-	strncpy(skin->face,      "LIVSONIC", 8);
-	strncpy(skin->superface, "LIVSUPER", 8);
+	strncpy(skin->charsel,   "CHRSONIC", 9);
+	strncpy(skin->face,      "LIVSONIC", 9);
+	strncpy(skin->superface, "LIVSUPER", 9);
 	skin->prefcolor = SKINCOLOR_BLUE;
 
 	skin->ability =   CA_THOK;
diff --git a/src/r_things.h b/src/r_things.h
index 483db7e99..e4a5f4260 100644
--- a/src/r_things.h
+++ b/src/r_things.h
@@ -2,7 +2,7 @@
 //-----------------------------------------------------------------------------
 // Copyright (C) 1993-1996 by id Software, Inc.
 // Copyright (C) 1998-2000 by DooM Legacy Team.
-// Copyright (C) 1999-2016 by Sonic Team Junior.
+// Copyright (C) 1999-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
@@ -75,7 +75,7 @@ typedef struct
 
 	char realname[SKINNAMESIZE+1]; // Display name for level completion.
 	char hudname[SKINNAMESIZE+1]; // HUD name to display (officially exactly 5 characters long)
-	char charsel[8], face[8], superface[8]; // Arbitrarily named patch lumps
+	char charsel[9], face[9], superface[9]; // Arbitrarily named patch lumps
 
 	UINT8 ability; // ability definition
 	UINT8 ability2; // secondary ability definition
diff --git a/src/s_sound.c b/src/s_sound.c
index 76ee4c649..0961a4427 100644
--- a/src/s_sound.c
+++ b/src/s_sound.c
@@ -2,7 +2,7 @@
 //-----------------------------------------------------------------------------
 // Copyright (C) 1993-1996 by id Software, Inc.
 // Copyright (C) 1998-2000 by DooM Legacy Team.
-// Copyright (C) 1999-2016 by Sonic Team Junior.
+// Copyright (C) 1999-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
@@ -36,6 +36,7 @@ extern INT32 msg_id;
 #include "d_main.h"
 #include "r_sky.h" // skyflatnum
 #include "p_local.h" // camera info
+#include "m_misc.h" // for tunes command
 
 #ifdef HW3SOUND
 // 3D Sound Interface
@@ -46,6 +47,13 @@ static INT32 S_AdjustSoundParams(const mobj_t *listener, const mobj_t *source, I
 
 CV_PossibleValue_t soundvolume_cons_t[] = {{0, "MIN"}, {31, "MAX"}, {0, NULL}};
 static void SetChannelsNum(void);
+static void Command_Tunes_f(void);
+static void Command_RestartAudio_f(void);
+
+// Sound system toggles
+static void GameMIDIMusic_OnChange(void);
+static void GameSounds_OnChange(void);
+static void GameDigiMusic_OnChange(void);
 
 // commands for music and sound servers
 #ifdef MUSSERV
@@ -89,6 +97,12 @@ consvar_t cv_numChannels = {"snd_channels", "32", CV_SAVE|CV_CALL, CV_Unsigned,
 #endif
 
 static consvar_t surround = {"surround", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
+consvar_t cv_resetmusic = {"resetmusic", "No", CV_SAVE, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL};
+
+// Sound system toggles, saved into the config
+consvar_t cv_gamedigimusic = {"digimusic", "On", CV_SAVE|CV_CALL|CV_NOINIT, CV_OnOff, GameDigiMusic_OnChange, 0, NULL, NULL, 0, 0, NULL};
+consvar_t cv_gamemidimusic = {"midimusic", "On", CV_SAVE|CV_CALL|CV_NOINIT, CV_OnOff, GameMIDIMusic_OnChange, 0, NULL, NULL, 0, 0, NULL};
+consvar_t cv_gamesounds = {"sounds", "On", CV_SAVE|CV_CALL|CV_NOINIT, CV_OnOff, GameSounds_OnChange, 0, NULL, NULL, 0, 0, NULL};
 
 #define S_MAX_VOLUME 127
 
@@ -226,7 +240,7 @@ void S_RegisterSoundStuff(void)
 {
 	if (dedicated)
 	{
-		nosound = true;
+		sound_disabled = true;
 		return;
 	}
 
@@ -243,6 +257,14 @@ void S_RegisterSoundStuff(void)
 #endif
 	CV_RegisterVar(&surround);
 	CV_RegisterVar(&cv_samplerate);
+	CV_RegisterVar(&cv_resetmusic);
+	CV_RegisterVar(&cv_gamesounds);
+	CV_RegisterVar(&cv_gamedigimusic);
+	CV_RegisterVar(&cv_gamemidimusic);
+
+	COM_AddCommand("tunes", Command_Tunes_f);
+	COM_AddCommand("restartaudio", Command_RestartAudio_f);
+
 
 #if defined (macintosh) && !defined (HAVE_SDL) // mp3 playlist stuff
 	{
@@ -400,7 +422,7 @@ void S_StartSoundAtVolume(const void *origin_p, sfxenum_t sfx_id, INT32 volume)
 	mobj_t *listenmobj = players[displayplayer].mo;
 	mobj_t *listenmobj2 = NULL;
 
-	if (sound_disabled || !sound_started || nosound)
+	if (sound_disabled || !sound_started)
 		return;
 
 	// Don't want a sound? Okay then...
@@ -529,7 +551,7 @@ void S_StartSoundAtVolume(const void *origin_p, sfxenum_t sfx_id, INT32 volume)
 
 		// Assigns the handle to one of the channels in the
 		// mix/output buffer.
-		channels[cnum].handle = I_StartSound(sfx_id, volume, sep, pitch, priority);
+		channels[cnum].handle = I_StartSound(sfx_id, volume, sep, pitch, priority, cnum);
 	}
 
 dontplay:
@@ -579,7 +601,7 @@ dontplay:
 
 	// Assigns the handle to one of the channels in the
 	// mix/output buffer.
-	channels[cnum].handle = I_StartSound(sfx_id, volume, sep, pitch, priority);
+	channels[cnum].handle = I_StartSound(sfx_id, volume, sep, pitch, priority, cnum);
 }
 
 void S_StartSound(const void *origin, sfxenum_t sfx_id)
@@ -716,7 +738,7 @@ void S_UpdateSounds(void)
 		return;
 	}
 
-	if (dedicated || nosound)
+	if (dedicated || sound_disabled)
 		return;
 
 	if (players[displayplayer].awayviewtics)
@@ -1151,6 +1173,43 @@ void S_StartSoundName(void *mo, const char *soundname)
 	S_StartSound(mo, soundnum);
 }
 
+//
+// Initializes sound stuff, including volume
+// Sets channels, SFX volume,
+//  allocates channel buffer, sets S_sfx lookup.
+//
+void S_InitSfxChannels(INT32 sfxVolume)
+{
+	INT32 i;
+
+	if (dedicated)
+		return;
+
+	S_SetSfxVolume(sfxVolume);
+
+	SetChannelsNum();
+
+	// Note that sounds have not been cached (yet).
+	for (i = 1; i < NUMSFX; i++)
+	{
+		S_sfx[i].usefulness = -1; // for I_GetSfx()
+		S_sfx[i].lumpnum = LUMPERROR;
+	}
+
+	// precache sounds if requested by cmdline, or precachesound var true
+	if (!sound_disabled && (M_CheckParm("-precachesound") || precachesound.value))
+	{
+		// Initialize external data (all sounds) at start, keep static.
+		CONS_Printf(M_GetText("Loading sounds... "));
+
+		for (i = 1; i < NUMSFX; i++)
+			if (S_sfx[i].name)
+				S_sfx[i].data = I_GetSfx(&S_sfx[i]);
+
+		CONS_Printf(M_GetText(" pre-cached all sound data\n"));
+	}
+}
+
 /// ------------------------
 /// Music
 /// ------------------------
@@ -1177,31 +1236,109 @@ const char *compat_special_music_slots[16] =
 };
 #endif
 
-#define music_playing (music_name[0]) // String is empty if no music is playing
-
 static char      music_name[7]; // up to 6-character name
-static lumpnum_t music_lumpnum; // lump number of music (used??)
-static void     *music_data;    // music raw data
-static INT32     music_handle;  // once registered, the handle for the music
+static void      *music_data;
+static UINT16    music_flags;
+static boolean   music_looping;
 
-static boolean mus_paused     = 0;  // whether songs are mus_paused
+/// ------------------------
+/// Music Status
+/// ------------------------
 
-static boolean S_MIDIMusic(const char *mname, boolean looping)
+boolean S_DigMusicDisabled(void)
+{
+	return digital_disabled;
+}
+
+boolean S_MIDIMusicDisabled(void)
+{
+	return midi_disabled;
+}
+
+boolean S_MusicDisabled(void)
+{
+	return (midi_disabled && digital_disabled);
+}
+
+boolean S_MusicPlaying(void)
+{
+	return I_SongPlaying();
+}
+
+boolean S_MusicPaused(void)
+{
+	return I_SongPaused();
+}
+
+musictype_t S_MusicType(void)
+{
+	return I_SongType();
+}
+
+boolean S_MusicInfo(char *mname, UINT16 *mflags, boolean *looping)
+{
+	if (!I_SongPlaying())
+		return false;
+
+	strncpy(mname, music_name, 7);
+	mname[6] = 0;
+	*mflags = music_flags;
+	*looping = music_looping;
+
+	return (boolean)mname[0];
+}
+
+boolean S_MusicExists(const char *mname, boolean checkMIDI, boolean checkDigi)
+{
+	return (
+		(checkDigi ? W_CheckNumForName(va("O_%s", mname)) != LUMPERROR : false)
+		|| (checkMIDI ? W_CheckNumForName(va("D_%s", mname)) != LUMPERROR : false)
+	);
+}
+
+/// ------------------------
+/// Music Effects
+/// ------------------------
+
+boolean S_SpeedMusic(float speed)
+{
+	return I_SetSongSpeed(speed);
+}
+
+/// ------------------------
+/// Music Playback
+/// ------------------------
+
+static boolean S_LoadMusic(const char *mname)
 {
 	lumpnum_t mlumpnum;
 	void *mdata;
-	INT32 mhandle;
 
-	if (nomidimusic || music_disabled)
-		return false; // didn't search.
-
-	if (W_CheckNumForName(va("d_%s", mname)) == LUMPERROR)
+	if (S_MusicDisabled())
 		return false;
-	mlumpnum = W_GetNumForName(va("d_%s", mname));
+
+	if (!S_DigMusicDisabled() && S_DigExists(mname))
+		mlumpnum = W_GetNumForName(va("o_%s", mname));
+	else if (!S_MIDIMusicDisabled() && S_MIDIExists(mname))
+		mlumpnum = W_GetNumForName(va("d_%s", mname));
+	else if (S_DigMusicDisabled() && S_DigExists(mname))
+	{
+		CONS_Alert(CONS_NOTICE, "Digital music is disabled!\n");
+		return false;
+	}
+	else if (S_MIDIMusicDisabled() && S_MIDIExists(mname))
+	{
+		CONS_Alert(CONS_NOTICE, "MIDI music is disabled!\n");
+		return false;
+	}
+	else
+	{
+		CONS_Alert(CONS_ERROR, M_GetText("Music lump %.6s not found!\n"), mname);
+		return false;
+	}
 
 	// load & register it
 	mdata = W_CacheLumpNum(mlumpnum, PU_MUSIC);
-	mhandle = I_RegisterSong(mdata, W_LumpLength(mlumpnum));
 
 #ifdef MUSSERV
 	if (msg_id != -1)
@@ -1215,31 +1352,43 @@ static boolean S_MIDIMusic(const char *mname, boolean looping)
 	}
 #endif
 
-	// play it
-	if (!I_PlaySong(mhandle, looping))
+	if (I_LoadSong(mdata, W_LumpLength(mlumpnum)))
+	{
+		strncpy(music_name, mname, 7);
+		music_name[6] = 0;
+		music_data = mdata;
+		return true;
+	}
+	else
 		return false;
-
-	strncpy(music_name, mname, 7);
-	music_name[6] = 0;
-	music_lumpnum = mlumpnum;
-	music_data = mdata;
-	music_handle = mhandle;
-	return true;
 }
 
-static boolean S_DigMusic(const char *mname, boolean looping)
+static void S_UnloadMusic(void)
 {
-	if (nodigimusic || digital_disabled)
-		return false; // try midi
+	I_UnloadSong();
 
-	if (!I_StartDigSong(mname, looping))
+#ifndef HAVE_SDL //SDL uses RWOPS
+	Z_ChangeTag(music_data, PU_CACHE);
+#endif
+	music_data = NULL;
+
+	music_name[0] = 0;
+	music_flags = 0;
+	music_looping = false;
+}
+
+static boolean S_PlayMusic(boolean looping)
+{
+	if (S_MusicDisabled())
 		return false;
 
-	strncpy(music_name, mname, 7);
-	music_name[6] = 0;
-	music_lumpnum = LUMPERROR;
-	music_data = NULL;
-	music_handle = 0;
+	if (!I_PlaySong(looping))
+	{
+		S_UnloadMusic();
+		return false;
+	}
+
+	S_InitMusicVolume(); // switch between digi and sequence volume
 	return true;
 }
 
@@ -1249,7 +1398,7 @@ void S_ChangeMusic(const char *mmusic, UINT16 mflags, boolean looping)
 	S_ClearSfx();
 #endif
 
-	if ((nomidimusic || music_disabled) && (nodigimusic || digital_disabled))
+	if (S_MusicDisabled())
 		return;
 
 	// No Music (empty string)
@@ -1259,121 +1408,105 @@ void S_ChangeMusic(const char *mmusic, UINT16 mflags, boolean looping)
 		return;
 	}
 
-	if (strncmp(music_name, mmusic, 6))
+	if (strnicmp(music_name, mmusic, 6))
 	{
 		S_StopMusic(); // shutdown old music
-		if (!S_DigMusic(mmusic, looping) && !S_MIDIMusic(mmusic, looping))
+
+		if (!S_LoadMusic(mmusic))
 		{
-			CONS_Alert(CONS_ERROR, M_GetText("Music lump %.6s not found!\n"), mmusic);
+			CONS_Alert(CONS_ERROR, "Music %.6s could not be loaded!\n", mmusic);
+			return;
+		}
+
+		music_flags = mflags;
+		music_looping = looping;
+
+		if (!S_PlayMusic(looping))
+		{
+			CONS_Alert(CONS_ERROR, "Music %.6s could not be played!\n", mmusic);
 			return;
 		}
 	}
 	I_SetSongTrack(mflags & MUSIC_TRACKMASK);
 }
 
-boolean S_SpeedMusic(float speed)
-{
-	return I_SetSongSpeed(speed);
-}
-
 void S_StopMusic(void)
 {
-	if (!music_playing)
+	if (!I_SongPlaying())
 		return;
 
-	if (mus_paused)
-		I_ResumeSong(music_handle);
-
-	if (!nodigimusic)
-		I_StopDigSong();
+	if (I_SongPaused())
+		I_ResumeSong();
 
 	S_SpeedMusic(1.0f);
-	I_StopSong(music_handle);
-	I_UnRegisterSong(music_handle);
-
-#ifndef HAVE_SDL //SDL uses RWOPS
-	Z_ChangeTag(music_data, PU_CACHE);
-#endif
-
-	music_data = NULL;
-	music_name[0] = 0;
+	I_StopSong();
+	S_UnloadMusic(); // for now, stopping also means you unload the song
 }
 
-void S_SetDigMusicVolume(INT32 volume)
+//
+// Stop and resume music, during game PAUSE.
+//
+void S_PauseAudio(void)
 {
-	if (volume < 0 || volume > 31)
-		CONS_Alert(CONS_WARNING, "musicvolume should be between 0-31\n");
+	if (I_SongPlaying() && !I_SongPaused())
+		I_PauseSong();
 
-	CV_SetValue(&cv_digmusicvolume, volume&31);
+	// pause cd music
+#if (defined (__unix__) && !defined (MSDOS)) || defined (UNIXCOMMON) || defined (HAVE_SDL)
+	I_PauseCD();
+#else
+	I_StopCD();
+#endif
+}
+
+void S_ResumeAudio(void)
+{
+	if (I_SongPlaying() && I_SongPaused())
+		I_ResumeSong();
+
+	// resume cd music
+	I_ResumeCD();
+}
+
+void S_SetMusicVolume(INT32 digvolume, INT32 seqvolume)
+{
+	if (digvolume < 0)
+		digvolume = cv_digmusicvolume.value;
+	if (seqvolume < 0)
+		seqvolume = cv_midimusicvolume.value;
+
+	if (digvolume < 0 || digvolume > 31)
+		CONS_Alert(CONS_WARNING, "digmusicvolume should be between 0-31\n");
+	CV_SetValue(&cv_digmusicvolume, digvolume&31);
 	actualdigmusicvolume = cv_digmusicvolume.value;   //check for change of var
 
-#ifdef DJGPPDOS
-	I_SetDigMusicVolume(31); // Trick for buggy dos drivers. Win32 doesn't need this.
-#endif
-	I_SetDigMusicVolume(volume&31);
-}
-
-void S_SetMIDIMusicVolume(INT32 volume)
-{
-	if (volume < 0 || volume > 31)
-		CONS_Alert(CONS_WARNING, "musicvolume should be between 0-31\n");
-
-	CV_SetValue(&cv_midimusicvolume, volume&0x1f);
+	if (seqvolume < 0 || seqvolume > 31)
+		CONS_Alert(CONS_WARNING, "midimusicvolume should be between 0-31\n");
+	CV_SetValue(&cv_midimusicvolume, seqvolume&31);
 	actualmidimusicvolume = cv_midimusicvolume.value;   //check for change of var
 
 #ifdef DJGPPDOS
-	I_SetMIDIMusicVolume(31); // Trick for buggy dos drivers. Win32 doesn't need this.
+	digvolume = seqvolume = 31;
 #endif
-	I_SetMIDIMusicVolume(volume&0x1f);
+
+	switch(I_SongType())
+	{
+		case MU_MID:
+		//case MU_MOD:
+		//case MU_GME:
+			I_SetMusicVolume(seqvolume&31);
+			break;
+		default:
+			I_SetMusicVolume(digvolume&31);
+			break;
+	}
 }
 
+
 /// ------------------------
 /// Init & Others
 /// ------------------------
 
-//
-// Initializes sound stuff, including volume
-// Sets channels, SFX and music volume,
-//  allocates channel buffer, sets S_sfx lookup.
-//
-void S_Init(INT32 sfxVolume, INT32 digMusicVolume, INT32 midiMusicVolume)
-{
-	INT32 i;
-
-	if (dedicated)
-		return;
-
-	S_SetSfxVolume(sfxVolume);
-	S_SetDigMusicVolume(digMusicVolume);
-	S_SetMIDIMusicVolume(midiMusicVolume);
-
-	SetChannelsNum();
-
-	// no sounds are playing, and they are not mus_paused
-	mus_paused = 0;
-
-	// Note that sounds have not been cached (yet).
-	for (i = 1; i < NUMSFX; i++)
-	{
-		S_sfx[i].usefulness = -1; // for I_GetSfx()
-		S_sfx[i].lumpnum = LUMPERROR;
-	}
-
-	// precache sounds if requested by cmdline, or precachesound var true
-	if (!nosound && (M_CheckParm("-precachesound") || precachesound.value))
-	{
-		// Initialize external data (all sounds) at start, keep static.
-		CONS_Printf(M_GetText("Loading sounds... "));
-
-		for (i = 1; i < NUMSFX; i++)
-			if (S_sfx[i].name)
-				S_sfx[i].data = I_GetSfx(&S_sfx[i]);
-
-		CONS_Printf(M_GetText(" pre-cached all sound data\n"));
-	}
-}
-
-
 //
 // Per level startup code.
 // Kills playing sounds at start of level,
@@ -1388,46 +1521,193 @@ void S_Start(void)
 		mapmusflags = (mapheaderinfo[gamemap-1]->mustrack & MUSIC_TRACKMASK);
 	}
 
-	mus_paused = 0;
-
 	if (cv_resetmusic.value)
 		S_StopMusic();
 	S_ChangeMusic(mapmusname, mapmusflags, true);
 }
 
-//
-// Stop and resume music, during game PAUSE.
-//
-void S_PauseAudio(void)
+static void Command_Tunes_f(void)
 {
-	if (!nodigimusic)
-		I_PauseSong(0);
+	const char *tunearg;
+	UINT16 tunenum, track = 0;
+	const size_t argc = COM_Argc();
 
-	if (music_playing && !mus_paused)
+	if (argc < 2) //tunes slot ...
 	{
-		I_PauseSong(music_handle);
-		mus_paused = true;
+		CONS_Printf("tunes <name/num> [track] [speed] / <-show> / <-default> / <-none>:\n");
+		CONS_Printf(M_GetText("Play an arbitrary music lump. If a map number is used, 'MAP##M' is played.\n"));
+		CONS_Printf(M_GetText("If the format supports multiple songs, you can specify which one to play.\n\n"));
+		CONS_Printf(M_GetText("* With \"-show\", shows the currently playing tune and track.\n"));
+		CONS_Printf(M_GetText("* With \"-default\", returns to the default music for the map.\n"));
+		CONS_Printf(M_GetText("* With \"-none\", any music playing will be stopped.\n"));
+		return;
 	}
 
-	// pause cd music
-#if (defined (__unix__) && !defined (MSDOS)) || defined (UNIXCOMMON) || defined (HAVE_SDL)
-	I_PauseCD();
-#else
-	I_StopCD();
-#endif
-}
+	tunearg = COM_Argv(1);
+	tunenum = (UINT16)atoi(tunearg);
+	track = 0;
 
-void S_ResumeAudio(void)
-{
-	if (!nodigimusic)
-		I_ResumeSong(0);
+	if (!strcasecmp(tunearg, "-show"))
+	{
+		CONS_Printf(M_GetText("The current tune is: %s [track %d]\n"),
+			mapmusname, (mapmusflags & MUSIC_TRACKMASK));
+		return;
+	}
+	if (!strcasecmp(tunearg, "-none"))
+	{
+		S_StopMusic();
+		return;
+	}
+	else if (!strcasecmp(tunearg, "-default"))
+	{
+		tunearg = mapheaderinfo[gamemap-1]->musname;
+		track = mapheaderinfo[gamemap-1]->mustrack;
+	}
+	else if (!tunearg[2] && toupper(tunearg[0]) >= 'A' && toupper(tunearg[0]) <= 'Z')
+		tunenum = (UINT16)M_MapNumber(tunearg[0], tunearg[1]);
+
+	if (tunenum && tunenum >= 1036)
+	{
+		CONS_Alert(CONS_NOTICE, M_GetText("Valid music slots are 1 to 1035.\n"));
+		return;
+	}
+	if (!tunenum && strlen(tunearg) > 6) // This is automatic -- just show the error just in case
+		CONS_Alert(CONS_NOTICE, M_GetText("Music name too long - truncated to six characters.\n"));
+
+	if (argc > 2)
+		track = (UINT16)atoi(COM_Argv(2))-1;
+
+	if (tunenum)
+		snprintf(mapmusname, 7, "%sM", G_BuildMapName(tunenum));
 	else
-	if (music_playing && mus_paused)
-	{
-		I_ResumeSong(music_handle);
-		mus_paused = false;
-	}
+		strncpy(mapmusname, tunearg, 7);
+	mapmusname[6] = 0;
+	mapmusflags = (track & MUSIC_TRACKMASK);
 
-	// resume cd music
-	I_ResumeCD();
+	S_ChangeMusic(mapmusname, mapmusflags, true);
+
+	if (argc > 3)
+	{
+		float speed = (float)atof(COM_Argv(3));
+		if (speed > 0.0f)
+			S_SpeedMusic(speed);
+	}
+}
+
+static void Command_RestartAudio_f(void)
+{
+	S_StopMusic();
+	S_StopSounds();
+	I_ShutdownMusic();
+	I_ShutdownSound();
+	I_StartupSound();
+	I_InitMusic();
+
+// These must be called or no sound and music until manually set.
+
+	I_SetSfxVolume(cv_soundvolume.value);
+	S_SetMusicVolume(cv_digmusicvolume.value, cv_midimusicvolume.value);
+	if (Playing()) // Gotta make sure the player is in a level
+		P_RestoreMusic(&players[consoleplayer]);
+}
+
+void GameSounds_OnChange(void)
+{
+	if (M_CheckParm("-nosound"))
+		return;
+
+	if (sound_disabled)
+	{
+		sound_disabled = false;
+		S_InitSfxChannels(cv_soundvolume.value);
+		S_StartSound(NULL, sfx_strpst);
+	}
+	else
+	{
+		sound_disabled = true;
+		S_StopSounds();
+	}
+}
+
+void GameDigiMusic_OnChange(void)
+{
+	if (M_CheckParm("-nomusic"))
+		return;
+	else if (M_CheckParm("-nodigmusic"))
+		return;
+
+	if (digital_disabled)
+	{
+		digital_disabled = false;
+		I_InitMusic();
+		S_StopMusic();
+		if (Playing())
+			P_RestoreMusic(&players[consoleplayer]);
+		else
+			S_ChangeMusicInternal("lclear", false);
+	}
+	else
+	{
+		digital_disabled = true;
+		if (S_MusicType() != MU_MID)
+		{
+			if (midi_disabled)
+				S_StopMusic();
+			else
+			{
+				char mmusic[7];
+				UINT16 mflags;
+				boolean looping;
+
+				if (S_MusicInfo(mmusic, &mflags, &looping) && S_MIDIExists(mmusic))
+				{
+					S_StopMusic();
+					S_ChangeMusic(mmusic, mflags, looping);
+				}
+				else
+					S_StopMusic();
+			}
+		}
+	}
+}
+
+void GameMIDIMusic_OnChange(void)
+{
+	if (M_CheckParm("-nomusic"))
+		return;
+	else if (M_CheckParm("-nomidimusic"))
+		return;
+
+	if (midi_disabled)
+	{
+		midi_disabled = false;
+		I_InitMusic();
+		if (Playing())
+			P_RestoreMusic(&players[consoleplayer]);
+		else
+			S_ChangeMusicInternal("lclear", false);
+	}
+	else
+	{
+		midi_disabled = true;
+		if (S_MusicType() == MU_MID)
+		{
+			if (digital_disabled)
+				S_StopMusic();
+			else
+			{
+				char mmusic[7];
+				UINT16 mflags;
+				boolean looping;
+
+				if (S_MusicInfo(mmusic, &mflags, &looping) && S_DigExists(mmusic))
+				{
+					S_StopMusic();
+					S_ChangeMusic(mmusic, mflags, looping);
+				}
+				else
+					S_StopMusic();
+			}
+		}
+	}
 }
diff --git a/src/s_sound.h b/src/s_sound.h
index 39ec769a6..821746074 100644
--- a/src/s_sound.h
+++ b/src/s_sound.h
@@ -2,7 +2,7 @@
 //-----------------------------------------------------------------------------
 // Copyright (C) 1993-1996 by id Software, Inc.
 // Copyright (C) 1998-2000 by DooM Legacy Team.
-// Copyright (C) 1999-2016 by Sonic Team Junior.
+// Copyright (C) 1999-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
@@ -14,6 +14,7 @@
 #ifndef __S_SOUND__
 #define __S_SOUND__
 
+#include "i_sound.h" // musictype_t
 #include "sounds.h"
 #include "m_fixed.h"
 #include "command.h"
@@ -25,6 +26,10 @@
 extern consvar_t stereoreverse;
 extern consvar_t cv_soundvolume, cv_digmusicvolume, cv_midimusicvolume;
 extern consvar_t cv_numChannels;
+extern consvar_t cv_resetmusic;
+extern consvar_t cv_gamedigimusic;
+extern consvar_t cv_gamemidimusic;
+extern consvar_t cv_gamesounds;
 
 #ifdef SNDSERV
 extern consvar_t sndserver_cmd, sndserver_arg;
@@ -69,9 +74,9 @@ void S_RegisterSoundStuff(void);
 
 //
 // Initializes sound stuff, including volume
-// Sets channels, SFX and music volume, allocates channel buffer, sets S_sfx lookup.
+// Sets channels, SFX, allocates channel buffer, sets S_sfx lookup.
 //
-void S_Init(INT32 sfxVolume, INT32 digMusicVolume, INT32 midiMusicVolume);
+void S_InitSfxChannels(INT32 sfxVolume);
 
 //
 // Per level startup code.
@@ -97,6 +102,33 @@ void S_StartSoundAtVolume(const void *origin, sfxenum_t sound_id, INT32 volume);
 // Stop sound for thing at <origin>
 void S_StopSound(void *origin);
 
+//
+// Music Status
+//
+
+boolean S_DigMusicDisabled(void);
+boolean S_MIDIMusicDisabled(void);
+boolean S_MusicDisabled(void);
+boolean S_MusicPlaying(void);
+boolean S_MusicPaused(void);
+musictype_t S_MusicType(void);
+boolean S_MusicInfo(char *mname, UINT16 *mflags, boolean *looping);
+boolean S_MusicExists(const char *mname, boolean checkMIDI, boolean checkDigi);
+#define S_DigExists(a) S_MusicExists(a, false, true)
+#define S_MIDIExists(a) S_MusicExists(a, true, false)
+
+
+//
+// Music Properties
+//
+
+// Set Speed of Music
+boolean S_SpeedMusic(float speed);
+
+//
+// Music Routines
+//
+
 // Start music track, arbitrary, given its name, and set whether looping
 // note: music flags 12 bits for tracknum (gme, other formats with more than one track)
 //       13-15 aren't used yet
@@ -104,9 +136,6 @@ void S_StopSound(void *origin);
 #define S_ChangeMusicInternal(a,b) S_ChangeMusic(a,0,b)
 void S_ChangeMusic(const char *mmusic, UINT16 mflags, boolean looping);
 
-// Set Speed of Music
-boolean S_SpeedMusic(float speed);
-
 // Stops the music.
 void S_StopMusic(void);
 
@@ -121,9 +150,11 @@ void S_UpdateSounds(void);
 
 FUNCMATH fixed_t S_CalculateSoundDistance(fixed_t px1, fixed_t py1, fixed_t pz1, fixed_t px2, fixed_t py2, fixed_t pz2);
 
-void S_SetDigMusicVolume(INT32 volume);
-void S_SetMIDIMusicVolume(INT32 volume);
 void S_SetSfxVolume(INT32 volume);
+void S_SetMusicVolume(INT32 digvolume, INT32 seqvolume);
+#define S_SetDigMusicVolume(a) S_SetMusicVolume(a,-1)
+#define S_SetMIDIMusicVolume(a) S_SetMusicVolume(-1,a)
+#define S_InitMusicVolume() S_SetMusicVolume(-1,-1)
 
 INT32 S_OriginPlaying(void *origin);
 INT32 S_IdPlaying(sfxenum_t id);
diff --git a/src/screen.c b/src/screen.c
index 2780edb60..d5beaf360 100644
--- a/src/screen.c
+++ b/src/screen.c
@@ -1,7 +1,7 @@
 // SONIC ROBO BLAST 2
 //-----------------------------------------------------------------------------
 // Copyright (C) 1998-2000 by DooM Legacy Team.
-// Copyright (C) 1999-2016 by Sonic Team Junior.
+// Copyright (C) 1999-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
@@ -49,6 +49,7 @@ void (*splatfunc)(void); // span drawer w/ transparency
 void (*basespanfunc)(void); // default span func for color mode
 void (*transtransfunc)(void); // translucent translated column drawer
 void (*twosmultipatchfunc)(void); // for cols with transparent pixels
+void (*twosmultipatchtransfunc)(void); // for cols with transparent pixels AND translucency
 
 // ------------------
 // global video state
@@ -70,11 +71,7 @@ consvar_t cv_scr_depth = {"scr_depth", "16 bits", CV_SAVE, scr_depth_cons_t, NUL
 #endif
 consvar_t cv_renderview = {"renderview", "On", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
 
-#ifdef DIRECTFULLSCREEN
-static FUNCMATH void SCR_ChangeFullscreen (void);
-#else
 static void SCR_ChangeFullscreen (void);
-#endif
 
 consvar_t cv_fullscreen = {"fullscreen", "Yes", CV_SAVE|CV_CALL, CV_YesNo, SCR_ChangeFullscreen, 0, NULL, NULL, 0, 0, NULL};
 
@@ -127,6 +124,7 @@ void SCR_SetMode(void)
 		fuzzcolfunc = R_DrawTranslucentColumn_8;
 		walldrawerfunc = R_DrawWallColumn_8;
 		twosmultipatchfunc = R_Draw2sMultiPatchColumn_8;
+		twosmultipatchtransfunc = R_Draw2sMultiPatchTranslucentColumn_8;
 #ifdef RUSEASM
 		if (R_ASM)
 		{
@@ -282,7 +280,10 @@ void SCR_Recalc(void)
 	vid.fdupy = FixedDiv(vid.height*FRACUNIT, BASEVIDHEIGHT*FRACUNIT);
 
 #ifdef HWRENDER
-	if (rendermode != render_opengl && rendermode != render_none) // This was just placing it incorrectly at non aspect correct resolutions in opengl
+	//if (rendermode != render_opengl && rendermode != render_none) // This was just placing it incorrectly at non aspect correct resolutions in opengl
+	// 13/11/18:
+	// The above is no longer necessary, since we want OpenGL to be just like software now
+	// -- Monster Iestyn
 #endif
 		vid.fdupx = vid.fdupy = (vid.fdupx < vid.fdupy ? vid.fdupx : vid.fdupy);
 
diff --git a/src/screen.h b/src/screen.h
index 2dff4590e..9ad254d3f 100644
--- a/src/screen.h
+++ b/src/screen.h
@@ -1,7 +1,7 @@
 // SONIC ROBO BLAST 2
 //-----------------------------------------------------------------------------
 // Copyright (C) 1998-2000 by DooM Legacy Team.
-// Copyright (C) 1999-2016 by Sonic Team Junior.
+// Copyright (C) 1999-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
@@ -136,6 +136,7 @@ extern void (*basespanfunc)(void);
 extern void (*splatfunc)(void);
 extern void (*transtransfunc)(void);
 extern void (*twosmultipatchfunc)(void);
+extern void (*twosmultipatchtransfunc)(void);
 
 // -----
 // CPUID
diff --git a/src/sdl/CMakeLists.txt b/src/sdl/CMakeLists.txt
index 7f6771262..a3626970e 100644
--- a/src/sdl/CMakeLists.txt
+++ b/src/sdl/CMakeLists.txt
@@ -3,7 +3,18 @@
 set(SRB2_CONFIG_SDL2_USEMIXER ON CACHE BOOL "Use SDL2_mixer or regular sdl sound")
 
 if(${SRB2_CONFIG_SDL2_USEMIXER})
-	find_package(SDL2_mixer)
+	if(${SRB2_CONFIG_USE_INTERNAL_LIBRARIES})
+		set(SDL2_MIXER_FOUND ON)
+		if(${SRB2_SYSTEM_BITS} EQUAL 64)
+			set(SDL2_MIXER_INCLUDE_DIRS ${CMAKE_SOURCE_DIR}/libs/SDL2_mixer/x86_64-w64-mingw32/include/SDL2)
+			set(SDL2_MIXER_LIBRARIES "-L${CMAKE_SOURCE_DIR}/libs/SDL2_mixer/x86_64-w64-mingw32/lib -lSDL2_mixer")
+		else() # 32-bit
+			set(SDL2_MIXER_INCLUDE_DIRS ${CMAKE_SOURCE_DIR}/libs/SDL2_mixer/i686-w64-mingw32/include/SDL2)
+			set(SDL2_MIXER_LIBRARIES "-L${CMAKE_SOURCE_DIR}/libs/SDL2_mixer/i686-w64-mingw32/lib -lSDL2_mixer")
+		endif()
+	else()
+		find_package(SDL2_mixer)
+	endif()
 	if(${SDL2_MIXER_FOUND})
 		set(SRB2_HAVE_MIXER ON)
 		set(SRB2_SDL2_SOUNDIMPL mixer_sound.c)
@@ -42,7 +53,18 @@ set(SRB2_SDL2_HEADERS
 source_group("Interface Code" FILES ${SRB2_SDL2_SOURCES} ${SRB2_SDL2_HEADERS})
 
 # Dependency
-find_package(SDL2)
+if(${SRB2_CONFIG_USE_INTERNAL_LIBRARIES})
+	set(SDL2_FOUND ON)
+	if(${SRB2_SYSTEM_BITS} EQUAL 64)
+		set(SDL2_INCLUDE_DIRS ${CMAKE_SOURCE_DIR}/libs/SDL2/x86_64-w64-mingw32/include/SDL2)
+		set(SDL2_LIBRARIES "-L${CMAKE_SOURCE_DIR}/libs/SDL2/x86_64-w64-mingw32/lib -lSDL2")
+	else() # 32-bit
+		set(SDL2_INCLUDE_DIRS ${CMAKE_SOURCE_DIR}/libs/SDL2/i686-w64-mingw32/include/SDL2)
+		set(SDL2_LIBRARIES "-L${CMAKE_SOURCE_DIR}/libs/SDL2/i686-w64-mingw32/lib -lSDL2")
+	endif()
+else()
+	find_package(SDL2)
+endif()
 
 if(${SDL2_FOUND})
 	set(SRB2_SDL2_TOTAL_SOURCES
@@ -185,7 +207,18 @@ if(${SDL2_FOUND})
 	endif()
 
 	if(MSVC)
-		find_package(SDL2_MAIN REQUIRED)
+		if(${SRB2_CONFIG_USE_INTERNAL_LIBRARIES})
+			set(SDL2_MAIN_FOUND ON)
+			if(${SRB2_SYSTEM_BITS} EQUAL 64)
+				set(SDL2_MAIN_INCLUDE_DIRS ${CMAKE_SOURCE_DIR}/libs/SDL2/x86_64-w64-mingw32/include/SDL2)
+				set(SDL2_MAIN_LIBRARIES "-L${CMAKE_SOURCE_DIR}/libs/SDL2/x86_64-w64-mingw32/lib -lSDL2main")
+			else() # 32-bit
+				set(SDL2_MAIN_INCLUDE_DIRS ${CMAKE_SOURCE_DIR}/libs/SDL2/i686-w64-mingw32/include/SDL2)
+				set(SDL2_MAIN_LIBRARIES "-L${CMAKE_SOURCE_DIR}/libs/SDL2/i686-w64-mingw32/lib -lSDL2main")
+			endif()
+		else()
+			find_package(SDL2_MAIN REQUIRED)
+		endif()
 		target_link_libraries(SRB2SDL2 PRIVATE
 			${SDL2_MAIN_LIBRARIES}
 		)
@@ -241,17 +274,49 @@ if(${SDL2_FOUND})
 	if(${CMAKE_SYSTEM} MATCHES Windows)
 		set(win_extra_dll_list "")
 		macro(getwinlib dllname defaultname)
-			find_library(SRB2_SDL2_DLL_${dllname} "${defaultname}")
-			list(APPEND win_extra_dll_list ${SRB2_SDL2_DLL_${dllname}})
+			if(${SRB2_CONFIG_USE_INTERNAL_LIBRARIES})
+				if (${CMAKE_GENERATOR} STREQUAL "MinGW Makefiles")
+					if(${SRB2_SYSTEM_BITS} EQUAL 64)
+						find_library(SRB2_SDL2_DLL_${dllname} "${defaultname}"
+							HINTS ${CMAKE_SOURCE_DIR}/Bin/Resources/x86_64
+							HINTS ${CMAKE_SOURCE_DIR}/libs/SDL2/x86_64-w64-mingw32/bin
+							HINTS ${CMAKE_SOURCE_DIR}/libs/SDL2_mixer/x86_64-w64-mingw32/bin
+						)
+					else()
+						find_library(SRB2_SDL2_DLL_${dllname} "${defaultname}"
+							HINTS ${CMAKE_SOURCE_DIR}/Bin/Resources/i686
+							HINTS ${CMAKE_SOURCE_DIR}/libs/SDL2/i686-w64-mingw32/bin
+							HINTS ${CMAKE_SOURCE_DIR}/libs/SDL2_mixer/i686-w64-mingw32/bin
+						)
+					endif()
+				else()
+					if(${SRB2_SYSTEM_BITS} EQUAL 64)
+						find_library(SRB2_SDL2_DLL_${dllname} "${defaultname}"
+							HINTS ${CMAKE_SOURCE_DIR}/Bin/Resources/x86_64
+							HINTS ${CMAKE_SOURCE_DIR}/libs/SDL2/lib/x64
+							HINTS ${CMAKE_SOURCE_DIR}/libs/SDL2_mixer/lib/x64
+						)
+					else()
+						find_library(SRB2_SDL2_DLL_${dllname} "${defaultname}"
+							HINTS ${CMAKE_SOURCE_DIR}/Bin/Resources/i686
+							HINTS ${CMAKE_SOURCE_DIR}/libs/SDL2/lib/x86
+							HINTS ${CMAKE_SOURCE_DIR}/libs/SDL2_mixer/lib/x86
+						)
+					endif()
+				endif()
+
+				list(APPEND win_extra_dll_list ${SRB2_SDL2_DLL_${dllname}})
+			else()
+				find_library(SRB2_SDL2_DLL_${dllname} "${defaultname}")
+				list(APPEND win_extra_dll_list ${SRB2_SDL2_DLL_${dllname}})
+	endif()
 		endmacro()
 		getwinlib(SDL2 "SDL2.dll")
 		if(${SRB2_CONFIG_SDL2_USEMIXER})
 			getwinlib(SDL2_mixer "SDL2_mixer.dll")
-			getwinlib(libmikmod-2 "libmikmod-2.dll")
 			getwinlib(libogg_0 "libogg-0.dll")
 			getwinlib(libvorbis_0 "libvorbis-0.dll")
 			getwinlib(libvorbisfile_3 "libvorbisfile-3.dll")
-			getwinlib(smpeg2 "smpeg2.dll")
 		endif()
 		if(${SRB2_CONFIG_HAVE_GME})
 			getwinlib(libgme "libgme.dll")
diff --git a/src/sdl/IMG_xpm.c b/src/sdl/IMG_xpm.c
index 8adfd3434..af76ec1dd 100644
--- a/src/sdl/IMG_xpm.c
+++ b/src/sdl/IMG_xpm.c
@@ -45,9 +45,10 @@
 #if 0
 #include "SDL_image.h"
 #else
-extern SDLCALL int SDLCALL IMG_isXPM(SDL_RWops *src);
-extern SDLCALL SDL_Surface *IMG_LoadXPM_RW(SDL_RWops *src);
-extern SDLCALL SDL_Surface * SDLCALL IMG_ReadXPMFromArray(const char **xpm);
+// SDLCALL terms removed from original SDL_image declarations
+int IMG_isXPM(SDL_RWops *src);
+SDL_Surface *IMG_LoadXPM_RW(SDL_RWops *src);
+SDL_Surface *IMG_ReadXPMFromArray(const char **xpm);
 #define IMG_SetError    SDL_SetError
 #define IMG_GetError    SDL_GetError
 #endif
diff --git a/src/sdl/Srb2SDL-vc10.vcxproj b/src/sdl/Srb2SDL-vc10.vcxproj
index 820192649..467d2829b 100644
--- a/src/sdl/Srb2SDL-vc10.vcxproj
+++ b/src/sdl/Srb2SDL-vc10.vcxproj
@@ -141,6 +141,7 @@
     <ClInclude Include="..\hardware\hw3dsdrv.h" />
     <ClInclude Include="..\hardware\hw3sound.h" />
     <ClInclude Include="..\hardware\hws_data.h" />
+    <ClInclude Include="..\hardware\hw_clip.h" />
     <ClInclude Include="..\hardware\hw_data.h" />
     <ClInclude Include="..\hardware\hw_defs.h" />
     <ClInclude Include="..\hardware\hw_dll.h" />
@@ -282,6 +283,7 @@
     <ClCompile Include="..\hardware\hw3sound.c" />
     <ClCompile Include="..\hardware\hw_bsp.c" />
     <ClCompile Include="..\hardware\hw_cache.c" />
+    <ClCompile Include="..\hardware\hw_clip.c" />
     <ClCompile Include="..\hardware\hw_draw.c" />
     <ClCompile Include="..\hardware\hw_light.c" />
     <ClCompile Include="..\hardware\hw_main.c" />
diff --git a/src/sdl/Srb2SDL-vc10.vcxproj.filters b/src/sdl/Srb2SDL-vc10.vcxproj.filters
index d04007dd7..364deb497 100644
--- a/src/sdl/Srb2SDL-vc10.vcxproj.filters
+++ b/src/sdl/Srb2SDL-vc10.vcxproj.filters
@@ -216,6 +216,9 @@
     <ClInclude Include="..\hardware\hws_data.h">
       <Filter>Hw_Hardware</Filter>
     </ClInclude>
+    <ClInclude Include="..\hardware\hw_clip.h">
+      <Filter>Hw_Hardware</Filter>
+    </ClInclude>
     <ClInclude Include="..\hardware\hw_data.h">
       <Filter>Hw_Hardware</Filter>
     </ClInclude>
@@ -603,6 +606,9 @@
     <ClCompile Include="..\hardware\hw_cache.c">
       <Filter>Hw_Hardware</Filter>
     </ClCompile>
+    <ClCompile Include="..\hardware\hw_clip.c">
+      <Filter>Hw_Hardware</Filter>
+    </ClCompile>
     <ClCompile Include="..\hardware\hw_draw.c">
       <Filter>Hw_Hardware</Filter>
     </ClCompile>
diff --git a/src/sdl/i_cdmus.c b/src/sdl/i_cdmus.c
index 3105f5122..5d086e73a 100644
--- a/src/sdl/i_cdmus.c
+++ b/src/sdl/i_cdmus.c
@@ -12,19 +12,19 @@ consvar_t cd_volume = {"cd_volume","31",CV_SAVE,soundvolume_cons_t, NULL, 0, NUL
 consvar_t cdUpdate  = {"cd_update","1",CV_SAVE, NULL, NULL, 0, NULL, NULL, 0, 0, NULL};
 
 
-FUNCMATH void I_InitCD(void){}
+void I_InitCD(void){}
 
-FUNCMATH void I_StopCD(void){}
+void I_StopCD(void){}
 
-FUNCMATH void I_PauseCD(void){}
+void I_PauseCD(void){}
 
-FUNCMATH void I_ResumeCD(void){}
+void I_ResumeCD(void){}
 
-FUNCMATH void I_ShutdownCD(void){}
+void I_ShutdownCD(void){}
 
-FUNCMATH void I_UpdateCD(void){}
+void I_UpdateCD(void){}
 
-FUNCMATH void I_PlayCD(UINT8 track, UINT8 looping)
+void I_PlayCD(UINT8 track, UINT8 looping)
 {
 	(void)track;
 	(void)looping;
diff --git a/src/sdl/i_system.c b/src/sdl/i_system.c
index f92cd4b6e..2b35ce8b8 100644
--- a/src/sdl/i_system.c
+++ b/src/sdl/i_system.c
@@ -1,8 +1,11 @@
 // Emacs style mode select   -*- C++ -*-
+//
+// SONIC ROBO BLAST 2
 //-----------------------------------------------------------------------------
 //
 // Copyright (C) 1993-1996 by id Software, Inc.
 // Portions Copyright (C) 1998-2000 by DooM Legacy Team.
+// Copyright (C) 2014-2018 by Sonic Team Junior.
 //
 // This program is free software; you can redistribute it and/or
 // modify it under the terms of the GNU General Public License
@@ -1154,6 +1157,7 @@ static void I_ShutdownJoystick2(void)
 		D_PostEvent(&event);
 	}
 
+	joystick2_started = 0;
 	JoyReset(&JoyInfo2);
 	if (!joystick_started && !joystick2_started && SDL_WasInit(SDL_INIT_JOYSTICK) == SDL_INIT_JOYSTICK)
 	{
@@ -1926,14 +1930,14 @@ void I_StartupMouse2(void)
 //
 // I_Tactile
 //
-FUNCMATH void I_Tactile(FFType pFFType, const JoyFF_t *FFEffect)
+void I_Tactile(FFType pFFType, const JoyFF_t *FFEffect)
 {
 	// UNUSED.
 	(void)pFFType;
 	(void)FFEffect;
 }
 
-FUNCMATH void I_Tactile2(FFType pFFType, const JoyFF_t *FFEffect)
+void I_Tactile2(FFType pFFType, const JoyFF_t *FFEffect)
 {
 	// UNUSED.
 	(void)pFFType;
@@ -1944,7 +1948,7 @@ FUNCMATH void I_Tactile2(FFType pFFType, const JoyFF_t *FFEffect)
 */
 static ticcmd_t emptycmd;
 
-FUNCMATH ticcmd_t *I_BaseTiccmd(void)
+ticcmd_t *I_BaseTiccmd(void)
 {
 	return &emptycmd;
 }
@@ -1953,7 +1957,7 @@ FUNCMATH ticcmd_t *I_BaseTiccmd(void)
 */
 static ticcmd_t emptycmd2;
 
-FUNCMATH ticcmd_t *I_BaseTiccmd2(void)
+ticcmd_t *I_BaseTiccmd2(void)
 {
 	return &emptycmd2;
 }
@@ -2047,7 +2051,7 @@ tic_t I_GetTime (void)
 //
 //I_StartupTimer
 //
-FUNCMATH void I_StartupTimer(void)
+void I_StartupTimer(void)
 {
 #ifdef _WIN32
 	// for win2k time bug
@@ -2135,6 +2139,8 @@ void I_Quit(void)
 		printf("\r");
 		ShowEndTxt();
 	}
+	if (myargmalloc)
+		free(myargv); // Deallocate allocated memory
 death:
 	W_Shutdown();
 	exit(0);
@@ -2146,11 +2152,11 @@ void I_WaitVBL(INT32 count)
 	SDL_Delay(count);
 }
 
-FUNCMATH void I_BeginRead(void)
+void I_BeginRead(void)
 {
 }
 
-FUNCMATH void I_EndRead(void)
+void I_EndRead(void)
 {
 }
 
@@ -2938,5 +2944,5 @@ const CPUInfoFlags *I_CPUInfo(void)
 }
 
 // note CPUAFFINITY code used to reside here
-FUNCMATH void I_RegisterSysCommands(void) {}
+void I_RegisterSysCommands(void) {}
 #endif
diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c
index ce84e86a6..3cc29dbb4 100644
--- a/src/sdl/i_video.c
+++ b/src/sdl/i_video.c
@@ -1,8 +1,10 @@
 // Emacs style mode select   -*- C++ -*-
+// SONIC ROBO BLAST 2
 //-----------------------------------------------------------------------------
 //
 // Copyright (C) 1993-1996 by id Software, Inc.
 // Portions Copyright (C) 1998-2000 by DooM Legacy Team.
+// Copyright (C) 2014-2018 by Sonic Team Junior.
 //
 // This program is free software; you can redistribute it and/or
 // modify it under the terms of the GNU General Public License
@@ -566,7 +568,7 @@ static void Impl_HandleWindowEvent(SDL_WindowEvent evt)
 		// Tell game we got focus back, resume music if necessary
 		window_notinfocus = false;
 		if (!paused)
-			I_ResumeSong(0); //resume it
+			I_ResumeSong(); //resume it
 
 		if (!firsttimeonmouse)
 		{
@@ -578,7 +580,7 @@ static void Impl_HandleWindowEvent(SDL_WindowEvent evt)
 	{
 		// Tell game we lost focus, pause music
 		window_notinfocus = true;
-		I_PauseSong(0);
+		I_PauseSong();
 
 		if (!disable_mouse)
 		{
@@ -1053,7 +1055,7 @@ void I_SetPalette(RGBA_t *palette)
 }
 
 // return number of fullscreen + X11 modes
-FUNCMATH INT32 VID_NumModes(void)
+INT32 VID_NumModes(void)
 {
 	if (USE_FULLSCREEN && numVidModes != -1)
 		return numVidModes - firstEntry;
@@ -1061,7 +1063,7 @@ FUNCMATH INT32 VID_NumModes(void)
 		return MAXWINMODES;
 }
 
-FUNCMATH const char *VID_GetModeName(INT32 modeNum)
+const char *VID_GetModeName(INT32 modeNum)
 {
 #if 0
 	if (USE_FULLSCREEN && numVidModes != -1) // fullscreen modes
@@ -1091,7 +1093,7 @@ FUNCMATH const char *VID_GetModeName(INT32 modeNum)
 	return &vidModeName[modeNum][0];
 }
 
-FUNCMATH INT32 VID_GetModeForSize(INT32 w, INT32 h)
+INT32 VID_GetModeForSize(INT32 w, INT32 h)
 {
 	int i;
 	for (i = 0; i < MAXWINMODES; i++)
diff --git a/src/sdl/mixer_sound.c b/src/sdl/mixer_sound.c
index 5211efe0a..a3c421991 100644
--- a/src/sdl/mixer_sound.c
+++ b/src/sdl/mixer_sound.c
@@ -1,3 +1,11 @@
+// SONIC ROBO BLAST 2
+//-----------------------------------------------------------------------------
+// Copyright (C) 2014-2018 by Sonic Team Junior.
+//
+// This program is free software distributed under the
+// terms of the GNU General Public License, version 2.
+// See the 'LICENSE' file for more details.
+//-----------------------------------------------------------------------------
 /// \file
 /// \brief SDL Mixer interface for sound
 
@@ -34,14 +42,18 @@
 	(SDL_MIXER_COMPILEDVERSION >= SDL_VERSIONNUM(X, Y, Z))
 #endif
 
+// thanks alam for making the buildbots happy!
+#if SDL_MIXER_VERSION_ATLEAST(2,0,2)
+#define MUS_MP3_MAD MUS_MP3_MAD_UNUSED
+#define MUS_MODPLUG MUS_MODPLUG_UNUSED
+#endif
+
 #ifdef HAVE_LIBGME
 #include "gme/gme.h"
 #define GME_TREBLE 5.0
 #define GME_BASS 1.0
-#ifdef HAVE_PNG /// TODO: compile with zlib support without libpng
-
-#define HAVE_ZLIB
 
+#ifdef HAVE_ZLIB
 #ifndef _MSC_VER
 #ifndef _LARGEFILE64_SOURCE
 #define _LARGEFILE64_SOURCE
@@ -57,14 +69,13 @@
 #endif
 
 #include "zlib.h"
-#endif
-#endif
+#endif // HAVE_ZLIB
+#endif // HAVE_LIBGME
 
 UINT8 sound_started = false;
 
-static boolean midimode;
 static Mix_Music *music;
-static UINT8 music_volume, midi_volume, sfx_volume;
+static UINT8 music_volume, sfx_volume;
 static float loop_point;
 static boolean songpaused;
 
@@ -73,13 +84,20 @@ static Music_Emu *gme;
 static INT32 current_track;
 #endif
 
+/// ------------------------
+/// Audio System
+/// ------------------------
+
 void I_StartupSound(void)
 {
 	I_Assert(!sound_started);
 
 	// EE inits audio first so we're following along.
 	if (SDL_WasInit(SDL_INIT_AUDIO) == SDL_INIT_AUDIO)
-		CONS_Printf("SDL Audio already started\n");
+	{
+		CONS_Debug(DBG_DETAILED, "SDL Audio already started\n");
+		return;
+	}
 	else if (SDL_InitSubSystem(SDL_INIT_AUDIO) < 0)
 	{
 		CONS_Alert(CONS_ERROR, "Error initializing SDL Audio: %s\n", SDL_GetError());
@@ -87,9 +105,8 @@ void I_StartupSound(void)
 		return;
 	}
 
-	midimode = false;
 	music = NULL;
-	music_volume = midi_volume = sfx_volume = 0;
+	music_volume = sfx_volume = 0;
 
 #if SDL_MIXER_VERSION_ATLEAST(1,2,11)
 	Mix_Init(MIX_INIT_FLAC|MIX_INIT_MOD|MIX_INIT_MP3|MIX_INIT_OGG);
@@ -126,10 +143,14 @@ void I_ShutdownSound(void)
 #endif
 }
 
-FUNCMATH void I_UpdateSound(void)
+void I_UpdateSound(void)
 {
 }
 
+/// ------------------------
+/// SFX
+/// ------------------------
+
 // this is as fast as I can possibly make it.
 // sorry. more asm needed.
 static Mix_Chunk *ds2chunk(void *stream)
@@ -178,7 +199,7 @@ static Mix_Chunk *ds2chunk(void *stream)
 			return NULL; // would and/or did wrap, can't store.
 		break;
 	}
-	sound = malloc(newsamples<<2); // samples * frequency shift * bytes per sample * channels
+	sound = Z_Malloc(newsamples<<2, PU_SOUND, NULL); // samples * frequency shift * bytes per sample * channels
 
 	s = (SINT8 *)stream;
 	d = (INT16 *)sound;
@@ -246,6 +267,7 @@ void *I_GetSfx(sfxinfo_t *sfx)
 {
 	void *lump;
 	Mix_Chunk *chunk;
+	SDL_RWops *rw;
 #ifdef HAVE_LIBGME
 	Music_Emu *emu;
 	gme_info_t *info;
@@ -361,7 +383,7 @@ void *I_GetSfx(sfxinfo_t *sfx)
 		}
 		Z_Free(inflatedData); // GME didn't open jack, but don't let that stop us from freeing this up
 #else
-		//CONS_Alert(CONS_ERROR,"Cannot decompress VGZ; no zlib support\n");
+		return NULL; // No zlib support
 #endif
 	}
 	// Try to read it as a GME sound
@@ -387,21 +409,43 @@ void *I_GetSfx(sfxinfo_t *sfx)
 #endif
 
 	// Try to load it as a WAVE or OGG using Mixer.
-	return Mix_LoadWAV_RW(SDL_RWFromMem(lump, sfx->length), 1);
+	rw = SDL_RWFromMem(lump, sfx->length);
+	if (rw != NULL)
+	{
+		chunk = Mix_LoadWAV_RW(rw, 1);
+		return chunk;
+	}
+
+	return NULL; // haven't been able to get anything
 }
 
 void I_FreeSfx(sfxinfo_t *sfx)
 {
 	if (sfx->data)
+	{
+		Mix_Chunk *chunk = (Mix_Chunk*)sfx->data;
+		UINT8 *abufdata = NULL;
+		if (chunk->allocated == 0)
+		{
+			// We allocated the data in this chunk, so get the abuf from mixer, then let it free the chunk, THEN we free the data
+			// I believe this should ensure the sound is not playing when we free it
+			abufdata = chunk->abuf;
+		}
 		Mix_FreeChunk(sfx->data);
+		if (abufdata)
+		{
+			// I'm going to assume we used Z_Malloc to allocate this data.
+			Z_Free(abufdata);
+		}
+	}
 	sfx->data = NULL;
 	sfx->lumpnum = LUMPERROR;
 }
 
-INT32 I_StartSound(sfxenum_t id, UINT8 vol, UINT8 sep, UINT8 pitch, UINT8 priority)
+INT32 I_StartSound(sfxenum_t id, UINT8 vol, UINT8 sep, UINT8 pitch, UINT8 priority, INT32 channel)
 {
 	UINT8 volume = (((UINT16)vol + 1) * (UINT16)sfx_volume) / 62; // (256 * 31) / 62 == 127
-	INT32 handle = Mix_PlayChannel(-1, S_sfx[id].data, 0);
+	INT32 handle = Mix_PlayChannel(channel, S_sfx[id].data, 0);
 	Mix_Volume(handle, volume);
 	Mix_SetPanning(handle, min((UINT16)(0xff-sep)<<1, 0xff), min((UINT16)(sep)<<1, 0xff));
 	(void)pitch; // Mixer can't handle pitch
@@ -432,11 +476,10 @@ void I_SetSfxVolume(UINT8 volume)
 	sfx_volume = volume;
 }
 
-//
-// Music
-//
+/// ------------------------
+/// Music Hooks
+/// ------------------------
 
-// Music hooks
 static void music_loop(void)
 {
 	Mix_PlayMusic(music, 0);
@@ -464,78 +507,101 @@ static void mix_gme(void *udata, Uint8 *stream, int len)
 }
 #endif
 
-FUNCMATH void I_InitMusic(void)
+
+/// ------------------------
+/// Music System
+/// ------------------------
+
+void I_InitMusic(void)
 {
 }
 
 void I_ShutdownMusic(void)
 {
-	I_ShutdownDigMusic();
-	I_ShutdownMIDIMusic();
+	I_UnloadSong();
 }
 
-void I_PauseSong(INT32 handle)
-{
-	(void)handle;
-	Mix_PauseMusic();
-	songpaused = true;
-}
+/// ------------------------
+/// Music Properties
+/// ------------------------
 
-void I_ResumeSong(INT32 handle)
-{
-	(void)handle;
-	Mix_ResumeMusic();
-	songpaused = false;
-}
-
-//
-// Digital Music
-//
-
-void I_InitDigMusic(void)
+musictype_t I_SongType(void)
 {
 #ifdef HAVE_LIBGME
-	gme = NULL;
-	current_track = -1;
+	if (gme)
+		return MU_GME;
+	else
 #endif
+	if (!music)
+		return MU_NONE;
+	else if (Mix_GetMusicType(music) == MUS_MID)
+		return MU_MID;
+	else if (Mix_GetMusicType(music) == MUS_MOD || Mix_GetMusicType(music) == MUS_MODPLUG)
+		return MU_MOD;
+	else if (Mix_GetMusicType(music) == MUS_MP3 || Mix_GetMusicType(music) == MUS_MP3_MAD)
+		return MU_MP3;
+	else
+		return (musictype_t)Mix_GetMusicType(music);
 }
 
-void I_ShutdownDigMusic(void)
+boolean I_SongPlaying(void)
 {
-	if (midimode)
-		return;
+	return (
+#ifdef HAVE_LIBGME
+		(I_SongType() == MU_GME && gme) ||
+#endif
+		music != NULL
+	);
+}
+
+boolean I_SongPaused(void)
+{
+	return songpaused;
+}
+
+/// ------------------------
+/// Music Effects
+/// ------------------------
+
+boolean I_SetSongSpeed(float speed)
+{
+	if (speed > 250.0f)
+		speed = 250.0f; //limit speed up to 250x
 #ifdef HAVE_LIBGME
 	if (gme)
 	{
-		Mix_HookMusic(NULL, NULL);
-		gme_delete(gme);
-		gme = NULL;
+		SDL_LockAudio();
+		gme_set_tempo(gme, speed);
+		SDL_UnlockAudio();
+		return true;
 	}
+#else
+	(void)speed;
 #endif
-	if (!music)
-		return;
-	Mix_HookMusicFinished(NULL);
-	Mix_FreeMusic(music);
-	music = NULL;
+	return false;
 }
 
-boolean I_StartDigSong(const char *musicname, boolean looping)
+/// ------------------------
+/// Music Playback
+/// ------------------------
+
+boolean I_LoadSong(char *data, size_t len)
 {
-	char *data;
-	size_t len;
-	lumpnum_t lumpnum = W_CheckNumForName(va("O_%s",musicname));
+	const char *key1 = "LOOP";
+	const char *key2 = "POINT=";
+	const char *key3 = "MS=";
+	const size_t key1len = strlen(key1);
+	const size_t key2len = strlen(key2);
+	const size_t key3len = strlen(key3);
+	char *p = data;
+	SDL_RWops *rw;
 
-	I_Assert(!music);
+	if (music
 #ifdef HAVE_LIBGME
-	I_Assert(!gme);
+		|| gme
 #endif
-
-	if (lumpnum == LUMPERROR)
-		return false;
-	midimode = false;
-
-	data = (char *)W_CacheLumpNum(lumpnum, PU_MUSIC);
-	len = W_LumpLength(lumpnum);
+	)
+		I_UnloadSong();
 
 #ifdef HAVE_LIBGME
 	if ((UINT8)data[0] == 0x1F
@@ -621,66 +687,95 @@ boolean I_StartDigSong(const char *musicname, boolean looping)
 		}
 		Z_Free(inflatedData); // GME didn't open jack, but don't let that stop us from freeing this up
 #else
-		//CONS_Alert(CONS_ERROR,"Cannot decompress VGZ; no zlib support\n");
+		CONS_Alert(CONS_ERROR,"Cannot decompress VGZ; no zlib support\n");
+		return true;
 #endif
 	}
 	else if (!gme_open_data(data, len, &gme, 44100))
 	{
 		gme_equalizer_t eq = {GME_TREBLE, GME_BASS, 0,0,0,0,0,0,0,0};
-		gme_start_track(gme, 0);
-		current_track = 0;
 		gme_set_equalizer(gme, &eq);
-		Mix_HookMusic(mix_gme, gme);
 		return true;
 	}
 #endif
 
-	music = Mix_LoadMUS_RW(SDL_RWFromMem(data, len), SDL_FALSE);
+	rw = SDL_RWFromMem(data, len);
+	if (rw != NULL)
+	{
+		music = Mix_LoadMUS_RW(rw, 1);
+	}
 	if (!music)
 	{
 		CONS_Alert(CONS_ERROR, "Mix_LoadMUS_RW: %s\n", Mix_GetError());
-		return true;
+		return false;
 	}
 
 	// Find the OGG loop point.
 	loop_point = 0.0f;
-	if (looping)
+
+	while ((UINT32)(p - data) < len)
 	{
-		const char *key1 = "LOOP";
-		const char *key2 = "POINT=";
-		const char *key3 = "MS=";
-		const size_t key1len = strlen(key1);
-		const size_t key2len = strlen(key2);
-		const size_t key3len = strlen(key3);
-		char *p = data;
-		while ((UINT32)(p - data) < len)
+		if (strncmp(p++, key1, key1len))
+			continue;
+		p += key1len-1; // skip OOP (the L was skipped in strncmp)
+		if (!strncmp(p, key2, key2len)) // is it LOOPPOINT=?
 		{
-			if (strncmp(p++, key1, key1len))
-				continue;
-			p += key1len-1; // skip OOP (the L was skipped in strncmp)
-			if (!strncmp(p, key2, key2len)) // is it LOOPPOINT=?
-			{
-				p += key2len; // skip POINT=
-				loop_point = (float)((44.1L+atoi(p)) / 44100.0L); // LOOPPOINT works by sample count.
-				// because SDL_Mixer is USELESS and can't even tell us
-				// something simple like the frequency of the streaming music,
-				// we are unfortunately forced to assume that ALL MUSIC is 44100hz.
-				// This means a lot of tracks that are only 22050hz for a reasonable downloadable file size will loop VERY badly.
-			}
-			else if (!strncmp(p, key3, key3len)) // is it LOOPMS=?
-			{
-				p += key3len; // skip MS=
-				loop_point = (float)(atoi(p) / 1000.0L); // LOOPMS works by real time, as miliseconds.
-				// Everything that uses LOOPMS will work perfectly with SDL_Mixer.
-			}
-			// Neither?! Continue searching.
+			p += key2len; // skip POINT=
+			loop_point = (float)((44.1L+atoi(p)) / 44100.0L); // LOOPPOINT works by sample count.
+			// because SDL_Mixer is USELESS and can't even tell us
+			// something simple like the frequency of the streaming music,
+			// we are unfortunately forced to assume that ALL MUSIC is 44100hz.
+			// This means a lot of tracks that are only 22050hz for a reasonable downloadable file size will loop VERY badly.
 		}
+		else if (!strncmp(p, key3, key3len)) // is it LOOPMS=?
+		{
+			p += key3len; // skip MS=
+			loop_point = (float)(atoi(p) / 1000.0L); // LOOPMS works by real time, as miliseconds.
+			// Everything that uses LOOPMS will work perfectly with SDL_Mixer.
+		}
+		// Neither?! Continue searching.
 	}
 
+	return true;
+}
+
+void I_UnloadSong(void)
+{
+	I_StopSong();
+
+#ifdef HAVE_LIBGME
+	if (gme)
+	{
+		gme_delete(gme);
+		gme = NULL;
+	}
+#endif
+	if (music)
+	{
+		Mix_FreeMusic(music);
+		music = NULL;
+	}
+}
+
+boolean I_PlaySong(boolean looping)
+{
+#ifdef HAVE_LIBGME
+	if (gme)
+	{
+		gme_start_track(gme, 0);
+		current_track = 0;
+		Mix_HookMusic(mix_gme, gme);
+		return true;
+	}
+	else
+#endif
+	if (!music)
+		return false;
+
 	if (Mix_PlayMusic(music, looping && loop_point == 0.0f ? -1 : 0) == -1)
 	{
 		CONS_Alert(CONS_ERROR, "Mix_PlayMusic: %s\n", Mix_GetError());
-		return true;
+		return false;
 	}
 	Mix_VolumeMusic((UINT32)music_volume*128/31);
 
@@ -689,51 +784,49 @@ boolean I_StartDigSong(const char *musicname, boolean looping)
 	return true;
 }
 
-void I_StopDigSong(void)
+void I_StopSong(void)
 {
-	if (midimode)
-		return;
 #ifdef HAVE_LIBGME
 	if (gme)
 	{
 		Mix_HookMusic(NULL, NULL);
-		gme_delete(gme);
-		gme = NULL;
 		current_track = -1;
-		return;
 	}
 #endif
-	if (!music)
-		return;
-	Mix_HookMusicFinished(NULL);
-	Mix_FreeMusic(music);
-	music = NULL;
-}
-
-void I_SetDigMusicVolume(UINT8 volume)
-{
-	music_volume = volume;
-	if (midimode || !music)
-		return;
-	Mix_VolumeMusic((UINT32)volume*128/31);
-}
-
-boolean I_SetSongSpeed(float speed)
-{
-	if (speed > 250.0f)
-		speed = 250.0f; //limit speed up to 250x
-#ifdef HAVE_LIBGME
-	if (gme)
+	if (music)
 	{
-		SDL_LockAudio();
-		gme_set_tempo(gme, speed);
-		SDL_UnlockAudio();
-		return true;
+		Mix_HookMusicFinished(NULL);
+		Mix_HaltMusic();
 	}
-#else
-	(void)speed;
+}
+
+void I_PauseSong(void)
+{
+	Mix_PauseMusic();
+	songpaused = true;
+}
+
+void I_ResumeSong(void)
+{
+	Mix_ResumeMusic();
+	songpaused = false;
+}
+
+void I_SetMusicVolume(UINT8 volume)
+{
+	if (!I_SongPlaying())
+		return;
+
+#ifdef _WIN32
+	if (I_SongType() == MU_MID)
+		// HACK: Until we stop using native MIDI,
+		// disable volume changes
+		music_volume = 31;
+	else
 #endif
-	return false;
+		music_volume = volume;
+
+	Mix_VolumeMusic((UINT32)music_volume*128/31);
 }
 
 boolean I_SetSongTrack(int track)
@@ -767,79 +860,4 @@ boolean I_SetSongTrack(int track)
 	return false;
 }
 
-//
-// MIDI Music
-//
-
-FUNCMATH void I_InitMIDIMusic(void)
-{
-}
-
-void I_ShutdownMIDIMusic(void)
-{
-	if (!midimode || !music)
-		return;
-	Mix_FreeMusic(music);
-	music = NULL;
-}
-
-void I_SetMIDIMusicVolume(UINT8 volume)
-{
-	// HACK: Until we stop using native MIDI,
-	// disable volume changes
-	(void)volume;
-	midi_volume = 31;
-	//midi_volume = volume;
-
-	if (!midimode || !music)
-		return;
-	Mix_VolumeMusic((UINT32)midi_volume*128/31);
-}
-
-INT32 I_RegisterSong(void *data, size_t len)
-{
-	music = Mix_LoadMUS_RW(SDL_RWFromMem(data, len), SDL_FALSE);
-	if (!music)
-	{
-		CONS_Alert(CONS_ERROR, "Mix_LoadMUS_RW: %s\n", Mix_GetError());
-		return -1;
-	}
-	return 1337;
-}
-
-boolean I_PlaySong(INT32 handle, boolean looping)
-{
-	(void)handle;
-
-	midimode = true;
-
-	if (Mix_PlayMusic(music, looping ? -1 : 0) == -1)
-	{
-		CONS_Alert(CONS_ERROR, "Mix_PlayMusic: %s\n", Mix_GetError());
-		return false;
-	}
-
-	Mix_VolumeMusic((UINT32)midi_volume*128/31);
-	return true;
-}
-
-void I_StopSong(INT32 handle)
-{
-	if (!midimode || !music)
-		return;
-
-	(void)handle;
-	Mix_HaltMusic();
-}
-
-void I_UnRegisterSong(INT32 handle)
-{
-	if (!midimode || !music)
-		return;
-
-	(void)handle;
-	Mix_FreeMusic(music);
-	music = NULL;
-}
-
 #endif
diff --git a/src/sdl/sdl_sound.c b/src/sdl/sdl_sound.c
index 6c70c163b..f4796cd80 100644
--- a/src/sdl/sdl_sound.c
+++ b/src/sdl/sdl_sound.c
@@ -194,8 +194,8 @@ static srb2audio_t localdata;
 static void Snd_LockAudio(void) //Alam: Lock audio data and uninstall audio callback
 {
 	if (Snd_Mutex) SDL_LockMutex(Snd_Mutex);
-	else if (nosound) return;
-	else if (nomidimusic && nodigimusic
+	else if (sound_disabled) return;
+	else if (midi_disabled && digital_disabled
 #ifdef HW3SOUND
 	         && hws_mode == HWS_DEFAULT_MODE
 #endif
@@ -208,8 +208,8 @@ static void Snd_LockAudio(void) //Alam: Lock audio data and uninstall audio call
 static void Snd_UnlockAudio(void) //Alam: Unlock audio data and reinstall audio callback
 {
 	if (Snd_Mutex) SDL_UnlockMutex(Snd_Mutex);
-	else if (nosound) return;
-	else if (nomidimusic && nodigimusic
+	else if (sound_disabled) return;
+	else if (midi_disabled && digital_disabled
 #ifdef HW3SOUND
 	         && hws_mode == HWS_DEFAULT_MODE
 #endif
@@ -219,7 +219,7 @@ static void Snd_UnlockAudio(void) //Alam: Unlock audio data and reinstall audio
 #endif
 }
 
-FUNCMATH static inline Uint16 Snd_LowerRate(Uint16 sr)
+static inline Uint16 Snd_LowerRate(Uint16 sr)
 {
 	if (sr <= audio.freq) // already lowered rate?
 		return sr; // good then
@@ -493,7 +493,7 @@ static inline void I_SetChannels(void)
 
 	INT32 *steptablemid = steptable + 128;
 
-	if (nosound)
+	if (sound_disabled)
 		return;
 
 	// This table provides step widths for pitch parameters.
@@ -604,12 +604,13 @@ void I_FreeSfx(sfxinfo_t * sfx)
 // Pitching (that is, increased speed of playback)
 //  is set, but currently not used by mixing.
 //
-INT32 I_StartSound(sfxenum_t id, UINT8 vol, UINT8 sep, UINT8 pitch, UINT8 priority)
+INT32 I_StartSound(sfxenum_t id, UINT8 vol, UINT8 sep, UINT8 pitch, UINT8 priority, INT32 channel)
 {
 	(void)priority;
 	(void)pitch;
+	(void)channel;
 
-	if (nosound)
+	if (sound_disabled)
 		return 0;
 
 	if (S_sfx[id].data == NULL) return -1;
@@ -989,7 +990,7 @@ FUNCINLINE static ATTRINLINE void I_UpdateStream16M(Uint8 *stream, int len)
 	if (Snd_Mutex) SDL_UnlockMutex(Snd_Mutex);
 }
 
-#ifdef HAVE_LIBGME
+#if 0 //#ifdef HAVE_LIBGME
 static void I_UpdateSteamGME(Music_Emu *emu, INT16 *stream, int len, UINT8 looping)
 {
 	#define GME_BUFFER_LEN 44100*2048
@@ -1049,14 +1050,16 @@ static void SDLCALL I_UpdateStream(void *userdata, Uint8 *stream, int len)
 	else if (audio.channels == 2 && audio.format == AUDIO_S16SYS)
 	{
 		I_UpdateStream16S(stream, len);
-#ifdef HAVE_LIBGME
-		if (userdata)
-		{
-			srb2audio_t *sa_userdata = userdata;
-			if (!sa_userdata->gme_pause)
-				I_UpdateSteamGME(sa_userdata->gme_emu, (INT16 *)stream, len/4, sa_userdata->gme_loop);
-		}
-#endif
+
+		// Crashes! But no matter; this build doesn't play music anyway...
+// #ifdef HAVE_LIBGME
+// 		if (userdata)
+// 		{
+// 			srb2audio_t *sa_userdata = userdata;
+// 			if (!sa_userdata->gme_pause)
+// 				I_UpdateSteamGME(sa_userdata->gme_emu, (INT16 *)stream, len/4, sa_userdata->gme_loop);
+// 		}
+// #endif
 
 	}
 }
@@ -1136,7 +1139,7 @@ static INT32 Init3DSDriver(const char *soName)
 
 void I_ShutdownSound(void)
 {
-	if (nosound || !sound_started)
+	if (sound_disabled || !sound_started)
 		return;
 
 	CONS_Printf("I_ShutdownSound: ");
@@ -1150,7 +1153,7 @@ void I_ShutdownSound(void)
 	}
 #endif
 
-	if (nomidimusic && nodigimusic)
+	if (midi_disabled && digital_disabled)
 		SDL_CloseAudio();
 	CONS_Printf("%s", M_GetText("shut down\n"));
 	sound_started = false;
@@ -1170,7 +1173,7 @@ void I_StartupSound(void)
 	const char *sdrv_name = NULL;
 #endif
 #ifndef HAVE_MIXER
-	nomidimusic = nodigimusic = true;
+	midi_disabled = digital_disabled = true;
 #endif
 
 	memset(channels, 0, sizeof (channels)); //Alam: Clean it
@@ -1213,7 +1216,7 @@ void I_StartupSound(void)
 		audio.samples /= 2;
 	}
 
-	if (nosound)
+	if (sound_disabled)
 		return;
 
 #ifdef HW3SOUND
@@ -1261,7 +1264,7 @@ void I_StartupSound(void)
 		{
 			snddev_t            snddev;
 
-			//nosound = true;
+			//sound_disabled = true;
 			//I_AddExitFunc(I_ShutdownSound);
 			snddev.bps = 16;
 			snddev.sample_rate = audio.freq;
@@ -1288,7 +1291,7 @@ void I_StartupSound(void)
 	if (!musicStarted && SDL_OpenAudio(&audio, &audio) < 0)
 	{
 		CONS_Printf("%s", M_GetText(" couldn't open audio with desired format\n"));
-		nosound = true;
+		sound_disabled = true;
 		return;
 	}
 	else
@@ -1313,13 +1316,11 @@ void I_StartupSound(void)
 // MUSIC API.
 //
 
-void I_ShutdownMIDIMusic(void)
-{
-	nomidimusic = false;
-	if (nodigimusic) I_ShutdownMusic();
-}
+/// ------------------------
+//  MUSIC SYSTEM
+/// ------------------------
 
-#ifdef HAVE_LIBGME
+#if 0 //#ifdef HAVE_LIBGME
 static void I_ShutdownGMEMusic(void)
 {
 	Snd_LockAudio();
@@ -1330,391 +1331,127 @@ static void I_ShutdownGMEMusic(void)
 }
 #endif
 
-void I_ShutdownDigMusic(void)
-{
-	nodigimusic = false;
-	if (nomidimusic) I_ShutdownMusic();
-}
-
-#ifdef HAVE_MIXER
-static boolean LoadSong(void *data, size_t lumplength, size_t selectpos)
-{
-	FILE *midfile;
-	const char *tempname;
-#ifdef USE_RWOPS
-	if (canuseRW)
-	{
-		SDL_RWops *SDLRW;
-		void *olddata = Smidi[selectpos]; //quick shortcut to set
-
-		Z_Free(olddata); //free old memory
-		Smidi[selectpos] = NULL;
-
-		if (!data)
-			return olddata != NULL; //was there old data?
-
-		SDLRW = SDL_RWFromConstMem(data, (int)lumplength); //new RWops from Z_zone
-		if (!SDLRW) //ERROR while making RWops!
-		{
-			CONS_Printf(M_GetText("Couldn't load music lump: %s\n"), SDL_GetError());
-			Z_Free(data);
-			return false;
-		}
-
-		music[selectpos] = Mix_LoadMUS_RW(SDLRW); // new Mix_Chuck from RWops
-		if (music[selectpos])
-			Smidi[selectpos] = data; //all done
-		else //ERROR while making Mix_Chuck
-		{
-			CONS_Printf(M_GetText("Couldn't load music data: %s\n"), Mix_GetError());
-			Z_Free(data);
-			SDL_RWclose(SDLRW);
-			Smidi[selectpos] = NULL;
-		}
-		return true;
-	}
-#endif
-	tempname = va("%s/%s", MIDI_PATH, fmidi[selectpos]);
-
-	if (!data)
-	{
-		if (FIL_FileExists(tempname))
-			return unlink(tempname)+1;
-#ifdef MIDI_PATH2
-		else if (FIL_FileExists(tempname = va("%s/%s", MIDI_PATH2, fmidi[selectpos])))
-			return unlink(tempname)+1;
-#endif
-		else
-			return false;
-	}
-
-	midfile = fopen(tempname, "wb");
-
-#ifdef MIDI_PATH2
-	if (!midfile)
-	{
-		tempname = va("%s/%s", MIDI_PATH2, fmidi[selectpos]);
-		midfile = fopen(tempname, "wb");
-	}
-#endif
-
-	if (!midfile)
-	{
-		CONS_Printf(M_GetText("Couldn't open file %s to write music in\n"), tempname);
-		Z_Free(data);
-		return false;
-	}
-
-	if (fwrite(data, lumplength, 1, midfile) == 0)
-	{
-		CONS_Printf(M_GetText("Couldn't write music into file %s because %s\n"), tempname, strerror(ferror(midfile)));
-		Z_Free(data);
-		fclose(midfile);
-		return false;
-	}
-
-	fclose(midfile);
-
-	Z_Free(data);
-
-	music[selectpos] = Mix_LoadMUS(tempname);
-	if (!music[selectpos]) //ERROR while making Mix_Chuck
-	{
-		CONS_Printf(M_GetText("Couldn't load music file %s: %s\n"), tempname, Mix_GetError());
-		return false;
-	}
-	return true;
-}
-#endif
-
-
-void I_ShutdownMusic(void)
-{
-#ifdef HAVE_MIXER
-	if ((nomidimusic && nodigimusic) || !musicStarted)
-		return;
-
-	CONS_Printf("%s", M_GetText("I_ShutdownMusic: "));
-
-	I_UnRegisterSong(0);
-	I_StopDigSong();
-	Mix_CloseAudio();
-#ifdef MIX_INIT
-	Mix_Quit();
-#endif
-	CONS_Printf("%s", M_GetText("shut down\n"));
-	musicStarted = SDL_FALSE;
-	if (Msc_Mutex)
-		SDL_DestroyMutex(Msc_Mutex);
-	Msc_Mutex = NULL;
-#endif
-}
-
-void I_InitMIDIMusic(void)
-{
-	if (nodigimusic) I_InitMusic();
-}
-
-void I_InitDigMusic(void)
-{
-	if (nomidimusic) I_InitMusic();
-}
-
 void I_InitMusic(void)
 {
-#ifdef HAVE_MIXER
-	char ad[100];
-	SDL_version MIXcompiled;
-	const SDL_version *MIXlinked;
-#ifdef MIXER_INIT
-	const int mixstart = MIX_INIT_OGG;
-	int mixflags;
-#endif
-#endif
-#ifdef HAVE_LIBGME
+#if 0 //#ifdef HAVE_LIBGME
 	I_AddExitFunc(I_ShutdownGMEMusic);
 #endif
-
-#ifdef HAVE_MIXER
-	MIX_VERSION(&MIXcompiled)
-	MIXlinked = Mix_Linked_Version();
-	I_OutputMsg("Compiled for SDL_mixer version: %d.%d.%d\n",
-	            MIXcompiled.major, MIXcompiled.minor, MIXcompiled.patch);
-#ifdef MIXER_POS
-	if (MIXlinked->major == 1 && MIXlinked->minor == 2 && MIXlinked->patch < 7)
-		canlooping = SDL_FALSE;
-#endif
-#ifdef USE_RWOPS
-	if (M_CheckParm("-noRW"))
-		canuseRW = SDL_FALSE;
-#endif
-	I_OutputMsg("Linked with SDL_mixer version: %d.%d.%d\n",
-	            MIXlinked->major, MIXlinked->minor, MIXlinked->patch);
-	if (audio.freq < 44100 && !M_CheckParm ("-freq")) //I want atleast 44Khz
-	{
-		audio.samples = (Uint16)(audio.samples*(INT32)(44100/audio.freq));
-		audio.freq = 44100; //Alam: to keep it around the same XX ms
-	}
-
-	if (sound_started
-#ifdef HW3SOUND
-		&& hws_mode == HWS_DEFAULT_MODE
-#endif
-		)
-	{
-		I_OutputMsg("Temp Shutdown of SDL Audio System");
-		SDL_CloseAudio();
-		I_OutputMsg(" Done\n");
-	}
-
-	CONS_Printf("%s", M_GetText("I_InitMusic:"));
-
-#ifdef MIXER_INIT
-	mixflags = Mix_Init(mixstart);
-	if ((mixstart & MIX_INIT_FLAC) != (mixflags & MIX_INIT_FLAC))
-	{
-		CONS_Printf("%s", M_GetText(" Unable to load FLAC support\n"));
-	}
-	if ((mixstart & MIX_INIT_MOD ) != (mixflags & MIX_INIT_MOD ))
-	{
-		CONS_Printf("%s", M_GetText(" Unable to load MOD support\n"));
-	}
-	if ((mixstart & MIX_INIT_MP3 ) != (mixflags & MIX_INIT_MP3 ))
-	{
-		CONS_Printf("%s", M_GetText(" Unable to load MP3 support\n"));
-	}
-	if ((mixstart & MIX_INIT_OGG ) != (mixflags & MIX_INIT_OGG ))
-	{
-		CONS_Printf("%s", M_GetText(" Unable to load OGG support\n"));
-	}
-#endif
-
-	if (Mix_OpenAudio(audio.freq, audio.format, audio.channels, audio.samples) < 0) //open_music(&audio)
-	{
-		CONS_Printf(M_GetText(" Unable to open music: %s\n"), Mix_GetError());
-		nomidimusic = nodigimusic = true;
-		if (sound_started
-#ifdef HW3SOUND
-			&& hws_mode == HWS_DEFAULT_MODE
-#endif
-			)
-		{
-			if (SDL_OpenAudio(&audio, NULL) < 0) //retry
-			{
-				CONS_Printf("%s", M_GetText(" couldn't open audio with desired format\n"));
-				nosound = true;
-				sound_started = false;
-			}
-			else
-			{
-				CONS_Printf(M_GetText(" Starting with audio driver : %s\n"), SDL_AudioDriverName(ad, (int)sizeof ad));
-			}
-		}
-		return;
-	}
-	else
-		CONS_Printf(M_GetText(" Starting up with audio driver : %s with SDL_Mixer\n"), SDL_AudioDriverName(ad, (int)sizeof ad));
-
-	samplecount = audio.samples;
-	CV_SetValue(&cv_samplerate, audio.freq);
-	if (sound_started
-#ifdef HW3SOUND
-		&& hws_mode == HWS_DEFAULT_MODE
-#endif
-		)
-		I_OutputMsg(" Reconfigured SDL Audio System");
-	else I_OutputMsg(" Configured SDL_Mixer System");
-	I_OutputMsg(" with %d samples/slice at %ikhz(%dms buffer)\n", samplecount, audio.freq/1000, (INT32) ((audio.samples * 1000.0f) / audio.freq));
-	Mix_SetPostMix(audio.callback, audio.userdata);  // after mixing music, add sound effects
-	Mix_Resume(-1);
-	CONS_Printf("%s", M_GetText("Music initialized\n"));
-	musicStarted = SDL_TRUE;
-	Msc_Mutex = SDL_CreateMutex();
-#endif
 }
 
-boolean I_PlaySong(INT32 handle, boolean looping)
+void I_ShutdownMusic(void) { }
+
+/// ------------------------
+//  MUSIC PROPERTIES
+/// ------------------------
+
+musictype_t I_SongType(void)
 {
-	(void)handle;
-#ifdef HAVE_MIXER
-	if (nomidimusic || !musicStarted || !music[handle])
-		return false;
+	return MU_NONE;
+}
 
-#ifdef MIXER_POS
-	if (canlooping)
-		Mix_HookMusicFinished(NULL);
-#endif
-
-	if (Mix_FadeInMusic(music[handle], looping ? -1 : 0, MIDIfade) == -1)
-		CONS_Printf(M_GetText("Couldn't play song because %s\n"), Mix_GetError());
-	else
-	{
-		Mix_VolumeMusic(musicvol);
-		return true;
-	}
-#else
-	(void)looping;
-#endif
+boolean I_SongPlaying(void)
+{
 	return false;
 }
 
+boolean I_SongPaused(void)
+{
+	return false;
+}
+
+/// ------------------------
+//  MUSIC EFFECTS
+/// ------------------------
+
+boolean I_SetSongSpeed(float speed)
+{
+	(void)speed;
+	return false;
+}
+
+/// ------------------------
+//  MUSIC PLAYBACK
+/// ------------------------
+
+#if 0 //#ifdef HAVE_LIBGME
+static void I_StopGME(void)
+{
+	Snd_LockAudio();
+	gme_seek(localdata.gme_emu, 0);
+	Snd_UnlockAudio();
+}
+
 static void I_PauseGME(void)
 {
-#ifdef HAVE_LIBGME
 	localdata.gme_pause = true;
-#endif
-}
-
-void I_PauseSong(INT32 handle)
-{
-	(void)handle;
-	I_PauseGME();
-#ifdef HAVE_MIXER
-	if ((nomidimusic && nodigimusic) || !musicStarted)
-		return;
-
-	Mix_PauseMusic();
-	//I_StopSong(handle);
-#endif
 }
 
 static void I_ResumeGME(void)
 {
-#ifdef HAVE_LIBGME
 	localdata.gme_pause = false;
-#endif
 }
-
-void I_ResumeSong(INT32 handle)
-{
-	(void)handle;
-	I_ResumeGME();
-#ifdef HAVE_MIXER
-	if ((nomidimusic && nodigimusic) || !musicStarted)
-		return;
-
-	Mix_VolumeMusic(musicvol);
-	Mix_ResumeMusic();
-	//I_PlaySong(handle, true);
 #endif
-}
 
-void I_StopSong(INT32 handle)
+boolean I_LoadSong(char *data, size_t len)
 {
-	(void)handle;
-#ifdef HAVE_MIXER
-	if (nomidimusic || !musicStarted)
-		return;
-	Mix_FadeOutMusic(MIDIfade);
-#endif
-}
-
-void I_UnRegisterSong(INT32 handle)
-{
-#ifdef HAVE_MIXER
-
-	if (nomidimusic || !musicStarted)
-		return;
-
-	Mix_HaltMusic();
-	while (Mix_PlayingMusic())
-		;
-
-	if (music[handle])
-		Mix_FreeMusic(music[handle]);
-	music[handle] = NULL;
-	LoadSong(NULL, 0, handle);
-#else
-	(void)handle;
-#endif
-}
-
-INT32 I_RegisterSong(void *data, size_t len)
-{
-#ifdef HAVE_MIXER
-	if (nomidimusic || !musicStarted)
-		return false;
-
-	if (!LoadSong(data, len, 0))
-		return false;
-
-	if (music[0])
-		return true;
-
-	CONS_Printf(M_GetText("Couldn't load MIDI: %s\n"), Mix_GetError());
-#else
-	(void)len;
-	(void)data;
-#endif
 	return false;
 }
 
-void I_SetMIDIMusicVolume(UINT8 volume)
-{
-#ifdef HAVE_MIXER
-	if ((nomidimusic && nodigimusic) || !musicStarted)
-		return;
+void I_UnloadSong(void) { }
 
-	if (Msc_Mutex) SDL_LockMutex(Msc_Mutex);
-	musicvol = volume * 2;
-	if (Msc_Mutex) SDL_UnlockMutex(Msc_Mutex);
-	Mix_VolumeMusic(musicvol);
-#else
-	(void)volume;
+boolean I_PlaySong(boolean looping)
+{
+	(void)looping;
+	return false;
+}
+
+void I_StopSong(void)
+{
+#if 0 //#ifdef HAVE_LIBGME
+	I_StopGME();
 #endif
 }
 
-#ifdef HAVE_LIBGME
+void I_PauseSong(void)
+{
+#if 0 //#ifdef HAVE_LIBGME
+	I_PauseGME();
+#endif
+}
+
+void I_ResumeSong(void)
+{
+#if 0
+	I_ResumeGME();
+#endif
+}
+
+void I_SetMusicVolume(UINT8 volume)
+{
+	(void)volume;
+}
+
+boolean I_SetSongTrack(int track)
+{
+	(void)track;
+	return false;
+}
+
+/// ------------------------
+//  MUSIC LOADING AND CLEANUP
+//  \todo Split logic between loading and playing,
+//        then move to Playback section
+/// ------------------------
+
+#if 0 //#ifdef HAVE_LIBGME
 static void I_CleanupGME(void *userdata)
 {
 	Z_Free(userdata);
 }
-#endif
 
 static boolean I_StartGMESong(const char *musicname, boolean looping)
 {
-#ifdef HAVE_LIBGME
-	XBOXSTATIC char filename[9];
+	char filename[9];
 	void *data;
 	lumpnum_t lumpnum;
 	size_t lumplength;
@@ -1759,240 +1496,7 @@ static boolean I_StartGMESong(const char *musicname, boolean looping)
 	Snd_UnlockAudio();
 
 	return true;
-#else
-	(void)musicname;
-	(void)looping;
-#endif
-	return false;
-}
-
-boolean I_StartDigSong(const char *musicname, boolean looping)
-{
-#ifdef HAVE_MIXER
-	XBOXSTATIC char filename[9];
-	void *data;
-	lumpnum_t lumpnum;
-	size_t lumplength;
-#endif
-
-	if(I_StartGMESong(musicname, looping))
-		return true;
-
-#ifdef HAVE_MIXER
-	if (nodigimusic)
-		return false;
-
-	snprintf(filename, sizeof filename, "o_%s", musicname);
-
-	lumpnum = W_CheckNumForName(filename);
-
-	I_StopDigSong();
-
-	if (lumpnum == LUMPERROR)
-	{
-		// Alam_GBC: like in win32/win_snd.c: Graue 02-29-2004: don't worry about missing music, there might still be a MIDI
-		//I_OutputMsg("Music lump %s not found!\n", filename);
-		return false; // No music found. Oh well!
-	}
-	else
-		lumplength = W_LumpLength(lumpnum);
-
-	data = W_CacheLumpNum(lumpnum, PU_MUSIC);
-
-	if (Msc_Mutex) SDL_LockMutex(Msc_Mutex);
-
-#ifdef MIXER_POS
-	if (canlooping && (loopingDig = looping) == SDL_TRUE && strcmp(data, "OggS")  == 0)
-		looping = false; // Only on looping Ogg files, will we will do our own looping
-
-	// Scan the Ogg Vorbis file for the COMMENT= field for a custom
-	// loop point
-	if (!looping && loopingDig)
-	{
-		size_t scan;
-		const char *dataum = data;
-		XBOXSTATIC char looplength[64];
-		UINT32 loopstart = 0;
-		UINT8 newcount = 0;
-
-		Mix_HookMusicFinished(I_FinishMusic);
-
-		for (scan = 0; scan < lumplength; scan++)
-		{
-			if (*dataum++ == 'C'){
-			if (*dataum++ == 'O'){
-			if (*dataum++ == 'M'){
-			if (*dataum++ == 'M'){
-			if (*dataum++ == 'E'){
-			if (*dataum++ == 'N'){
-			if (*dataum++ == 'T'){
-			if (*dataum++ == '='){
-			if (*dataum++ == 'L'){
-			if (*dataum++ == 'O'){
-			if (*dataum++ == 'O'){
-			if (*dataum++ == 'P'){
-			if (*dataum++ == 'P'){
-			if (*dataum++ == 'O'){
-			if (*dataum++ == 'I'){
-			if (*dataum++ == 'N'){
-			if (*dataum++ == 'T'){
-			if (*dataum++ == '=')
-			{
-
-				while (*dataum != 1 && newcount != 63)
-					looplength[newcount++] = *dataum++;
-
-				looplength[newcount] = '\0';
-
-				loopstart = atoi(looplength);
-
-			}
-			else
-				dataum--;}
-			else
-				dataum--;}
-			else
-				dataum--;}
-			else
-				dataum--;}
-			else
-				dataum--;}
-			else
-				dataum--;}
-			else
-				dataum--;}
-			else
-				dataum--;}
-			else
-				dataum--;}
-			else
-				dataum--;}
-			else
-				dataum--;}
-			else
-				dataum--;}
-			else
-				dataum--;}
-			else
-				dataum--;}
-			else
-				dataum--;}
-			else
-				dataum--;}
-			else
-				dataum--;}
-		}
-
-		if (loopstart > 0)
-		{
-			loopstartDig = (double)((44.1l+loopstart) / 44100.0l); //8 PCM chucks off and PCM to secs
-//#ifdef PARANOIA
-			//I_OutputMsg("I_StartDigSong: setting looping point to %ul PCMs(%f seconds)\n", loopstart, loopstartDig);
-//#endif
-		}
-		else
-		{
-			looping = true; // loopingDig true, but couldn't find start loop point
-		}
-	}
-	else
-		loopstartDig = 0.0l;
-#else
-	if (looping && strcmp(data, "OggS")  == 0)
-		I_OutputMsg("I_StartDigSong: SRB2 was not compiled with looping music support(no Mix_FadeInMusicPos)\n");
-#endif
-
-	if (!LoadSong(data, lumplength, 1))
-	{
-		if (Msc_Mutex) SDL_UnlockMutex(Msc_Mutex);
-		return false;
-	}
-
-	// Note: LoadSong() frees the data. Let's make sure
-	// we don't try to use the data again.
-	data = NULL;
-
-	if (Mix_FadeInMusic(music[1], looping ? -1 : 0, Digfade) == -1)
-	{
-		if (Msc_Mutex) SDL_UnlockMutex(Msc_Mutex);
-		I_OutputMsg("I_StartDigSong: Couldn't play song %s because %s\n", musicname, Mix_GetError());
-		return false;
-	}
-	Mix_VolumeMusic(musicvol);
-
-	if (Msc_Mutex) SDL_UnlockMutex(Msc_Mutex);
-	return true;
-#else
-	(void)looping;
-	(void)musicname;
-	return false;
-#endif
-}
-
-static void I_StopGME(void)
-{
-#ifdef HAVE_LIBGME
-	Snd_LockAudio();
-	gme_seek(localdata.gme_emu, 0);
-	Snd_UnlockAudio();
-#endif
-}
-
-void I_StopDigSong(void)
-{
-	I_StopGME();
-#ifdef HAVE_MIXER
-	if (nodigimusic)
-		return;
-
-#ifdef MIXER_POS
-	if (canlooping)
-		Mix_HookMusicFinished(NULL);
-#endif
-
-	Mix_HaltMusic();
-	while (Mix_PlayingMusic())
-		;
-
-	if (music[1])
-		Mix_FreeMusic(music[1]);
-	music[1] = NULL;
-	LoadSong(NULL, 0, 1);
-#endif
-}
-
-void I_SetDigMusicVolume(UINT8 volume)
-{
-	I_SetMIDIMusicVolume(volume);
-}
-
-boolean I_SetSongSpeed(float speed)
-{
-
-	(void)speed;
-	return false;
-}
-
-boolean I_SetSongTrack(int track)
-{
-	(void)track;
-	return false;
-}
-
-#ifdef MIXER_POS
-static void SDLCALL I_FinishMusic(void)
-{
-	if (!music[1])
-		return;
-	else if (Msc_Mutex) SDL_LockMutex(Msc_Mutex);
-//		I_OutputMsg("I_FinishMusic: Loopping song to %g seconds\n", loopstartDig);
-
-	if (Mix_FadeInMusicPos(music[1], loopstartDig ? 0 : -1, Digfade, loopstartDig) == 0)
-		Mix_VolumeMusic(musicvol);
-	else
-		I_OutputMsg("I_FinishMusic: Couldn't loop song because %s\n", Mix_GetError());
-
-	if (Msc_Mutex) SDL_UnlockMutex(Msc_Mutex);
 }
 #endif
-#endif //HAVE_SDL
+
+#endif //HAVE_SDL
\ No newline at end of file
diff --git a/src/sdl/sdlmain.h b/src/sdl/sdlmain.h
index fea1e1648..d12daaa8a 100644
--- a/src/sdl/sdlmain.h
+++ b/src/sdl/sdlmain.h
@@ -1,7 +1,7 @@
 // Emacs style mode select   -*- C++ -*-
 //-----------------------------------------------------------------------------
 //
-// Copyright (C) 2006 by Sonic Team Jr.
+// Copyright (C) 2006-2018 by Sonic Team Jr.
 //
 // This program is free software; you can redistribute it and/or
 // modify it under the terms of the GNU General Public License
diff --git a/src/sdl12/SRB2CE/cehelp.c b/src/sdl12/SRB2CE/cehelp.c
index 7c5efdee9..13505cff7 100644
--- a/src/sdl12/SRB2CE/cehelp.c
+++ b/src/sdl12/SRB2CE/cehelp.c
@@ -1,7 +1,7 @@
 // Emacs style mode select   -*- C++ -*-
 //-----------------------------------------------------------------------------
 //
-// Copyright (C) 2004 by Sonic Team Jr.
+// Copyright (C) 2004-2018 by Sonic Team Jr.
 //
 // This program is free software; you can redistribute it and/or
 // modify it under the terms of the GNU General Public License
diff --git a/src/sdl12/SRB2CE/cehelp.h b/src/sdl12/SRB2CE/cehelp.h
index bc265b058..3ed0d9dd4 100644
--- a/src/sdl12/SRB2CE/cehelp.h
+++ b/src/sdl12/SRB2CE/cehelp.h
@@ -1,7 +1,7 @@
 // Emacs style mode select   -*- C++ -*-
 //-----------------------------------------------------------------------------
 //
-// Copyright (C) 2004 by Sonic Team Jr.
+// Copyright (C) 2004-2018 by Sonic Team Jr.
 //
 // This program is free software; you can redistribute it and/or
 // modify it under the terms of the GNU General Public License
diff --git a/src/sdl12/SRB2DC/dchelp.c b/src/sdl12/SRB2DC/dchelp.c
index 5fdf04bc2..1468baa8b 100644
--- a/src/sdl12/SRB2DC/dchelp.c
+++ b/src/sdl12/SRB2DC/dchelp.c
@@ -1,7 +1,7 @@
 // Emacs style mode select   -*- C++ -*-
 //-----------------------------------------------------------------------------
 //
-// Copyright (C) 2006 by Sonic Team Jr.
+// Copyright (C) 2006-2018 by Sonic Team Jr.
 //
 // This program is free software; you can redistribute it and/or
 // modify it under the terms of the GNU General Public License
diff --git a/src/sdl12/SRB2DC/dchelp.h b/src/sdl12/SRB2DC/dchelp.h
index 236f31110..3647f9c89 100644
--- a/src/sdl12/SRB2DC/dchelp.h
+++ b/src/sdl12/SRB2DC/dchelp.h
@@ -1,7 +1,7 @@
 // Emacs style mode select   -*- C++ -*-
 //-----------------------------------------------------------------------------
 //
-// Copyright (C) 2006 by Sonic Team Jr.
+// Copyright (C) 2006-2018 by Sonic Team Jr.
 //
 // This program is free software; you can redistribute it and/or
 // modify it under the terms of the GNU General Public License
diff --git a/src/sdl12/SRB2DC/i_udp.c b/src/sdl12/SRB2DC/i_udp.c
index ec5e305fc..cf7654c10 100644
--- a/src/sdl12/SRB2DC/i_udp.c
+++ b/src/sdl12/SRB2DC/i_udp.c
@@ -1,7 +1,7 @@
 // Emacs style mode select   -*- C++ -*-
 //-----------------------------------------------------------------------------
 // Copyright (C) 1993-1996 by id Software, Inc.
-// Portions Copyright (C) 2005 by Sonic Team Jr.
+// Portions Copyright (C) 2005-2018 by Sonic Team Jr.
 //
 // This program is free software; you can redistribute it and/or
 // modify it under the terms of the GNU General Public License
diff --git a/src/sdl12/SRB2XBOX/xboxhelp.c b/src/sdl12/SRB2XBOX/xboxhelp.c
index 9de01712f..05b6c5e68 100644
--- a/src/sdl12/SRB2XBOX/xboxhelp.c
+++ b/src/sdl12/SRB2XBOX/xboxhelp.c
@@ -1,7 +1,7 @@
 // Emacs style mode select   -*- C++ -*-
 //-----------------------------------------------------------------------------
 //
-// Copyright (C) 2004 by Sonic Team Jr.
+// Copyright (C) 2004-2018 by Sonic Team Jr.
 //
 // This program is free software; you can redistribute it and/or
 // modify it under the terms of the GNU General Public License
diff --git a/src/sdl12/i_system.c b/src/sdl12/i_system.c
index ed0db653d..8729e5921 100644
--- a/src/sdl12/i_system.c
+++ b/src/sdl12/i_system.c
@@ -2301,6 +2301,8 @@ void I_Quit(void)
 		printf("\r");
 		ShowEndTxt();
 	}
+	if (myargmalloc)
+		free(myargv); // Deallocate allocated memory
 death:
 	W_Shutdown();
 #ifdef GP2X
diff --git a/src/sdl12/mixer_sound.c b/src/sdl12/mixer_sound.c
index 542a67169..dcae19b05 100644
--- a/src/sdl12/mixer_sound.c
+++ b/src/sdl12/mixer_sound.c
@@ -1,3 +1,11 @@
+// SONIC ROBO BLAST 2
+//-----------------------------------------------------------------------------
+// Copyright (C) 2008-2018 by Sonic Team Junior.
+//
+// This program is free software distributed under the
+// terms of the GNU General Public License, version 2.
+// See the 'LICENSE' file for more details.
+//-----------------------------------------------------------------------------
 /// \file
 /// \brief SDL Mixer interface for sound
 
@@ -376,10 +384,10 @@ void I_FreeSfx(sfxinfo_t *sfx)
 	sfx->data = NULL;
 }
 
-INT32 I_StartSound(sfxenum_t id, UINT8 vol, UINT8 sep, UINT8 pitch, UINT8 priority)
+INT32 I_StartSound(sfxenum_t id, UINT8 vol, UINT8 sep, UINT8 pitch, UINT8 priority, INT32 channel)
 {
 	UINT8 volume = (((UINT16)vol + 1) * (UINT16)sfx_volume) / 62; // (256 * 31) / 62 == 127
-	INT32 handle = Mix_PlayChannel(-1, S_sfx[id].data, 0);
+	INT32 handle = Mix_PlayChannel(channel, S_sfx[id].data, 0);
 	Mix_Volume(handle, volume);
 	Mix_SetPanning(handle, min((UINT16)(0xff-sep)<<1, 0xff), min((UINT16)(sep)<<1, 0xff));
 	(void)pitch; // Mixer can't handle pitch
diff --git a/src/sdl12/sdl_sound.c b/src/sdl12/sdl_sound.c
index 6ba83104e..ed1afd8e2 100644
--- a/src/sdl12/sdl_sound.c
+++ b/src/sdl12/sdl_sound.c
@@ -236,7 +236,7 @@ static void Snd_UnlockAudio(void) //Alam: Unlock audio data and reinstall audio
 #endif
 }
 
-FUNCMATH static inline Uint16 Snd_LowerRate(Uint16 sr)
+static inline Uint16 Snd_LowerRate(Uint16 sr)
 {
 	if (sr <= audio.freq) // already lowered rate?
 		return sr; // good then
@@ -621,10 +621,11 @@ void I_FreeSfx(sfxinfo_t * sfx)
 // Pitching (that is, increased speed of playback)
 //  is set, but currently not used by mixing.
 //
-INT32 I_StartSound(sfxenum_t id, UINT8 vol, UINT8 sep, UINT8 pitch, UINT8 priority)
+INT32 I_StartSound(sfxenum_t id, UINT8 vol, UINT8 sep, UINT8 pitch, UINT8 priority, INT32 channel)
 {
 	(void)priority;
 	(void)pitch;
+	(void)channel;
 
 	if (nosound)
 		return 0;
diff --git a/src/sdl12/sdlmain.h b/src/sdl12/sdlmain.h
index 1e497b10d..d08236bdd 100644
--- a/src/sdl12/sdlmain.h
+++ b/src/sdl12/sdlmain.h
@@ -1,7 +1,7 @@
 // Emacs style mode select   -*- C++ -*-
 //-----------------------------------------------------------------------------
 //
-// Copyright (C) 2006 by Sonic Team Jr.
+// Copyright (C) 2006-2018 by Sonic Team Jr.
 //
 // This program is free software; you can redistribute it and/or
 // modify it under the terms of the GNU General Public License
diff --git a/src/sounds.c b/src/sounds.c
index 53e3b6187..47dc28178 100644
--- a/src/sounds.c
+++ b/src/sounds.c
@@ -2,7 +2,7 @@
 //-----------------------------------------------------------------------------
 // Copyright (C) 1993-1996 by id Software, Inc.
 // Copyright (C) 1998-2000 by DooM Legacy Team.
-// Copyright (C) 1999-2016 by Sonic Team Junior.
+// Copyright (C) 1999-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
diff --git a/src/sounds.h b/src/sounds.h
index 565d41b56..495a55a1e 100644
--- a/src/sounds.h
+++ b/src/sounds.h
@@ -2,7 +2,7 @@
 //-----------------------------------------------------------------------------
 // Copyright (C) 1993-1996 by id Software, Inc.
 // Copyright (C) 1998-2000 by DooM Legacy Team.
-// Copyright (C) 1999-2016 by Sonic Team Junior.
+// Copyright (C) 1999-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
diff --git a/src/st_stuff.c b/src/st_stuff.c
index 72e0b6b94..f2e62feda 100644
--- a/src/st_stuff.c
+++ b/src/st_stuff.c
@@ -2,7 +2,7 @@
 //-----------------------------------------------------------------------------
 // Copyright (C) 1993-1996 by id Software, Inc.
 // Copyright (C) 1998-2000 by DooM Legacy Team.
-// Copyright (C) 1999-2016 by Sonic Team Junior.
+// Copyright (C) 1999-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
diff --git a/src/st_stuff.h b/src/st_stuff.h
index c11559d2b..6c4140ce3 100644
--- a/src/st_stuff.h
+++ b/src/st_stuff.h
@@ -2,7 +2,7 @@
 //-----------------------------------------------------------------------------
 // Copyright (C) 1993-1996 by id Software, Inc.
 // Copyright (C) 1998-2000 by DooM Legacy Team.
-// Copyright (C) 1999-2016 by Sonic Team Junior.
+// Copyright (C) 1999-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
@@ -24,7 +24,7 @@
 //
 
 // Called by main loop.
-FUNCMATH void ST_Ticker(void);
+void ST_Ticker(void);
 
 // Called by main loop.
 void ST_Drawer(void);
diff --git a/src/string.c b/src/string.c
index d7f8b3679..2a03e8729 100644
--- a/src/string.c
+++ b/src/string.c
@@ -1,7 +1,7 @@
 // SONIC ROBO BLAST 2
 //-----------------------------------------------------------------------------
 // Copyright (C) 2006      by Graue.
-// Copyright (C) 2006-2016 by Sonic Team Junior.
+// Copyright (C) 2006-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
diff --git a/src/tables.c b/src/tables.c
index 6b06c81b4..d4e0e5df6 100644
--- a/src/tables.c
+++ b/src/tables.c
@@ -2,7 +2,7 @@
 //-----------------------------------------------------------------------------
 // Copyright (C) 1993-1996 by id Software, Inc.
 // Copyright (C) 1998-2000 by DooM Legacy Team.
-// Copyright (C) 1999-2016 by Sonic Team Junior.
+// Copyright (C) 1999-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
diff --git a/src/tables.h b/src/tables.h
index e05b81845..1ea49a62f 100644
--- a/src/tables.h
+++ b/src/tables.h
@@ -2,7 +2,7 @@
 //-----------------------------------------------------------------------------
 // Copyright (C) 1993-1996 by id Software, Inc.
 // Copyright (C) 1998-2000 by DooM Legacy Team.
-// Copyright (C) 1999-2016 by Sonic Team Junior.
+// Copyright (C) 1999-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
diff --git a/src/tmap.nas b/src/tmap.nas
index 16f53f535..78840106f 100644
--- a/src/tmap.nas
+++ b/src/tmap.nas
@@ -1,7 +1,7 @@
 ;; SONIC ROBO BLAST 2
 ;;-----------------------------------------------------------------------------
 ;; Copyright (C) 1998-2000 by DooM Legacy Team.
-;; Copyright (C) 1999-2016 by Sonic Team Junior.
+;; Copyright (C) 1999-2018 by Sonic Team Junior.
 ;;
 ;; This program is free software distributed under the
 ;; terms of the GNU General Public License, version 2.
diff --git a/src/tmap.s b/src/tmap.s
index a828a9d46..babd4ec1a 100644
--- a/src/tmap.s
+++ b/src/tmap.s
@@ -1,7 +1,7 @@
 // SONIC ROBO BLAST 2
 //-----------------------------------------------------------------------------
 // Copyright (C) 1998-2000 by DooM Legacy Team.
-// Copyright (C) 1999-2016 by Sonic Team Junior.
+// Copyright (C) 1999-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
@@ -13,7 +13,7 @@
 // structures, must match the C structures!
 #include "asm_defs.inc"
 
-// Rappel: seuls EAX, ECX, EDX peuvent �tre �cras�s librement.
+// Rappel: seuls EAX, ECX, EDX peuvent �tre �cras�s librement.
 //         il faut sauver esi,edi, cd...gs
 
 /* Attention aux comparaisons!                                              */
@@ -28,7 +28,7 @@
 /*              cmp     A,B                     // B-A , set flags          */
 /*              jg      B_greater_than_A                                    */
 /*                                                                          */
-/*        (soustrait l'op�rande source DE l'op�rande destination,           */
+/*        (soustrait l'op�rande source DE l'op�rande destination,           */
 /*         comme sur Motorola! )                                            */
 
 // RAPPEL: Intel
@@ -66,7 +66,7 @@ C(vidwidth):    .long   0       //use this one out of the inner loops
 .globl C(ASM_PatchRowBytes)
 C(ASM_PatchRowBytes):
     pushl   %ebp
-    movl    %esp, %ebp      // assure l'"adressabilit� du stack"
+    movl    %esp, %ebp      // assure l'"adressabilit� du stack"
 
     movl    ARG1, %edx         // read first arg
     movl    %edx, C(vidwidth)
diff --git a/src/tmap_asm.s b/src/tmap_asm.s
index e8b7af1cd..99cb0b627 100644
--- a/src/tmap_asm.s
+++ b/src/tmap_asm.s
@@ -1,7 +1,7 @@
 // SONIC ROBO BLAST 2
 //-----------------------------------------------------------------------------
 // Copyright (C) 1998-2000 by DooM Legacy Team.
-// Copyright (C) 1999-2016 by Sonic Team Junior.
+// Copyright (C) 1999-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
diff --git a/src/tmap_mmx.nas b/src/tmap_mmx.nas
index 187beec71..39380a065 100644
--- a/src/tmap_mmx.nas
+++ b/src/tmap_mmx.nas
@@ -1,7 +1,7 @@
 ;; SONIC ROBO BLAST 2
 ;;-----------------------------------------------------------------------------
 ;; Copyright (C) 1998-2000 by DOSDOOM.
-;; Copyright (C) 2010-2016 by Sonic Team Junior.
+;; Copyright (C) 2010-2018 by Sonic Team Junior.
 ;;
 ;; This program is free software distributed under the
 ;; terms of the GNU General Public License, version 2.
diff --git a/src/tmap_vc.nas b/src/tmap_vc.nas
index 8fe39ec89..e943d48d8 100644
--- a/src/tmap_vc.nas
+++ b/src/tmap_vc.nas
@@ -1,7 +1,7 @@
 ;; SONIC ROBO BLAST 2
 ;;-----------------------------------------------------------------------------
 ;; Copyright (C) 1998-2000 by DooM Legacy Team.
-;; Copyright (C) 1999-2016 by Sonic Team Junior.
+;; Copyright (C) 1999-2018 by Sonic Team Junior.
 ;;
 ;; This program is free software distributed under the
 ;; terms of the GNU General Public License, version 2.
diff --git a/src/v_video.c b/src/v_video.c
index aa2852c01..35b848f98 100644
--- a/src/v_video.c
+++ b/src/v_video.c
@@ -2,7 +2,7 @@
 //-----------------------------------------------------------------------------
 // Copyright (C) 1993-1996 by id Software, Inc.
 // Copyright (C) 1998-2000 by DooM Legacy Team.
-// Copyright (C) 1999-2016 by Sonic Team Junior.
+// Copyright (C) 1999-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
@@ -331,7 +331,6 @@ void V_DrawFixedPatch(fixed_t x, fixed_t y, fixed_t pscale, INT32 scrn, patch_t
 {
 	UINT8 (*patchdrawfunc)(const UINT8*, const UINT8*, fixed_t);
 	UINT32 alphalevel = 0;
-	boolean flip = false;
 
 	fixed_t col, ofs, colfrac, rowfrac, fdup;
 	INT32 dupx, dupy;
@@ -345,8 +344,8 @@ void V_DrawFixedPatch(fixed_t x, fixed_t y, fixed_t pscale, INT32 scrn, patch_t
 		return;
 
 #ifdef HWRENDER
-	// oh please
-	if (rendermode != render_soft && !con_startup)
+	//if (rendermode != render_soft && !con_startup)		// Why?
+	if (rendermode != render_soft)
 	{
 		HWR_DrawFixedPatch((GLPatch_t *)patch, x, y, pscale, scrn, colormap);
 		return;
@@ -406,22 +405,32 @@ void V_DrawFixedPatch(fixed_t x, fixed_t y, fixed_t pscale, INT32 scrn, patch_t
 	colfrac = FixedDiv(FRACUNIT, fdup);
 	rowfrac = FixedDiv(FRACUNIT, fdup);
 
-	if (scrn & V_OFFSET) // Crosshair shit
+	// So it turns out offsets aren't scaled in V_NOSCALESTART unless V_OFFSET is applied ...poo, that's terrible
+	// For now let's just at least give V_OFFSET the ability to support V_FLIP
+	// I'll probably make a better fix for 2.2 where I don't have to worry about breaking existing support for stuff
+	// -- Monster Iestyn 29/10/18
 	{
-		y -= FixedMul((SHORT(patch->topoffset)*dupy)<<FRACBITS,  pscale);
-		x -= FixedMul((SHORT(patch->leftoffset)*dupx)<<FRACBITS, pscale);
-	}
-	else
-	{
-		y -= FixedMul(SHORT(patch->topoffset)<<FRACBITS, pscale);
+		fixed_t offsetx = 0, offsety = 0;
 
+		// left offset
 		if (scrn & V_FLIP)
-		{
-			flip = true;
-			x -= FixedMul((SHORT(patch->width) - SHORT(patch->leftoffset))<<FRACBITS, pscale) + 1;
-		}
+			offsetx = FixedMul((SHORT(patch->width) - SHORT(patch->leftoffset))<<FRACBITS, pscale) + 1;
 		else
-			x -= FixedMul(SHORT(patch->leftoffset)<<FRACBITS, pscale);
+			offsetx = FixedMul(SHORT(patch->leftoffset)<<FRACBITS, pscale);
+
+		// top offset
+		// TODO: make some kind of vertical version of V_FLIP, maybe by deprecating V_OFFSET in future?!?
+		offsety = FixedMul(SHORT(patch->topoffset)<<FRACBITS, pscale);
+
+		if ((scrn & (V_NOSCALESTART|V_OFFSET)) == (V_NOSCALESTART|V_OFFSET)) // Multiply by dupx/dupy for crosshairs
+		{
+			offsetx = FixedMul(offsetx, dupx<<FRACBITS);
+			offsety = FixedMul(offsety, dupy<<FRACBITS);
+		}
+
+		// Subtract the offsets from x/y positions
+		x -= offsetx;
+		y -= offsety;
 	}
 
 	if (scrn & V_SPLITSCREEN)
@@ -497,7 +506,7 @@ void V_DrawFixedPatch(fixed_t x, fixed_t y, fixed_t pscale, INT32 scrn, patch_t
 	for (col = 0; (col>>FRACBITS) < SHORT(patch->width); col += colfrac, ++offx, desttop++)
 	{
 		INT32 topdelta, prevdelta = -1;
-		if (flip) // offx is measured from right edge instead of left
+		if (scrn & V_FLIP) // offx is measured from right edge instead of left
 		{
 			if (x+pwidth-offx < 0) // don't draw off the left of the screen (WRAP PREVENTION)
 				break;
@@ -521,7 +530,7 @@ void V_DrawFixedPatch(fixed_t x, fixed_t y, fixed_t pscale, INT32 scrn, patch_t
 			prevdelta = topdelta;
 			source = (const UINT8 *)(column) + 3;
 			dest = desttop;
-			if (flip)
+			if (scrn & V_FLIP)
 				dest = deststart + (destend - desttop);
 			dest += FixedInt(FixedMul(topdelta<<FRACBITS,fdup))*vid.width;
 
@@ -653,14 +662,10 @@ void V_DrawCroppedPatch(fixed_t x, fixed_t y, fixed_t pscale, INT32 scrn, patch_
 //
 void V_DrawContinueIcon(INT32 x, INT32 y, INT32 flags, INT32 skinnum, UINT8 skincolor)
 {
-	if (skins[skinnum].flags & SF_HIRES
-#ifdef HWRENDER
-//	|| (rendermode != render_soft && rendermode != render_none)
-#endif
-	)
-		V_DrawScaledPatch(x - 10, y - 14, flags, W_CachePatchName("CONTINS", PU_CACHE));
+	if (skinnum < 0 || skinnum >= numskins || (skins[skinnum].flags & SF_HIRES))
+		V_DrawScaledPatch(x - 10, y - 14, flags, W_CachePatchName("CONTINS", PU_CACHE)); // Draw a star
 	else
-	{
+	{ // Find front angle of the first waiting frame of the character's actual sprites
 		spriteframe_t *sprframe = &skins[skinnum].spritedef.spriteframes[2 & FF_FRAMEMASK];
 		patch_t *patch = W_CachePatchNum(sprframe->lumppat[0], PU_CACHE);
 		const UINT8 *colormap = R_GetTranslationColormap(skinnum, skincolor, GTC_CACHE);
diff --git a/src/v_video.h b/src/v_video.h
index 353f84c1d..a60a08a5b 100644
--- a/src/v_video.h
+++ b/src/v_video.h
@@ -2,7 +2,7 @@
 //-----------------------------------------------------------------------------
 // Copyright (C) 1993-1996 by id Software, Inc.
 // Copyright (C) 1998-2000 by DooM Legacy Team.
-// Copyright (C) 1999-2016 by Sonic Team Junior.
+// Copyright (C) 1999-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
diff --git a/src/vid_copy.s b/src/vid_copy.s
index 9d8e7d4e0..050a80999 100644
--- a/src/vid_copy.s
+++ b/src/vid_copy.s
@@ -1,7 +1,7 @@
 // SONIC ROBO BLAST 2
 //-----------------------------------------------------------------------------
 // Copyright (C) 1998-2000 by DooM Legacy Team.
-// Copyright (C) 1999-2016 by Sonic Team Junior.
+// Copyright (C) 1999-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
diff --git a/src/w_wad.c b/src/w_wad.c
index 3a8285593..4cedd3cf4 100644
--- a/src/w_wad.c
+++ b/src/w_wad.c
@@ -2,7 +2,7 @@
 //-----------------------------------------------------------------------------
 // Copyright (C) 1993-1996 by id Software, Inc.
 // Copyright (C) 1998-2000 by DooM Legacy Team.
-// Copyright (C) 1999-2016 by Sonic Team Junior.
+// Copyright (C) 1999-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
@@ -194,16 +194,21 @@ static inline void W_LoadDehackedLumps(UINT16 wadnum)
 		for (lump = 0; lump < wadfiles[wadnum]->numlumps; lump++, lump_p++)
 			if (memcmp(lump_p->name,"SOC_",4)==0) // Check for generic SOC lump
 			{	// shameless copy+paste of code from LUA_LoadLump
-				char *name = malloc(strlen(wadfiles[wadnum]->filename)+10);
+				size_t len = strlen(wadfiles[wadnum]->filename);
+				char *name = malloc(len+10);
+
 				strcpy(name, wadfiles[wadnum]->filename);
-				if (!fasticmp(&name[strlen(name) - 4], ".soc")) {
+				if (!fasticmp(&name[len - 4], ".soc")) {
 					// If it's not a .soc file, copy the lump name in too.
-					name[strlen(wadfiles[wadnum]->filename)] = '|';
-					M_Memcpy(name+strlen(wadfiles[wadnum]->filename)+1, lump_p->name, 8);
-					name[strlen(wadfiles[wadnum]->filename)+9] = '\0';
+					name[len] = '|';
+					M_Memcpy(name+len+1, lump_p->name, 8);
+					name[len+9] = '\0';
 				}
+
 				CONS_Printf(M_GetText("Loading SOC from %s\n"), name);
 				DEH_LoadDehackedLumpPwad(wadnum, lump);
+
+				free(name);
 			}
 			else if (memcmp(lump_p->name,"MAINCFG",8)==0) // Check for MAINCFG
 			{
@@ -376,6 +381,8 @@ UINT16 W_LoadWadFile(const char *filename)
 		if (fread(&header, 1, sizeof header, handle) < sizeof header)
 		{
 			CONS_Alert(CONS_ERROR, M_GetText("Can't read wad header from %s because %s\n"), filename, strerror(ferror(handle)));
+			if (handle)
+				fclose(handle);
 			return INT16_MAX;
 		}
 
@@ -386,6 +393,8 @@ UINT16 W_LoadWadFile(const char *filename)
 			&& memcmp(header.identification, "SDLL", 4) != 0)
 		{
 			CONS_Alert(CONS_ERROR, M_GetText("%s does not have a valid WAD header\n"), filename);
+			if (handle)
+				fclose(handle);
 			return INT16_MAX;
 		}
 
@@ -400,6 +409,8 @@ UINT16 W_LoadWadFile(const char *filename)
 		{
 			CONS_Alert(CONS_ERROR, M_GetText("Wadfile directory in %s is corrupted (%s)\n"), filename, strerror(ferror(handle)));
 			free(fileinfov);
+			if (handle)
+				fclose(handle);
 			return INT16_MAX;
 		}
 
@@ -457,6 +468,8 @@ UINT16 W_LoadWadFile(const char *filename)
 		if (!memcmp(wadfiles[i]->md5sum, md5sum, 16))
 		{
 			CONS_Alert(CONS_ERROR, M_GetText("%s is already loaded\n"), filename);
+			if (handle)
+				fclose(handle);
 			return INT16_MAX;
 		}
 	}
diff --git a/src/w_wad.h b/src/w_wad.h
index f7ea64a56..320bc3220 100644
--- a/src/w_wad.h
+++ b/src/w_wad.h
@@ -2,7 +2,7 @@
 //-----------------------------------------------------------------------------
 // Copyright (C) 1993-1996 by id Software, Inc.
 // Copyright (C) 1998-2000 by DooM Legacy Team.
-// Copyright (C) 1999-2016 by Sonic Team Junior.
+// Copyright (C) 1999-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
@@ -48,7 +48,7 @@ typedef struct
 //                         DYNAMIC WAD LOADING
 // =========================================================================
 
-#define MAX_WADPATH 128
+#define MAX_WADPATH 512
 #define MAX_WADFILES 48 // maximum of wad files used at the same time
 // (there is a max of simultaneous open files anyway, and this should be plenty)
 
diff --git a/src/win32/Makefile.cfg b/src/win32/Makefile.cfg
index 749734a72..a73858bd4 100644
--- a/src/win32/Makefile.cfg
+++ b/src/win32/Makefile.cfg
@@ -9,6 +9,9 @@
 ifdef MINGW64
 	NOASM=1
 	NONX86=1
+	HAVE_LIBGME=1
+	LIBGME_CFLAGS=-I../libs/gme/include
+	LIBGME_LDFLAGS=-L../libs/gme/win64 -lgme
 	SDL_CFLAGS?=-I../libs/SDL2/x86_64-w64-mingw32/include/SDL2 -I../libs/SDL2_mixer/x86_64-w64-mingw32/include/SDL2 -Dmain=SDL_main
 	SDL_LDFLAGS?=-L../libs/SDL2/x86_64-w64-mingw32/lib -L../libs/SDL2_mixer/x86_64-w64-mingw32/lib -lmingw32 -lSDL2main -lSDL2 -mwindows
 else
@@ -23,7 +26,9 @@ ifndef NOASM
 	USEASM=1
 endif
 
+ifndef MINGW64 #miniupnc is broken with MINGW64
 	HAVE_MINIUPNPC=1
+endif
 
 	OPTS=-DSTDC_HEADERS
 
diff --git a/src/win32/Srb2win-vc10.vcxproj b/src/win32/Srb2win-vc10.vcxproj
index 064f75d7d..0722c0b68 100644
--- a/src/win32/Srb2win-vc10.vcxproj
+++ b/src/win32/Srb2win-vc10.vcxproj
@@ -119,6 +119,7 @@
     <ClCompile Include="..\hardware\hw3sound.c" />
     <ClCompile Include="..\hardware\hw_bsp.c" />
     <ClCompile Include="..\hardware\hw_cache.c" />
+    <ClCompile Include="..\hardware\hw_clip.c" />
     <ClCompile Include="..\hardware\hw_draw.c" />
     <ClCompile Include="..\hardware\hw_light.c" />
     <ClCompile Include="..\hardware\hw_main.c" />
@@ -275,6 +276,7 @@
     <ClInclude Include="..\hardware\hw3dsdrv.h" />
     <ClInclude Include="..\hardware\hw3sound.h" />
     <ClInclude Include="..\hardware\hws_data.h" />
+    <ClInclude Include="..\hardware\hw_clip.h" />
     <ClInclude Include="..\hardware\hw_data.h" />
     <ClInclude Include="..\hardware\hw_defs.h" />
     <ClInclude Include="..\hardware\hw_dll.h" />
diff --git a/src/win32/Srb2win-vc10.vcxproj.filters b/src/win32/Srb2win-vc10.vcxproj.filters
index b2647ea1c..95e79cab1 100644
--- a/src/win32/Srb2win-vc10.vcxproj.filters
+++ b/src/win32/Srb2win-vc10.vcxproj.filters
@@ -93,6 +93,9 @@
     <ClCompile Include="..\hardware\hw_cache.c">
       <Filter>Hw_Hardware</Filter>
     </ClCompile>
+    <ClCompile Include="..\hardware\hw_clip.c">
+      <Filter>Hw_Hardware</Filter>
+    </ClCompile>
     <ClCompile Include="..\hardware\hw_draw.c">
       <Filter>Hw_Hardware</Filter>
     </ClCompile>
@@ -470,6 +473,9 @@
     <ClInclude Include="win_main.h">
       <Filter>Win32app</Filter>
     </ClInclude>
+    <ClInclude Include="..\hardware\hw_clip.h">
+      <Filter>Hw_Hardware</Filter>
+    </ClInclude>
     <ClInclude Include="..\hardware\hw_data.h">
       <Filter>Hw_Hardware</Filter>
     </ClInclude>
diff --git a/src/win32/Srb2win.rc b/src/win32/Srb2win.rc
index 426a5e013..b60ba750d 100644
--- a/src/win32/Srb2win.rc
+++ b/src/win32/Srb2win.rc
@@ -36,18 +36,18 @@ IDI_ICON1               ICON    DISCARDABLE     "Srb2win.ico"
 // TEXTINCLUDE
 //
 
-1 TEXTINCLUDE DISCARDABLE 
+1 TEXTINCLUDE DISCARDABLE
 BEGIN
     "resource.h\0"
 END
 
-2 TEXTINCLUDE DISCARDABLE 
+2 TEXTINCLUDE DISCARDABLE
 BEGIN
     "#include ""afxres.h""\r\n"
     "\0"
 END
 
-3 TEXTINCLUDE DISCARDABLE 
+3 TEXTINCLUDE DISCARDABLE
 BEGIN
     "\r\n"
     "\0"
@@ -84,7 +84,7 @@ BEGIN
             VALUE "FileDescription", "Sonic Robo Blast 2\0"
             VALUE "FileVersion", "1, 09\0"
             VALUE "InternalName", "srb2\0"
-            VALUE "LegalCopyright", "Copyright � 1998-2005 Sonic Team Junior\0"
+            VALUE "LegalCopyright", "Copyright � 1998-2018 by Sonic Team Junior\0"
             VALUE "LegalTrademarks", "Sonic the Hedgehog and related characters are trademarks of Sega.\0"
             VALUE "OriginalFilename", "srb2win.exe\0"
             VALUE "PrivateBuild", "\0"
diff --git a/src/win32/win_cd.c b/src/win32/win_cd.c
index f6c430748..2586b8440 100644
--- a/src/win32/win_cd.c
+++ b/src/win32/win_cd.c
@@ -471,7 +471,7 @@ void I_PlayCD(UINT8 nTrack, UINT8 bLooping)
 	//faB: stop MIDI music, MIDI music will restart if volume is upped later
 	cv_digmusicvolume.value = 0;
 	cv_midimusicvolume.value = 0;
-	I_StopSong (0);
+	I_StopSong();
 
 	//faB: I don't use the notify message, I'm trying to minimize the delay
 	mciPlay.dwCallback = (DWORD)((size_t)hWndMain);
diff --git a/src/win32/win_dll.c b/src/win32/win_dll.c
index c9b3fba4e..71eda0437 100644
--- a/src/win32/win_dll.c
+++ b/src/win32/win_dll.c
@@ -148,7 +148,7 @@ static loadfunc_t hwdFuncTable[] = {
 #ifdef SHUFFLE
 	{"PostImgRedraw",       &hwdriver.pfnPostImgRedraw},
 #endif
-	{"FlushScreenTextures"},&hwdriver.pfnFlushScreenTextures},
+	{"FlushScreenTextures", &hwdriver.pfnFlushScreenTextures},
 	{"StartScreenWipe",     &hwdriver.pfnStartScreenWipe},
 	{"EndScreenWipe",       &hwdriver.pfnEndScreenWipe},
 	{"DoScreenWipe",        &hwdriver.pfnDoScreenWipe},
diff --git a/src/win32/win_main.c b/src/win32/win_main.c
index 6c774f557..bfe620a43 100644
--- a/src/win32/win_main.c
+++ b/src/win32/win_main.c
@@ -110,9 +110,9 @@ static LRESULT CALLBACK MainWndproc(HWND hWnd, UINT message, WPARAM wParam, LPAR
 
 			// pause music when alt-tab
 			if (appActive  && !paused)
-				I_ResumeSong(0);
+				I_ResumeSong();
 			else if (!paused)
-				I_PauseSong(0);
+				I_PauseSong();
 			{
 				HANDLE ci = GetStdHandle(STD_INPUT_HANDLE);
 				DWORD mode;
diff --git a/src/win32/win_snd.c b/src/win32/win_snd.c
index f168f1fe3..454c53e37 100644
--- a/src/win32/win_snd.c
+++ b/src/win32/win_snd.c
@@ -17,17 +17,13 @@
 #include "gme/gme.h"
 #define GME_TREBLE 5.0
 #define GME_BASS 1.0
-#ifdef HAVE_PNG /// TODO: compile with zlib support without libpng
-
-#define HAVE_ZLIB
 
+#ifdef HAVE_ZLIB
 #ifndef _MSC_VER
-#ifndef _WII
 #ifndef _LARGEFILE64_SOURCE
 #define _LARGEFILE64_SOURCE
 #endif
 #endif
-#endif
 
 #ifndef _LFS64_LARGEFILE
 #define _LFS64_LARGEFILE
@@ -38,13 +34,12 @@
 #endif
 
 #include "zlib.h"
-#endif
-#endif
+#endif // HAVE_ZLIB
+#endif // HAVE_LIBGME
 
 static FMOD_SYSTEM *fsys;
 static FMOD_SOUND *music_stream;
 static FMOD_CHANNEL *music_channel;
-static boolean midimode;
 
 static UINT8 music_volume, midi_volume, sfx_volume;
 static INT32 current_track;
@@ -357,12 +352,13 @@ void I_FreeSfx(sfxinfo_t *sfx)
 	sfx->data = NULL;
 }
 
-INT32 I_StartSound(sfxenum_t id, UINT8 vol, UINT8 sep, UINT8 pitch, UINT8 priority)
+INT32 I_StartSound(sfxenum_t id, UINT8 vol, UINT8 sep, UINT8 pitch, UINT8 priority, INT32 channel)
 {
 	FMOD_SOUND *sound;
 	FMOD_CHANNEL *chan;
 	INT32 i;
 	float frequency;
+	(void)channel;
 
 	sound = (FMOD_SOUND *)S_sfx[id].data;
 	I_Assert(sound != NULL);
@@ -442,9 +438,9 @@ void I_SetSfxVolume(UINT8 volume)
 	sfx_volume = volume;
 }
 
-//
-// MUSIC
-//
+/// ------------------------
+//  MUSIC SYSTEM
+/// ------------------------
 
 void I_InitMusic(void)
 {
@@ -452,53 +448,117 @@ void I_InitMusic(void)
 
 void I_ShutdownMusic(void)
 {
-	I_ShutdownDigMusic();
-	I_ShutdownMIDIMusic();
+	I_StopSong();
 }
 
-void I_PauseSong(INT32 handle)
-{
-	UNREFERENCED_PARAMETER(handle);
-	if (music_stream)
-		FMR_MUSIC(FMOD_Channel_SetPaused(music_channel, true));
-}
+/// ------------------------
+//  MUSIC PROPERTIES
+/// ------------------------
 
-void I_ResumeSong(INT32 handle)
+musictype_t I_SongType(void)
 {
-	UNREFERENCED_PARAMETER(handle);
-	if (music_stream)
-		FMR_MUSIC(FMOD_Channel_SetPaused(music_channel, false));
-}
+	FMOD_SOUND_TYPE type;
 
-void I_InitDigMusic(void)
-{
-}
+#ifdef HAVE_LIBGME
+	if (gme)
+		return MU_GME;
+#endif
 
-void I_ShutdownDigMusic(void)
-{
-	if (!midimode)
-		I_StopDigSong();
-}
+	if (!music_stream)
+		return MU_NONE;
 
-boolean I_StartDigSong(const char *musicname, boolean looping)
-{
-	char *data;
-	size_t len;
-	FMOD_CREATESOUNDEXINFO fmt;
-	lumpnum_t lumpnum = W_CheckNumForName(va("O_%s",musicname));
-
-	if (lumpnum == LUMPERROR)
+	if (FMOD_Sound_GetFormat(music_stream, &type, NULL, NULL, NULL) == FMOD_OK)
 	{
-		lumpnum = W_CheckNumForName(va("D_%s",musicname));
-		if (lumpnum == LUMPERROR)
-			return false;
-		midimode = true;
+		switch(type)
+		{
+			case FMOD_SOUND_TYPE_WAV:
+				return MU_WAV;
+			case FMOD_SOUND_TYPE_MOD:
+				return MU_MOD;
+			case FMOD_SOUND_TYPE_MIDI:
+				return MU_MID;
+			case FMOD_SOUND_TYPE_OGGVORBIS:
+				return MU_OGG;
+			case FMOD_SOUND_TYPE_MPEG:
+				return MU_MP3;
+			case FMOD_SOUND_TYPE_FLAC:
+				return MU_FLAC;
+			default:
+				return MU_NONE;
+		}
 	}
 	else
-		midimode = false;
+		return MU_NONE;
+}
 
-	data = (char *)W_CacheLumpNum(lumpnum, PU_MUSIC);
-	len = W_LumpLength(lumpnum);
+boolean I_SongPlaying(void)
+{
+	return (music_stream != NULL);
+}
+
+boolean I_SongPaused(void)
+{
+	FMOD_BOOL fmpaused = false;
+	if (music_stream)
+		FMOD_Channel_GetPaused(music_channel, &fmpaused);
+	return (boolean)fmpaused;
+}
+
+/// ------------------------
+//  MUSIC EFFECTS
+/// ------------------------
+
+boolean I_SetSongSpeed(float speed)
+{
+	FMOD_RESULT e;
+	float frequency;
+	if (!music_stream)
+		return false;
+	if (speed > 250.0f)
+		speed = 250.0f; //limit speed up to 250x
+
+#ifdef HAVE_LIBGME
+	// Try to set GME speed
+	if (gme)
+	{
+		gme_set_tempo(gme, speed);
+		return true;
+	}
+#endif
+
+	// Try to set Mod/Midi speed
+	e = FMOD_Sound_SetMusicSpeed(music_stream, speed);
+
+	if (e == FMOD_ERR_FORMAT)
+	{
+		// Just change pitch instead for Ogg/etc.
+		FMR(FMOD_Sound_GetDefaults(music_stream, &frequency, NULL, NULL, NULL));
+		FMR_MUSIC(FMOD_Channel_SetFrequency(music_channel, speed*frequency));
+	}
+	else
+		FMR_MUSIC(e);
+
+	return true;
+}
+
+/// ------------------------
+//  MUSIC PLAYBACK
+/// ------------------------
+
+boolean I_LoadSong(char *data, size_t len)
+{
+	FMOD_CREATESOUNDEXINFO fmt;
+	FMOD_RESULT e;
+	FMOD_TAG tag;
+	unsigned int loopstart, loopend;
+
+	if (
+#ifdef HAVE_LIBGME
+		gme ||
+#endif
+		music_stream
+	)
+		I_UnloadSong();
 
 	memset(&fmt, 0, sizeof(FMOD_CREATESOUNDEXINFO));
 	fmt.cbsize = sizeof(FMOD_CREATESOUNDEXINFO);
@@ -533,8 +593,6 @@ boolean I_StartDigSong(const char *musicname, boolean looping)
 					gme_equalizer_t gmeq = {GME_TREBLE, GME_BASS, 0,0,0,0,0,0,0,0};
 					Z_Free(inflatedData); // GME supposedly makes a copy for itself, so we don't need this lying around
 					Z_Free(data); // We don't need this, either.
-					gme_start_track(gme, 0);
-					current_track = 0;
 					gme_set_equalizer(gme,&gmeq);
 					fmt.format = FMOD_SOUND_FORMAT_PCM16;
 					fmt.defaultfrequency = 44100;
@@ -543,10 +601,7 @@ boolean I_StartDigSong(const char *musicname, boolean looping)
 					fmt.decodebuffersize = (44100 * 2) / 35;
 					fmt.pcmreadcallback = GMEReadCallback;
 					fmt.userdata = gme;
-					FMR(FMOD_System_CreateStream(fsys, NULL, FMOD_OPENUSER | (looping ? FMOD_LOOP_NORMAL : 0), &fmt, &music_stream));
-					FMR(FMOD_System_PlaySound(fsys, FMOD_CHANNEL_FREE, music_stream, false, &music_channel));
-					FMR(FMOD_Channel_SetVolume(music_channel, music_volume / 31.0));
-					FMR(FMOD_Channel_SetPriority(music_channel, 0));
+					FMR(FMOD_System_CreateStream(fsys, NULL, FMOD_OPENUSER, &fmt, &music_stream));
 					return true;
 				}
 			}
@@ -605,8 +660,6 @@ boolean I_StartDigSong(const char *musicname, boolean looping)
 	{
 		gme_equalizer_t gmeq = {GME_TREBLE, GME_BASS, 0,0,0,0,0,0,0,0};
 		Z_Free(data); // We don't need this anymore.
-		gme_start_track(gme, 0);
-		current_track = 0;
 		gme_set_equalizer(gme,&gmeq);
 		fmt.format = FMOD_SOUND_FORMAT_PCM16;
 		fmt.defaultfrequency = 44100;
@@ -615,7 +668,102 @@ boolean I_StartDigSong(const char *musicname, boolean looping)
 		fmt.decodebuffersize = (44100 * 2) / 35;
 		fmt.pcmreadcallback = GMEReadCallback;
 		fmt.userdata = gme;
-		FMR(FMOD_System_CreateStream(fsys, NULL, FMOD_OPENUSER | (looping ? FMOD_LOOP_NORMAL : 0), &fmt, &music_stream));
+		FMR(FMOD_System_CreateStream(fsys, NULL, FMOD_OPENUSER, &fmt, &music_stream));
+		return true;
+	}
+#endif
+
+	fmt.length = len;
+
+	e = FMOD_System_CreateStream(fsys, data, FMOD_OPENMEMORY_POINT, &fmt, &music_stream);
+	if (e != FMOD_OK)
+	{
+		if (e == FMOD_ERR_FORMAT)
+			CONS_Alert(CONS_WARNING, "Failed to play music lump due to invalid format.\n");
+		else
+			FMR(e);
+		return false;
+	}
+
+	// Try to find a loop point in streaming music formats (ogg, mp3)
+
+	// A proper LOOPPOINT is its own tag, stupid.
+	e = FMOD_Sound_GetTag(music_stream, "LOOPPOINT", 0, &tag);
+	if (e != FMOD_ERR_TAGNOTFOUND)
+	{
+		FMR(e);
+		loopstart = atoi((char *)tag.data); // assumed to be a string data tag.
+		FMR(FMOD_Sound_GetLoopPoints(music_stream, NULL, FMOD_TIMEUNIT_PCM, &loopend, FMOD_TIMEUNIT_PCM));
+		if (loopstart > 0)
+			FMR(FMOD_Sound_SetLoopPoints(music_stream, loopstart, FMOD_TIMEUNIT_PCM, loopend, FMOD_TIMEUNIT_PCM));
+		return true;
+	}
+
+	// Use LOOPMS for time in miliseconds.
+	e = FMOD_Sound_GetTag(music_stream, "LOOPMS", 0, &tag);
+	if (e != FMOD_ERR_TAGNOTFOUND)
+	{
+		FMR(e);
+		loopstart = atoi((char *)tag.data); // assumed to be a string data tag.
+		FMR(FMOD_Sound_GetLoopPoints(music_stream, NULL, FMOD_TIMEUNIT_MS, &loopend, FMOD_TIMEUNIT_PCM));
+		if (loopstart > 0)
+			FMR(FMOD_Sound_SetLoopPoints(music_stream, loopstart, FMOD_TIMEUNIT_MS, loopend, FMOD_TIMEUNIT_PCM));
+		return true;
+	}
+
+	// Try to fetch it from the COMMENT tag, like A.J. Freda
+	e = FMOD_Sound_GetTag(music_stream, "COMMENT", 0, &tag);
+	if (e != FMOD_ERR_TAGNOTFOUND)
+	{
+		char *loopText;
+		// Handle any errors that arose, first
+		FMR(e);
+		// Figure out where the number starts
+		loopText = strstr((char *)tag.data,"LOOPPOINT=");
+		if (loopText != NULL)
+		{
+			// Skip the "LOOPPOINT=" part.
+			loopText += 10;
+			// Convert it to our looppoint
+			// FMOD seems to ensure the tag is properly NULL-terminated.
+			// atoi will stop when it reaches anything that's not a number.
+			loopstart = atoi(loopText);
+			// Now do the rest like above
+			FMR(FMOD_Sound_GetLoopPoints(music_stream, NULL, FMOD_TIMEUNIT_PCM, &loopend, FMOD_TIMEUNIT_PCM));
+			if (loopstart > 0)
+				FMR(FMOD_Sound_SetLoopPoints(music_stream, loopstart, FMOD_TIMEUNIT_PCM, loopend, FMOD_TIMEUNIT_PCM));
+		}
+		return true;
+	}
+
+	// No special loop point
+	return true;
+}
+
+void I_UnloadSong(void)
+{
+	I_StopSong();
+#ifdef HAVE_LIBGME
+	if (gme)
+	{
+		gme_delete(gme);
+		gme = NULL;
+	}
+#endif
+	if (music_stream)
+	{
+		FMR(FMOD_Sound_Release(music_stream));
+		music_stream = NULL;
+	}
+}
+
+boolean I_PlaySong(boolean looping)
+{
+#ifdef HAVE_LIBGME
+	if (gme)
+	{
+		gme_start_track(gme, 0);
+		current_track = 0;
 		FMR(FMOD_System_PlaySound(fsys, FMOD_CHANNEL_FREE, music_stream, false, &music_channel));
 		FMR(FMOD_Channel_SetVolume(music_channel, music_volume / 31.0));
 		FMR(FMOD_Channel_SetPriority(music_channel, 0));
@@ -623,139 +771,48 @@ boolean I_StartDigSong(const char *musicname, boolean looping)
 	}
 #endif
 
-	fmt.length = len;
-	{
-		FMOD_RESULT e = FMOD_System_CreateStream(fsys, data, FMOD_OPENMEMORY_POINT|(looping ? FMOD_LOOP_NORMAL : 0), &fmt, &music_stream);
-		if (e != FMOD_OK)
-		{
-			if (e == FMOD_ERR_FORMAT)
-				CONS_Alert(CONS_WARNING, "Failed to play music lump %s due to invalid format.\n", W_CheckNameForNum(lumpnum));
-			else
-				FMR(e);
-			return false;
-		}
-	}
+	FMR(FMOD_Sound_SetMode(music_stream, (looping ? FMOD_LOOP_NORMAL : FMOD_LOOP_OFF)));
 	FMR(FMOD_System_PlaySound(fsys, FMOD_CHANNEL_FREE, music_stream, false, &music_channel));
-	if (midimode)
+	if (I_SongType() != MU_MID)
 		FMR(FMOD_Channel_SetVolume(music_channel, midi_volume / 31.0));
 	else
 		FMR(FMOD_Channel_SetVolume(music_channel, music_volume / 31.0));
 	FMR(FMOD_Channel_SetPriority(music_channel, 0));
 	current_track = 0;
 
-	// Try to find a loop point in streaming music formats (ogg, mp3)
-	if (looping)
-	{
-		FMOD_RESULT e;
-		FMOD_TAG tag;
-		unsigned int loopstart, loopend;
-
-		// A proper LOOPPOINT is its own tag, stupid.
-		e = FMOD_Sound_GetTag(music_stream, "LOOPPOINT", 0, &tag);
-		if (e != FMOD_ERR_TAGNOTFOUND)
-		{
-			FMR(e);
-			loopstart = atoi((char *)tag.data); // assumed to be a string data tag.
-			FMR(FMOD_Sound_GetLoopPoints(music_stream, NULL, FMOD_TIMEUNIT_PCM, &loopend, FMOD_TIMEUNIT_PCM));
-			if (loopstart > 0)
-				FMR(FMOD_Sound_SetLoopPoints(music_stream, loopstart, FMOD_TIMEUNIT_PCM, loopend, FMOD_TIMEUNIT_PCM));
-			return true;
-		}
-
-		// Use LOOPMS for time in miliseconds.
-		e = FMOD_Sound_GetTag(music_stream, "LOOPMS", 0, &tag);
-		if (e != FMOD_ERR_TAGNOTFOUND)
-		{
-			FMR(e);
-			loopstart = atoi((char *)tag.data); // assumed to be a string data tag.
-			FMR(FMOD_Sound_GetLoopPoints(music_stream, NULL, FMOD_TIMEUNIT_MS, &loopend, FMOD_TIMEUNIT_PCM));
-			if (loopstart > 0)
-				FMR(FMOD_Sound_SetLoopPoints(music_stream, loopstart, FMOD_TIMEUNIT_MS, loopend, FMOD_TIMEUNIT_PCM));
-			return true;
-		}
-
-		// Try to fetch it from the COMMENT tag, like A.J. Freda
-		e = FMOD_Sound_GetTag(music_stream, "COMMENT", 0, &tag);
-		if (e != FMOD_ERR_TAGNOTFOUND)
-		{
-			char *loopText;
-			// Handle any errors that arose, first
-			FMR(e);
-			// Figure out where the number starts
-			loopText = strstr((char *)tag.data,"LOOPPOINT=");
-			if (loopText != NULL)
-			{
-				// Skip the "LOOPPOINT=" part.
-				loopText += 10;
-				// Convert it to our looppoint
-				// FMOD seems to ensure the tag is properly NULL-terminated.
-				// atoi will stop when it reaches anything that's not a number.
-				loopstart = atoi(loopText);
-				// Now do the rest like above
-				FMR(FMOD_Sound_GetLoopPoints(music_stream, NULL, FMOD_TIMEUNIT_PCM, &loopend, FMOD_TIMEUNIT_PCM));
-				if (loopstart > 0)
-					FMR(FMOD_Sound_SetLoopPoints(music_stream, loopstart, FMOD_TIMEUNIT_PCM, loopend, FMOD_TIMEUNIT_PCM));
-			}
-			return true;
-		}
-	}
-
-	// No special loop point, but we're playing so it's all good.
 	return true;
 }
 
-void I_StopDigSong(void)
+void I_StopSong(void)
 {
-	if (music_stream)
-		FMR(FMOD_Sound_Release(music_stream));
-	music_stream = NULL;
-#ifdef HAVE_LIBGME
-	if (gme)
-		gme_delete(gme);
-	gme = NULL;
-#endif
-	current_track = -1;
+	if (music_channel)
+		FMR_MUSIC(FMOD_Channel_Stop(music_channel));
 }
 
-void I_SetDigMusicVolume(UINT8 volume)
+void I_PauseSong(void)
 {
+	if (music_channel)
+		FMR_MUSIC(FMOD_Channel_SetPaused(music_channel, true));
+}
+
+void I_ResumeSong(void)
+{
+	if (music_channel)
+		FMR_MUSIC(FMOD_Channel_SetPaused(music_channel, false));
+}
+
+void I_SetMusicVolume(UINT8 volume)
+{
+	if (!music_channel)
+		return;
+
 	// volume is 0 to 31.
-	music_volume = volume;
-	if (!midimode && music_stream)
-		FMR_MUSIC(FMOD_Channel_SetVolume(music_channel, volume / 31.0));
-}
-
-boolean I_SetSongSpeed(float speed)
-{
-	FMOD_RESULT e;
-	float frequency;
-	if (!music_stream)
-		return false;
-	if (speed > 250.0f)
-		speed = 250.0f; //limit speed up to 250x
-
-#ifdef HAVE_LIBGME
-	// Try to set GME speed
-	if (gme)
-	{
-		gme_set_tempo(gme, speed);
-		return true;
-	}
-#endif
-
-	// Try to set Mod/Midi speed
-	e = FMOD_Sound_SetMusicSpeed(music_stream, speed);
-
-	if (e == FMOD_ERR_FORMAT)
-	{
-		// Just change pitch instead for Ogg/etc.
-		FMR(FMOD_Sound_GetDefaults(music_stream, &frequency, NULL, NULL, NULL));
-		FMR_MUSIC(FMOD_Channel_SetFrequency(music_channel, speed*frequency));
-	}
+	if (I_SongType() == MU_MID)
+		music_volume = 31; // windows bug hack
 	else
-		FMR_MUSIC(e);
+		music_volume = volume;
 
-	return true;
+	FMR_MUSIC(FMOD_Channel_SetVolume(music_channel, music_volume / 31.0));
 }
 
 boolean I_SetSongTrack(INT32 track)
@@ -802,62 +859,3 @@ boolean I_SetSongTrack(INT32 track)
 	}
 	return false;
 }
-
-//
-// Fuck MIDI. ... Okay fine, you can have your silly D_-only mode.
-//
-
-void I_InitMIDIMusic(void)
-{
-}
-
-void I_ShutdownMIDIMusic(void)
-{
-	if (midimode)
-		I_StopSong(0);
-}
-
-void I_SetMIDIMusicVolume(UINT8 volume)
-{
-	// volume is 0 to 31.
-	midi_volume = volume;
-	if (midimode && music_stream)
-		FMR_MUSIC(FMOD_Channel_SetVolume(music_channel, volume / 31.0));
-}
-
-INT32 I_RegisterSong(void *data, size_t len)
-{
-	FMOD_CREATESOUNDEXINFO fmt;
-	memset(&fmt, 0, sizeof(FMOD_CREATESOUNDEXINFO));
-	fmt.cbsize = sizeof(FMOD_CREATESOUNDEXINFO);
-	fmt.length = len;
-	FMR(FMOD_System_CreateStream(fsys, (char *)data, FMOD_OPENMEMORY_POINT, &fmt, &music_stream));
-	return 1337;
-}
-
-boolean I_PlaySong(INT32 handle, boolean looping)
-{
-	if (1337 == handle)
-	{
-		midimode = true;
-		if (looping)
-			FMR(FMOD_Sound_SetMode(music_stream, FMOD_LOOP_NORMAL));
-		FMR(FMOD_System_PlaySound(fsys, FMOD_CHANNEL_FREE, music_stream, false, &music_channel));
-		FMR_MUSIC(FMOD_Channel_SetVolume(music_channel, midi_volume / 31.0));
-		FMR_MUSIC(FMOD_Channel_SetPriority(music_channel, 0));
-	}
-	return true;
-}
-
-void I_StopSong(INT32 handle)
-{
-	I_UnRegisterSong(handle);
-}
-
-void I_UnRegisterSong(INT32 handle)
-{
-	UNREFERENCED_PARAMETER(handle);
-	if (music_stream)
-		FMR(FMOD_Sound_Release(music_stream));
-	music_stream = NULL;
-}
diff --git a/src/win32/win_sys.c b/src/win32/win_sys.c
index 316da61d4..77a21f7f3 100644
--- a/src/win32/win_sys.c
+++ b/src/win32/win_sys.c
@@ -771,6 +771,8 @@ void I_Quit(void)
 		ShowEndTxt(co);
 	}
 	fflush(stderr);
+	if (myargmalloc)
+		free(myargv); // Deallocate allocated memory
 	W_Shutdown();
 	exit(0);
 }
diff --git a/src/win32ce/win_snd.c b/src/win32ce/win_snd.c
index f9c652178..14ce4add4 100644
--- a/src/win32ce/win_snd.c
+++ b/src/win32ce/win_snd.c
@@ -538,7 +538,8 @@ INT32 I_StartSound (sfxenum_t      id,
                   INT32          vol,
                   INT32          sep,
                   INT32          pitch,
-                  INT32          priority)
+                  INT32          priority,
+				  INT32          channel)
 {
 	HRESULT     hr;
 	LPDIRECTSOUNDBUFFER     dsbuffer;
@@ -549,6 +550,7 @@ INT32 I_StartSound (sfxenum_t      id,
 #ifdef SURROUND
 	LPDIRECTSOUNDBUFFER     dssurround;
 #endif
+	(void)channel;
 
 	if (nosound)
 		return -1;
diff --git a/src/y_inter.c b/src/y_inter.c
index e7df165bf..ea3cfc33b 100644
--- a/src/y_inter.c
+++ b/src/y_inter.c
@@ -1,6 +1,6 @@
 // SONIC ROBO BLAST 2
 //-----------------------------------------------------------------------------
-// Copyright (C) 2004-2016 by Sonic Team Junior.
+// Copyright (C) 2004-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
@@ -1440,6 +1440,7 @@ static void Y_CalculateCompetitionWinners(void)
 	UINT32 maxrings[MAXPLAYERS];
 	UINT32 monitors[MAXPLAYERS];
 	UINT32 scores[MAXPLAYERS];
+	char tempname[9];
 
 	memset(data.competition.points, 0, sizeof (data.competition.points));
 	memset(points, 0, sizeof (points));
@@ -1531,8 +1532,9 @@ static void Y_CalculateCompetitionWinners(void)
 		data.competition.monitors[data.competition.numplayers] = monitors[winner];
 		data.competition.scores[data.competition.numplayers] = scores[winner];
 
-		snprintf(data.competition.name[data.competition.numplayers], 9, "%s", player_names[winner]);
-		data.competition.name[data.competition.numplayers][8] = '\0';
+		strncpy(tempname, player_names[winner], 8);
+		tempname[8] = '\0';
+		strncpy(data.competition.name[data.competition.numplayers], tempname, 9);
 
 		data.competition.color[data.competition.numplayers] = &players[winner].skincolor;
 		data.competition.character[data.competition.numplayers] = &players[winner].skin;
@@ -1904,4 +1906,5 @@ static void Y_UnloadData(void)
 			//are not handled
 			break;
 	}
+
 }
diff --git a/src/y_inter.h b/src/y_inter.h
index 9fe95fcc4..d7d3c95d7 100644
--- a/src/y_inter.h
+++ b/src/y_inter.h
@@ -1,6 +1,6 @@
 // SONIC ROBO BLAST 2
 //-----------------------------------------------------------------------------
-// Copyright (C) 2004-2016 by Sonic Team Junior.
+// Copyright (C) 2004-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
diff --git a/src/z_zone.c b/src/z_zone.c
index eecb6e808..a3e13422f 100644
--- a/src/z_zone.c
+++ b/src/z_zone.c
@@ -1,7 +1,7 @@
 // SONIC ROBO BLAST 2
 //-----------------------------------------------------------------------------
 // Copyright (C) 2006      by Graue.
-// Copyright (C) 2006-2016 by Sonic Team Junior.
+// Copyright (C) 2006-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
diff --git a/src/z_zone.h b/src/z_zone.h
index cd5fb2f7c..1424a3782 100644
--- a/src/z_zone.h
+++ b/src/z_zone.h
@@ -2,7 +2,7 @@
 //-----------------------------------------------------------------------------
 // Copyright (C) 1993-1996 by id Software, Inc.
 // Copyright (C) 1998-2000 by DooM Legacy Team.
-// Copyright (C) 1999-2016 by Sonic Team Junior.
+// Copyright (C) 1999-2018 by Sonic Team Junior.
 //
 // This program is free software distributed under the
 // terms of the GNU General Public License, version 2.
diff --git a/tools/masterserver/structure.sql b/tools/masterserver/structure.sql
new file mode 100644
index 000000000..3cc2cb15b
--- /dev/null
+++ b/tools/masterserver/structure.sql
@@ -0,0 +1,117 @@
+SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
+SET AUTOCOMMIT = 0;
+START TRANSACTION;
+SET time_zone = "+00:00";
+
+
+/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
+/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
+/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
+/*!40101 SET NAMES utf8mb4 */;
+
+--
+-- Database: `srb2ms`
+--
+
+CREATE DATABASE IF NOT EXISTS `srb2ms` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;
+USE `srb2ms`;
+
+
+-- --------------------------------------------------------
+
+--
+-- Table structure for table `ms_bans`
+--
+
+CREATE TABLE `ms_bans` (
+  `bid` int(11) DEFAULT NULL,
+  `ipstart` int(11) DEFAULT NULL,
+  `ipend` int(11) DEFAULT NULL,
+  `full_endtime` int(11) DEFAULT NULL,
+  `permanent` tinyint(1) DEFAULT NULL,
+  `hostonly` tinyint(1) DEFAULT NULL,
+  `reason` text COLLATE utf8mb4_unicode_ci
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
+
+-- --------------------------------------------------------
+
+--
+-- Table structure for table `ms_rooms`
+--
+
+CREATE TABLE `ms_rooms` (
+  `room_id` int(11) NOT NULL,
+  `title` text COLLATE utf8mb4_unicode_ci NOT NULL,
+  `motd` text COLLATE utf8mb4_unicode_ci NOT NULL,
+  `visible` tinyint(1) NOT NULL,
+  `order` int(11) NOT NULL,
+  `private` tinyint(1) NOT NULL
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
+
+--
+-- Dumping data for table `ms_rooms`
+--
+
+INSERT INTO `ms_rooms` (`room_id`, `title`, `motd`, `visible`, `order`, `private`) VALUES
+(10, 'Example', 'Example Room', 1, 0, 0),
+(0, 'All', 'View all of the servers currently being hosted.', 1, 1, 1);
+
+-- --------------------------------------------------------
+
+--
+-- Table structure for table `ms_servers`
+--
+
+CREATE TABLE `ms_servers` (
+  `sid` int(11) NOT NULL,
+  `name` text COLLATE utf8mb4_unicode_ci NOT NULL,
+  `ip` text COLLATE utf8mb4_unicode_ci NOT NULL,
+  `port` int(11) NOT NULL,
+  `version` text COLLATE utf8mb4_unicode_ci NOT NULL,
+  `timestamp` int(11) NOT NULL,
+  `room` int(11) NOT NULL,
+  `key` text COLLATE utf8mb4_unicode_ci NOT NULL,
+  `room_override` int(11) NOT NULL,
+  `upnow` tinyint(1) NOT NULL,
+  `permanent` tinyint(1) NOT NULL,
+  `delisted` tinyint(1) NOT NULL,
+  `sticky` int(11) NOT NULL
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
+
+-- --------------------------------------------------------
+
+--
+-- Table structure for table `ms_versions`
+--
+
+CREATE TABLE `ms_versions` (
+  `mod_id` int(11) NOT NULL,
+  `mod_version` int(11) NOT NULL
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
+
+--
+-- Dumping data for table `ms_versions`
+--
+
+INSERT INTO `ms_versions` (`mod_id`, `mod_version`) VALUES
+(12, 25);
+
+-- --------------------------------------------------------
+
+--
+-- Table structure for table `user`
+--
+
+CREATE TABLE `user` (
+  `userid` int(11) NOT NULL,
+  `username` text COLLATE utf8mb4_unicode_ci NOT NULL,
+  `live_authkey` blob NOT NULL,
+  `live_publickey` blob NOT NULL,
+  `salt` blob NOT NULL,
+  `password` blob NOT NULL
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
+COMMIT;
+
+/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
+/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
+/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;