diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 29f5ef5fff9f1bc4afb83006c65f54088762e6dc..14c36213e051f0af306b2d392af1f8da491ce289 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -12,6 +12,7 @@ variables:
 
 stages:
   - build
+  - osxcross
 
 default:
   interruptible: true
diff --git a/.gitlab/ci/jobs/alpine-3-gcc.yml b/.gitlab/ci/jobs/alpine-3-gcc.yml
index 522b88ae346e7fc27191c934fe5e53a608818ea4..72994d405b3dc36e6545fd33b210fb5246971c6d 100644
--- a/.gitlab/ci/jobs/alpine-3-gcc.yml
+++ b/.gitlab/ci/jobs/alpine-3-gcc.yml
@@ -15,8 +15,8 @@ Alpine 3 GCC:
 
   artifacts:
     paths:
-      - "build.alpine3/bin/"
-      - "build.alpine3/src/config.h"
+      - "build.cmake/bin/"
+      - "build.cmake/src/config.h"
     expose_as: "Apline-3"
     name: "$CI_PROJECT_PATH_SLUG-$CI_COMMIT_REF_SLUG-$CI_COMMIT_SHORT_SHA-Apline-3"
 
@@ -111,7 +111,7 @@ Alpine 3 GCC:
     - - |
           # cmake
           echo -e "\e[0Ksection_start:`date +%s`:cmake[collapsed=false]\r\e[0KBuilding Makefiles"
-      - cmake -B build.alpine3 -DSRB2_USE_CCACHE=YES -DSRB2_CONFIG_ERRORMODE=ON -DSRB2_CONFIG_EXECINFO=NO -G "Unix Makefiles"
+      - cmake -B build.cmake -DSRB2_USE_CCACHE=YES -DSRB2_CONFIG_ERRORMODE=ON -DSRB2_CONFIG_EXECINFO=NO -DSRB2_CONFIG_USE_GME:BOOL=ON
       - |
           # cmake
           echo -e "\e[0Ksection_end:`date +%s`:cmake\r\e[0K"
@@ -119,7 +119,7 @@ Alpine 3 GCC:
     - - |
           # make
           echo -e "\e[0Ksection_start:`date +%s`:make[collapsed=false]\r\e[0KCompiling SRB2"
-      - make --directory=build.alpine3 --keep-going || make --directory=build.alpine3 --keep-going
+      - cmake --build build.cmake --parallel 1 --verbose
       - |
           # make
           echo -e "\e[0Ksection_end:`date +%s`:make\r\e[0K"
diff --git a/.gitlab/ci/jobs/batocera-arm64.yml b/.gitlab/ci/jobs/batocera-arm64.yml
index c3b5865842f0bd0b09af3d78260ac7732279194a..3dcd73a0e2f422e84b5601a584d987a4bd0f2ed9 100644
--- a/.gitlab/ci/jobs/batocera-arm64.yml
+++ b/.gitlab/ci/jobs/batocera-arm64.yml
@@ -32,7 +32,7 @@ batocera:arm64:
     - - |
           # cmake
           echo -e "\e[0Ksection_start:`date +%s`:cmake[collapsed=false]\r\e[0KBuilding Makefiles"
-      - cmake -B build.cmake -DSRB2_USE_CCACHE=YES -DSRB2_CONFIG_ERRORMODE=ON -DSRB2_CONFIG_FORCE_NO_MS_BITFIELDS=ON -DSRB2_CONFIG_USE_GME=OFF -G "Unix Makefiles"
+      - cmake -B build.cmake -DSRB2_USE_CCACHE=YES -DSRB2_CONFIG_ERRORMODE=ON -DSRB2_CONFIG_FORCE_NO_MS_BITFIELDS=ON -DSRB2_CONFIG_USE_GME:BOOL=OFF
       - |
           # cmake
           echo -e "\e[0Ksection_end:`date +%s`:cmake\r\e[0K"
@@ -40,7 +40,7 @@ batocera:arm64:
     - - |
           # make
           echo -e "\e[0Ksection_start:`date +%s`:make[collapsed=false]\r\e[0KCompiling SRB2"
-      - make --directory=build.cmake --keep-going || make --directory=build.cmake --keep-going
+      - cmake --build build.cmake --parallel 1 --verbose
       - |
           # make
           echo -e "\e[0Ksection_end:`date +%s`:make\r\e[0K"
diff --git a/.gitlab/ci/jobs/debian-oldstable-amd64.yml b/.gitlab/ci/jobs/debian-oldstable-amd64.yml
index ad69dc8dd30fcf6b59c75294627e6c0c4e75405e..231e8485d71d5a50e94c1ecc08fb140549595e5e 100644
--- a/.gitlab/ci/jobs/debian-oldstable-amd64.yml
+++ b/.gitlab/ci/jobs/debian-oldstable-amd64.yml
@@ -34,7 +34,7 @@ Debian oldstable:amd64:
     - - |
           # cmake
           echo -e "\e[0Ksection_start:`date +%s`:cmake[collapsed=false]\r\e[0KBuilding Makefiles"
-      - cmake -B build.cmake -DSRB2_USE_CCACHE=YES -DSRB2_CONFIG_ERRORMODE=ON -DSRB2_CONFIG_USE_GME=OFF -G "Unix Makefiles"
+      - cmake -B build.cmake -DSRB2_USE_CCACHE=YES -DSRB2_CONFIG_ERRORMODE=ON -DSRB2_CONFIG_USE_GME:BOOL=ON
       - |
           # cmake
           echo -e "\e[0Ksection_end:`date +%s`:cmake\r\e[0K"
@@ -42,7 +42,7 @@ Debian oldstable:amd64:
     - - |
           # make
           echo -e "\e[0Ksection_start:`date +%s`:make[collapsed=false]\r\e[0KCompiling SRB2"
-      - make --directory=build.cmake --keep-going || make --directory=build.cmake --keep-going
+      - cmake --build build.cmake --parallel 1 --verbose
       - |
           # make
           echo -e "\e[0Ksection_end:`date +%s`:make\r\e[0K"
diff --git a/.gitlab/ci/jobs/debian-oldstable-arm64.yml b/.gitlab/ci/jobs/debian-oldstable-arm64.yml
index 24db9c80783aa83d8656ea1617abb09742839bd3..76d401309d07df3ee312b85488c09a9dd0fd28fb 100644
--- a/.gitlab/ci/jobs/debian-oldstable-arm64.yml
+++ b/.gitlab/ci/jobs/debian-oldstable-arm64.yml
@@ -34,7 +34,7 @@ Debian oldstable:arm64:
     - - |
           # cmake
           echo -e "\e[0Ksection_start:`date +%s`:cmake[collapsed=false]\r\e[0KBuilding Makefiles"
-      - cmake -B build.cmake -DSRB2_USE_CCACHE=YES -DSRB2_CONFIG_ERRORMODE=ON -DSRB2_CONFIG_FORCE_NO_MS_BITFIELDS=ON -DSRB2_CONFIG_USE_GME=OFF -G "Unix Makefiles"
+      - cmake -B build.cmake -DSRB2_USE_CCACHE=YES -DSRB2_CONFIG_ERRORMODE=ON -DSRB2_CONFIG_FORCE_NO_MS_BITFIELDS=ON -DSRB2_CONFIG_USE_GME:BOOL=ON
       - |
           # cmake
           echo -e "\e[0Ksection_end:`date +%s`:cmake\r\e[0K"
@@ -42,7 +42,7 @@ Debian oldstable:arm64:
     - - |
           # make
           echo -e "\e[0Ksection_start:`date +%s`:make[collapsed=false]\r\e[0KCompiling SRB2"
-      - make --directory=build.cmake --keep-going || make --directory=build.cmake --keep-going
+      - cmake --build build.cmake --parallel 1 --verbose
       - |
           # make
           echo -e "\e[0Ksection_end:`date +%s`:make\r\e[0K"
diff --git a/.gitlab/ci/jobs/debian-stable-amd64-makefile.yml b/.gitlab/ci/jobs/debian-stable-amd64-makefile.yml
index a6aebfac34bf1ad1e99380b167f16f56a5686f12..fee52c5a793015212c397c2907f1b927489ea93a 100644
--- a/.gitlab/ci/jobs/debian-stable-amd64-makefile.yml
+++ b/.gitlab/ci/jobs/debian-stable-amd64-makefile.yml
@@ -13,7 +13,6 @@ Debian stable:amd64 Makefile:
   variables:
     CC: x86_64-linux-gnu-gcc
     CXX: x86_64-linux-gnu-g++
-    LDFLAGS: -Wl,-fuse-ld=gold
     OBJCOPY: x86_64-linux-gnu-objcopy
     OBJDUMP: x86_64-linux-gnu-objdump
     PKG_CONFIG_PATH: /usr/lib/x86_64-linux-gnu/pkgconfig
diff --git a/.gitlab/ci/jobs/debian-stable-amd64.yml b/.gitlab/ci/jobs/debian-stable-amd64.yml
index a39344db89f94c646852346f6d2198d25ecd2e44..e58f5a112ca5a203d255dc6a9732ed46626d8f15 100644
--- a/.gitlab/ci/jobs/debian-stable-amd64.yml
+++ b/.gitlab/ci/jobs/debian-stable-amd64.yml
@@ -13,7 +13,6 @@ Debian stable:amd64:
   variables:
     CC: x86_64-linux-gnu-gcc
     CXX: x86_64-linux-gnu-g++
-    LDFLAGS: -Wl,-fuse-ld=gold
     OBJCOPY: x86_64-linux-gnu-objcopy
     OBJDUMP: x86_64-linux-gnu-objdump
     PKG_CONFIG_PATH: /usr/lib/x86_64-linux-gnu/pkgconfig
@@ -40,7 +39,7 @@ Debian stable:amd64:
     - - |
           # cmake
           echo -e "\e[0Ksection_start:`date +%s`:cmake[collapsed=false]\r\e[0KBuilding Makefiles"
-      - cmake -B build.cmake -DSRB2_USE_CCACHE=YES -DSRB2_CONFIG_ERRORMODE=ON -G "Unix Makefiles"
+      - cmake -B build.cmake -DSRB2_USE_CCACHE=YES -DSRB2_CONFIG_ERRORMODE=ON -DSRB2_CONFIG_USE_GME:BOOL=ON
       - |
           # cmake
           echo -e "\e[0Ksection_end:`date +%s`:cmake\r\e[0K"
@@ -48,7 +47,7 @@ Debian stable:amd64:
     - - |
           # make
           echo -e "\e[0Ksection_start:`date +%s`:make[collapsed=false]\r\e[0KCompiling SRB2"
-      - make --directory=build.cmake --keep-going || make --directory=build.cmake --keep-going
+      - cmake --build build.cmake --parallel 1 --verbose
       - |
           # make
           echo -e "\e[0Ksection_end:`date +%s`:make\r\e[0K"
diff --git a/.gitlab/ci/jobs/debian-stable-arm64-makefile.yml b/.gitlab/ci/jobs/debian-stable-arm64-makefile.yml
index 53625138abe3c56dc23612b9abca129f461f8b68..aa0ea3780bc3aad545ce70b2667374a62b839673 100644
--- a/.gitlab/ci/jobs/debian-stable-arm64-makefile.yml
+++ b/.gitlab/ci/jobs/debian-stable-arm64-makefile.yml
@@ -15,7 +15,6 @@ Debian stable:arm64 Makefile:
   variables:
     CC: aarch64-linux-gnu-gcc
     CXX: aarch64-linux-gnu-g++
-    LDFLAGS: -Wl,-fuse-ld=gold
     OBJCOPY: aarch64-linux-gnu-objcopy
     OBJDUMP: aarch64-linux-gnu-objdump
     LD: aarch64-linux-gnu-ld
diff --git a/.gitlab/ci/jobs/debian-stable-arm64.yml b/.gitlab/ci/jobs/debian-stable-arm64.yml
index 52e6e8603ad3af66addce46c56e5ef5ee6887f2a..135d87aa5942bf87f0f79cf3e982e9e345debe74 100644
--- a/.gitlab/ci/jobs/debian-stable-arm64.yml
+++ b/.gitlab/ci/jobs/debian-stable-arm64.yml
@@ -15,7 +15,6 @@ Debian stable:arm64:
   variables:
     CC: aarch64-linux-gnu-gcc
     CXX: aarch64-linux-gnu-g++
-    LDFLAGS: -Wl,-fuse-ld=gold
     OBJCOPY: aarch64-linux-gnu-objcopy
     OBJDUMP: aarch64-linux-gnu-objdump
     LD: aarch64-linux-gnu-ld
@@ -41,7 +40,7 @@ Debian stable:arm64:
     - - |
           # cmake
           echo -e "\e[0Ksection_start:`date +%s`:cmake[collapsed=false]\r\e[0KBuilding Makefiles"
-      - cmake -B build.cmake -DSRB2_USE_CCACHE=YES -DSRB2_CONFIG_ERRORMODE=ON -DSRB2_CONFIG_FORCE_NO_MS_BITFIELDS=ON -G "Unix Makefiles"
+      - cmake -B build.cmake -DSRB2_USE_CCACHE=YES -DSRB2_CONFIG_ERRORMODE=ON -DSRB2_CONFIG_FORCE_NO_MS_BITFIELDS=ON -DSRB2_CONFIG_USE_GME:BOOL=ON
       - |
           # cmake
           echo -e "\e[0Ksection_end:`date +%s`:cmake\r\e[0K"
@@ -49,7 +48,7 @@ Debian stable:arm64:
     - - |
           # make
           echo -e "\e[0Ksection_start:`date +%s`:make[collapsed=false]\r\e[0KCompiling SRB2"
-      - make --directory=build.cmake --keep-going || make --directory=build.cmake --keep-going
+      - cmake --build build.cmake --parallel 1 --verbose
       - |
           # make
           echo -e "\e[0Ksection_end:`date +%s`:make\r\e[0K"
diff --git a/.gitlab/ci/jobs/debian-stable-clang-amd64.yml b/.gitlab/ci/jobs/debian-stable-clang-amd64.yml
index 4686c1849196d3be6cbee936c1ad910c0f93627c..c40998e17af3157856f92fbb0121c409655900bc 100644
--- a/.gitlab/ci/jobs/debian-stable-clang-amd64.yml
+++ b/.gitlab/ci/jobs/debian-stable-clang-amd64.yml
@@ -9,8 +9,8 @@ Debian stable Clang:
 
   artifacts:
     paths:
-      - "build.clang/bin/"
-      - "build.clang/src/config.h"
+      - "build.cmake/bin/"
+      - "build.cmake/src/config.h"
     expose_as: "clang"
     name: "$CI_PROJECT_PATH_SLUG-$CI_COMMIT_REF_SLUG-$CI_COMMIT_SHORT_SHA-clang"
 
@@ -41,7 +41,7 @@ Debian stable Clang:
     - - |
           # cmake
           echo -e "\e[0Ksection_start:`date +%s`:cmake[collapsed=false]\r\e[0KBuilding Makefiles"
-      - cmake -B build.clang -DCPM_USE_LOCAL_PACKAGES:BOOL=ON -DSRB2_CONFIG_ENABLE_TESTS:BOOL=OFF -DSRB2_CONFIG_SYSTEM_LIBRARIES:BOOL=ON -DSRB2_USE_LIBGME:BOOL=OFF -G "Unix Makefiles"
+      - cmake -B build.cmake -DCPM_USE_LOCAL_PACKAGES:BOOL=ON -DSRB2_CONFIG_ENABLE_TESTS:BOOL=OFF -DSRB2_CONFIG_SYSTEM_LIBRARIES:BOOL=ON -DSRB2_USE_LIBGME:BOOL=OFF -DSRB2_CONFIG_USE_GME:BOOL=ON
       - |
           # cmake
           echo -e "\e[0Ksection_end:`date +%s`:cmake\r\e[0K"
@@ -49,7 +49,7 @@ Debian stable Clang:
     - - |
           # make
           echo -e "\e[0Ksection_start:`date +%s`:make[collapsed=false]\r\e[0KCompiling SRB2"
-      - make --directory=build.clang --keep-going || make --directory=build.clang --keep-going
+      - cmake  --build build.cmake --parallel 1 --verbose
       - |
           # make
           echo -e "\e[0Ksection_end:`date +%s`:make\r\e[0K"
diff --git a/.gitlab/ci/jobs/debian-stable-i386.yml b/.gitlab/ci/jobs/debian-stable-i386.yml
index ad4dcbb4ff25f7d8c91d4808c09851747ebcaaca..970b92a69c6f00ff508a0126bd1b82962f8e5c48 100644
--- a/.gitlab/ci/jobs/debian-stable-i386.yml
+++ b/.gitlab/ci/jobs/debian-stable-i386.yml
@@ -40,7 +40,7 @@ Debian stable:i386:
     - - |
           # cmake
           echo -e "\e[0Ksection_start:`date +%s`:cmake[collapsed=false]\r\e[0KBuilding Makefiles"
-      - cmake -B build.cmake -DSRB2_USE_CCACHE=YES -DSRB2_CONFIG_ERRORMODE=ON -G "Unix Makefiles"
+      - cmake -B build.cmake -DSRB2_USE_CCACHE=YES -DSRB2_CONFIG_ERRORMODE=ON -DSRB2_CONFIG_USE_GME:BOOL=ON
       - |
           # cmake
           echo -e "\e[0Ksection_end:`date +%s`:cmake\r\e[0K"
@@ -48,7 +48,7 @@ Debian stable:i386:
     - - |
           # make
           echo -e "\e[0Ksection_start:`date +%s`:make[collapsed=false]\r\e[0KCompiling SRB2"
-      - make --directory=build.cmake --keep-going || make --directory=build.cmake --keep-going
+      - cmake --build build.cmake --parallel 1 --verbose
       - |
           # make
           echo -e "\e[0Ksection_end:`date +%s`:make\r\e[0K"
diff --git a/.gitlab/ci/jobs/debian-testing-clang-amd64.yml b/.gitlab/ci/jobs/debian-testing-clang-amd64.yml
index dc790b397f2187b47a75c05bcf3e5973d5a175e1..7349f2b92869f2b378787a573a394a506f9ecb82 100644
--- a/.gitlab/ci/jobs/debian-testing-clang-amd64.yml
+++ b/.gitlab/ci/jobs/debian-testing-clang-amd64.yml
@@ -19,4 +19,3 @@ Debian testing Clang:
     CXX: clang
     WFLAGS: -Wno-cast-align -Wno-implicit-const-int-float-conversion -Werror -Wno-deprecated-non-prototype -Wno-single-bit-bitfield-constant-conversion
     CFLAGS: -Wno-cast-align -Wno-implicit-const-int-float-conversion -Werror -Wno-deprecated-non-prototype -Wno-single-bit-bitfield-constant-conversion
-    LDFLAGS: -Wl,-fuse-ld=gold
diff --git a/.gitlab/ci/jobs/debian-testing-gcc-amd64-makefile.yml b/.gitlab/ci/jobs/debian-testing-gcc-amd64-makefile.yml
index 70d71b537703e6ef07dcd572dec0d318d86e9d93..1165b1fea3e9ef2eb8db122f51a3dcb14174b15b 100644
--- a/.gitlab/ci/jobs/debian-testing-gcc-amd64-makefile.yml
+++ b/.gitlab/ci/jobs/debian-testing-gcc-amd64-makefile.yml
@@ -19,7 +19,6 @@ Debian testing GCC Makefile:
   variables:
     CC: gcc
     CXX: g++
-    LDFLAGS: -Wl,-fuse-ld=gold
 
   script:
     - - |
diff --git a/.gitlab/ci/jobs/debian-testing-gcc-amd64.yml b/.gitlab/ci/jobs/debian-testing-gcc-amd64.yml
index 7efb6c62dfc9fdc32764c9162bcd1d1449ba8387..fc998ea47b78b10476e72d6605c9ecfe6ea54009 100644
--- a/.gitlab/ci/jobs/debian-testing-gcc-amd64.yml
+++ b/.gitlab/ci/jobs/debian-testing-gcc-amd64.yml
@@ -19,7 +19,6 @@ Debian testing GCC:
   variables:
     CC: gcc
     CXX: g++
-    LDFLAGS: -Wl,-fuse-ld=gold
 
   script:
     - - |
@@ -41,7 +40,7 @@ Debian testing GCC:
     - - |
           # cmake
           echo -e "\e[0Ksection_start:`date +%s`:cmake[collapsed=false]\r\e[0KBuilding Makefiles"
-      - cmake -B build.cmake -DSRB2_USE_CCACHE=YES -DSRB2_CONFIG_ERRORMODE=ON -G "Unix Makefiles"
+      - cmake -B build.cmake -DSRB2_USE_CCACHE=YES -DSRB2_CONFIG_ERRORMODE=ON -DSRB2_CONFIG_USE_GME:BOOL=ON
       - |
           # cmake
           echo -e "\e[0Ksection_end:`date +%s`:cmake\r\e[0K"
@@ -49,7 +48,7 @@ Debian testing GCC:
     - - |
           # make
           echo -e "\e[0Ksection_start:`date +%s`:make[collapsed=false]\r\e[0KCompiling SRB2"
-      - make --directory=build.cmake --keep-going || make --directory=build.cmake --keep-going
+      - cmake --build build.cmake --parallel 1 --verbose
       - |
           # make
           echo -e "\e[0Ksection_end:`date +%s`:make\r\e[0K"
diff --git a/.gitlab/ci/jobs/macos-arm64.yml b/.gitlab/ci/jobs/macos-arm64.yml
index a9e31773e6b2d58ffa4fce856085a83ad0f8bece..1c89000c2f540bc1b1251f66aba833a6557ad9f9 100644
--- a/.gitlab/ci/jobs/macos-arm64.yml
+++ b/.gitlab/ci/jobs/macos-arm64.yml
@@ -3,16 +3,13 @@ osxcross arm64:
 
   stage: build
 
-  when: manual
-
-  allow_failure: true
-
   artifacts:
     paths:
-      - "build.osxcross/bin/"
-      - "build.osxcross/src/config.h"
+      - "build.arm64/bin/"
+      - "build.arm64/dist/arm64.h"
+      - "build.arm64/src/config.h"
     expose_as: "Mac arm64"
-    name: "$CI_PROJECT_PATH_SLUG-$CI_COMMIT_REF_SLUG-$CI_COMMIT_SHORT_SHA-clang"
+    name: "$CI_PROJECT_PATH_SLUG-$CI_COMMIT_REF_SLUG-$CI_COMMIT_SHORT_SHA-arm64-apple-darwin21.4"
 
   variables:
     OSXCROSS_HOST: arm64-apple-darwin21.4
@@ -22,7 +19,8 @@ osxcross arm64:
     - - |
           # apt_development
           echo -e "\e[0Ksection_start:`date +%s`:macports_development[collapsed=true]\r\e[0KInstalling development packages"
-      - osxcross-macports install --arm64 curl libopenmpt libsdl2_mixer
+      - osxcross-macports install --arm64 libxmp wavpack libopenmpt opusfile || osxcross-macports install --arm64 libxmp wavpack libopenmpt opusfile
+      - osxcross-macports install --static --arm64 curl libsdl2_mixer libpng || osxcross-macports install --static --arm64 curl libsdl2_mixer libpng
       - |
           # apt_development
           echo -e "\e[0Ksection_end:`date +%s`:macports_development\r\e[0K"
@@ -30,7 +28,7 @@ osxcross arm64:
     - - |
           # cmake
           echo -e "\e[0Ksection_start:`date +%s`:cmake[collapsed=false]\r\e[0KBuilding Makefiles"
-      - cmake -B build.osxcross --toolchain /osxcross/toolchain.cmake -DCPM_USE_LOCAL_PACKAGES:BOOL=ON -DOPENMPT_INCLUDE_DIR:PATH="/osxcross/macports/pkgs/opt/local/include" -DSDL2_INCLUDE_DIR:PATH="/osxcross/macports/pkgs/opt/local/lib" -DSRB2_CONFIG_ENABLE_TESTS:BOOL=OFF -DSRB2_CONFIG_SYSTEM_LIBRARIES:BOOL=ON -DSRB2_CONFIG_FORCE_NO_MS_BITFIELDS:BOOL=ON -DSRB2_CONFIG_USE_GME:BOOL=OFF -G "Unix Makefiles"
+      - cmake -B build.arm64 --toolchain /osxcross/toolchain.cmake -DCPM_USE_LOCAL_PACKAGES:BOOL=ON -DOPENMPT_INCLUDE_DIR:PATH="/osxcross/macports/pkgs/opt/local/include" -DSDL2_INCLUDE_DIR:PATH="/osxcross/macports/pkgs/opt/local/lib" -DSRB2_CONFIG_ENABLE_TESTS:BOOL=OFF -DSRB2_CONFIG_SYSTEM_LIBRARIES:BOOL=ON -DSRB2_CONFIG_FORCE_NO_MS_BITFIELDS:BOOL=ON -DSRB2_CONFIG_USE_GME:BOOL=OFF -DSRB2_SDL2_EXE_NAME=srb2_$CI_PIPELINE_ID
       - |
           # make
           echo -e "\e[0Ksection_end:`date +%s`:make\r\e[0K"
@@ -38,7 +36,16 @@ osxcross arm64:
     - - |
           # make
           echo -e "\e[0Ksection_start:`date +%s`:make[collapsed=false]\r\e[0KCompiling SRB2"
-      - make --directory=build.osxcross --keep-going || make --directory=build.osxcross --keep-going
+      - cmake --build build.arm64 --parallel 1 --verbose
       - |
           # make
           echo -e "\e[0Ksection_end:`date +%s`:make\r\e[0K"
+
+    - - |
+          # copy config.h
+          echo -e "\e[0Ksection_start:`date +%s`:copy[collapsed=false]\r\e[0KCopying config.h"
+      - mkdir --parents --verbose build.arm64/dist
+      - cp --reflink=auto --sparse=always --verbose build.arm64/src/config.h build.arm64/dist/arm64.h
+      - |
+          # make
+          echo -e "\e[0Ksection_end:`date +%s`:copy\r\e[0K"
diff --git a/.gitlab/ci/jobs/macos-x86_64.yml b/.gitlab/ci/jobs/macos-x86_64.yml
index 525a919c8a6976308d752bc82e68143233d59798..d40ae65f6c7729bf82d005c9024627da0fd36274 100644
--- a/.gitlab/ci/jobs/macos-x86_64.yml
+++ b/.gitlab/ci/jobs/macos-x86_64.yml
@@ -29,10 +29,11 @@ osxcross x86_64:
 
   artifacts:
     paths:
-      - "build.osxcross/bin/"
-      - "build.osxcross/src/config.h"
+      - "build.x86_64/bin/"
+      - "build.x86_64/dist/x86_64.h"
+      - "build.x86_64/src/config.h"
     expose_as: "Mac x86_64"
-    name: "$CI_PROJECT_PATH_SLUG-$CI_COMMIT_REF_SLUG-$CI_COMMIT_SHORT_SHA-clang"
+    name: "$CI_PROJECT_PATH_SLUG-$CI_COMMIT_REF_SLUG-$CI_COMMIT_SHORT_SHA-x86_64-apple-darwin21.4"
 
   variables:
     OSXCROSS_HOST: x86_64-apple-darwin21.4
@@ -63,7 +64,8 @@ osxcross x86_64:
     - - |
           # apt_development
           echo -e "\e[0Ksection_start:`date +%s`:macports_development[collapsed=true]\r\e[0KInstalling development packages"
-      - osxcross-macports install curl libopenmpt libsdl2_mixer
+      - osxcross-macports install libxmp wavpack libopenmpt opusfile || osxcross-macports install libxmp wavpack libopenmpt opusfile
+      - osxcross-macports install --static curl libsdl2_mixer libpng || osxcross-macports install --static curl libsdl2_mixer libpng
       - |
           # apt_development
           echo -e "\e[0Ksection_end:`date +%s`:macports_development\r\e[0K"
@@ -71,7 +73,7 @@ osxcross x86_64:
     - - |
           # cmake
           echo -e "\e[0Ksection_start:`date +%s`:cmake[collapsed=false]\r\e[0KBuilding Makefiles"
-      - cmake -B build.osxcross --toolchain /osxcross/toolchain.cmake -DCPM_USE_LOCAL_PACKAGES:BOOL=ON -DOPENMPT_INCLUDE_DIR:PATH="/osxcross/macports/pkgs/opt/local/include" -DSDL2_INCLUDE_DIR:PATH="/osxcross/macports/pkgs/opt/local/lib" -DSRB2_CONFIG_ENABLE_TESTS:BOOL=OFF -DSRB2_CONFIG_SYSTEM_LIBRARIES:BOOL=ON -DSRB2_CONFIG_USE_GME:BOOL=OFF -G "Unix Makefiles"
+      - cmake -B build.x86_64 --toolchain /osxcross/toolchain.cmake -DCPM_USE_LOCAL_PACKAGES:BOOL=ON -DOPENMPT_INCLUDE_DIR:PATH="/osxcross/macports/pkgs/opt/local/include" -DSDL2_INCLUDE_DIR:PATH="/osxcross/macports/pkgs/opt/local/lib" -DSRB2_CONFIG_ENABLE_TESTS:BOOL=OFF -DSRB2_CONFIG_SYSTEM_LIBRARIES:BOOL=ON -DSRB2_CONFIG_USE_GME:BOOL=OFF -DSRB2_SDL2_EXE_NAME=srb2_$CI_PIPELINE_ID
       - |
           # make
           echo -e "\e[0Ksection_end:`date +%s`:make\r\e[0K"
@@ -79,11 +81,21 @@ osxcross x86_64:
     - - |
           # make
           echo -e "\e[0Ksection_start:`date +%s`:make[collapsed=false]\r\e[0KCompiling SRB2"
-      - make --directory=build.osxcross --keep-going || make --directory=build.osxcross --keep-going
+      - cmake  --build build.x86_64 --parallel 1 --verbose
       - |
           # make
           echo -e "\e[0Ksection_end:`date +%s`:make\r\e[0K"
 
+    - - |
+          # copy config.h
+          echo -e "\e[0Ksection_start:`date +%s`:copy[collapsed=false]\r\e[0KCopying config.h"
+      - mkdir --parents --verbose build.x86_64/dist
+      - cp --reflink=auto --sparse=always --verbose build.x86_64/src/config.h build.x86_64/dist/x86_64.h
+      - |
+          # make
+          echo -e "\e[0Ksection_end:`date +%s`:copy\r\e[0K"
+
+
   after_script:
     - - |
            # apt_clean
diff --git a/.gitlab/ci/jobs/osxccross-universal.yml b/.gitlab/ci/jobs/osxccross-universal.yml
new file mode 100644
index 0000000000000000000000000000000000000000..841151f60895c9ea966068a541fa74251dc3964e
--- /dev/null
+++ b/.gitlab/ci/jobs/osxccross-universal.yml
@@ -0,0 +1,67 @@
+osxcross universal:
+  image: git.do.srb2.org:5050/stjr/srb2ci/srb2ci:stable
+
+  dependencies:
+    - osxcross arm64
+    - osxcross x86_64
+  needs:
+    - job: osxcross arm64
+    - job: osxcross x86_64
+
+  stage: osxcross
+
+  artifacts:
+    paths:
+      - "dist/bin"
+      - "dist/src"
+    expose_as: "Mac Universal"
+    name: "$CI_PROJECT_PATH_SLUG-$CI_COMMIT_REF_SLUG-$CI_COMMIT_SHORT_SHA-lipo-apple-darwin21.4"
+
+  script:
+    - - |
+         # mkdir
+         echo -e "\e[0Ksection_start:`date +%s`:mkdir[collapsed=true]\r\e[0KMaking dist folder"
+         mkdir --parents --verbose dist/src dist/bin
+      - |
+          # mkdir
+          echo -e "\e[0Ksection_end:`date +%s`:mkdir\r\e[0K"
+
+    - - |
+         # copy-config
+         echo -e "\e[0Ksection_start:`date +%s`:x86_64-config[collapsed=true]\r\e[0KCopying x86_64 config"
+      - cp --reflink=auto --sparse=always --verbose --target-directory=dist/src/ build.*/dist/*.h
+      - |
+          # x86_64-config
+          echo -e "\e[0Ksection_end:`date +%s`:x86_64-config\r\e[0K"
+
+    - - |
+         # copy-build
+         echo -e "\e[0Ksection_start:`date +%s`:copy-build[collapsed=true]\r\e[0KCopying ALL build"
+      - cp --reflink=auto --sparse=always --recursive --verbose --target-directory=dist/ build.*/bin/
+      - |
+          # copy-build
+          echo -e "\e[0Ksection_end:`date +%s`:copy-build\r\e[0K"
+
+    - - |
+         # link-build
+         echo -e "\e[0Ksection_start:`date +%s`:link-build[collapsed=true]\r\e[0KLinking universal build"
+      - lipo -create -output dist/bin/srb2_$CI_PIPELINE_ID.app/Contents/MacOS/srb2_$CI_PIPELINE_ID build.*/bin/srb2_$CI_PIPELINE_ID.app/Contents/MacOS/srb2_$CI_PIPELINE_ID
+      - |
+          # universal-build
+          echo -e "\e[0Ksection_end:`date +%s`:link-build\r\e[0K"
+
+    - - |
+         # arm64-verify
+         echo -e "\e[0Ksection_start:`date +%s`:arm64-verify[collapsed=true]\r\e[0KVerifying arm64"
+      - lipo dist/bin/srb2_$CI_PIPELINE_ID.app/Contents/MacOS/srb2_$CI_PIPELINE_ID -verify_arch arm64
+      - |
+          # arm64-verify
+          echo -e "\e[0Ksection_end:`date +%s`:arm64-verify\r\e[0K"
+
+    - - |
+         # x86_64-verify
+         echo -e "\e[0Ksection_start:`date +%s`:x86_64-verify[collapsed=true]\r\e[0KVerifying x86_64"
+      - lipo dist/bin/srb2_$CI_PIPELINE_ID.app/Contents/MacOS/srb2_$CI_PIPELINE_ID -verify_arch x86_64
+      - |
+          # x86_64-verify
+          echo -e "\e[0Ksection_end:`date +%s`:x86_64-verify\r\e[0K"
diff --git a/.gitlab/ci/jobs/windows-x64.yml b/.gitlab/ci/jobs/windows-x64.yml
index e5accf926bc96daeef9e55c948bb3e4c43e3a5b6..73791e82a202d91f1b0bc4c28e764bb0a846941a 100644
--- a/.gitlab/ci/jobs/windows-x64.yml
+++ b/.gitlab/ci/jobs/windows-x64.yml
@@ -7,6 +7,30 @@ Windows x64:
 
   allow_failure: true
 
+  cache:
+    - key: ccache-$CI_JOB_NAME_SLUG-$CI_COMMIT_REF_SLUG
+      fallback_keys:
+        - ccache-$CI_JOB_NAME_SLUG-$CI_DEFAULT_BRANCH
+        - ccache-$CI_JOB_NAME_SLUG-master
+      paths:
+        - build/ccache
+        - build/ccache_statslog
+
+    - key: apt-$CI_JOB_IMAGE
+      paths:
+        - build/apt-cache
+      unprotect: true
+
+    - key: vcpkg-root
+      paths:
+        - build/vcpkg-root
+      unprotect: true
+
+    - key: vcpkg-binary-cache-x64-mingw-static
+      paths:
+        - build/vcpkg-binary-cache
+      unprotect: true
+
   artifacts:
     paths:
       - "build.cmake/bin/"
@@ -16,8 +40,31 @@ Windows x64:
 
   variables:
     PREFIX: x86_64-w64-mingw32
+    CC: /usr/lib/ccache/x86_64-w64-mingw32-gcc
+    CXX: /usr/lib/ccache/x86_64-w64-mingw32-g++
 
   script:
+    - |
+        # vcpkg
+        echo -e "\e[0Ksection_start:`date +%s`:vcpkg-root[collapsed=true]\r\e[0KUpdating vcpkg"
+
+        if [ -d "build/vcpkg-root" ]; then
+          pushd build/vcpkg-root
+          git fetch https://github.com/Microsoft/vcpkg master
+          git reset --hard FETCH_HEAD
+          popd
+        else
+          mkdir -p build
+          git clone https://github.com/Microsoft/vcpkg build/vcpkg-root
+        fi
+
+        export VCPKG_ROOT=$(pwd)/build/vcpkg-root
+        export VCPKG_BINARY_SOURCES="clear;files,/opt/vcpkg.bsources,read;files,$(pwd)/build/vcpkg-binary-cache,readwrite"
+
+        mkdir -p "build/vcpkg-binary-cache"
+
+        echo -e "\e[0Ksection_end:`date +%s`:vcpkg-root\r\e[0K"
+
     - - |
           # apt_toolchain
           echo -e "\e[0Ksection_start:`date +%s`:apt_toolchain[collapsed=true]\r\e[0KInstalling toolchain packages"
@@ -37,7 +84,7 @@ Windows x64:
     - - |
           # cmake
           echo -e "\e[0Ksection_start:`date +%s`:cmake[collapsed=false]\r\e[0KBuilding Makefiles"
-      - cmake -B build.cmake -DSRB2_USE_CCACHE=YES -DSRB2_CONFIG_ERRORMODE=ON -DCMAKE_TOOLCHAIN_FILE=$VCPKG_ROOT/scripts/buildsystems/vcpkg.cmake -DVCPKG_TARGET_TRIPLET=x64-mingw-static -DVCPKG_CHAINLOAD_TOOLCHAIN_FILE=$VCPKG_ROOT/scripts/toolchains/mingw.cmake
+      - cmake -B build.cmake -DSRB2_USE_CCACHE=NO -DSRB2_CONFIG_ERRORMODE=ON -DCMAKE_TOOLCHAIN_FILE=$VCPKG_ROOT/scripts/buildsystems/vcpkg.cmake -DVCPKG_TARGET_TRIPLET=x64-mingw-static -DVCPKG_CHAINLOAD_TOOLCHAIN_FILE=$VCPKG_ROOT/scripts/toolchains/mingw.cmake -G "Unix Makefiles"
       - |
           # cmake
           echo -e "\e[0Ksection_end:`date +%s`:cmake\r\e[0K"
@@ -45,7 +92,37 @@ Windows x64:
     - - |
           # make
           echo -e "\e[0Ksection_start:`date +%s`:make[collapsed=false]\r\e[0KCompiling SRB2"
-      - make --directory=build.cmake --keep-going || make --directory=build.cmake --keep-going
+      - cmake --build build.cmake --parallel 1 --verbose
       - |
           # make
           echo -e "\e[0Ksection_end:`date +%s`:make\r\e[0K"
+
+  after_script:
+    - - |
+           # apt_clean
+           echo -e "\e[0Ksection_start:`date +%s`:apt_clean[collapsed=true]\r\e[0KCleaning of unneeded APT packages"
+      - apt-get autoclean
+      - |
+          # apt_clean
+          echo -e "\e[0Ksection_end:`date +%s`:apt_clean\r\e[0K"
+
+    - - |
+          # vcpkg_clean
+          echo -e "\e[0Ksection_start:`date +%s`:vcpkg_clean[collapsed=true]\r\e[0KCleaning vcpkg-root"
+
+          if [ -d "build/vcpkg-root" ]; then
+            pushd "build/vcpkg-root"
+            git clean -f
+            popd
+          fi
+
+          echo -e "\e[0Ksection_end:`date +%s`:vcpkg_clean\r\e[0K"
+
+    - - |
+          # ccache_stats
+          echo -e "\e[0Ksection_start:`date +%s`:ccache_stats[collapsed=true]\r\e[0Kccache statistics:"
+      - ccache --show-stats
+      - ccache --show-log-stats || true
+      - |
+          # ccahe_stats
+          echo -e "\e[0Ksection_end:`date +%s`:ccache_stats\r\e[0K"
diff --git a/.gitlab/ci/jobs/windows-x86.yml b/.gitlab/ci/jobs/windows-x86.yml
index f983c82875cebce4d41b616984ce8c17bf4b3e85..9a33364b2830df79055838037563a2711fd51d04 100644
--- a/.gitlab/ci/jobs/windows-x86.yml
+++ b/.gitlab/ci/jobs/windows-x86.yml
@@ -3,10 +3,6 @@ Windows x86:
 
   stage: build
 
-  when: manual
-
-  allow_failure: true
-
   cache:
     - key: ccache-$CI_JOB_NAME_SLUG-$CI_COMMIT_REF_SLUG
       fallback_keys:
@@ -33,15 +29,15 @@ Windows x86:
 
   artifacts:
     paths:
-      - "build/ninja-x86_mingw_static_vcpkg-debug/bin/"
-      - "build/ninja-x86_mingw_static_vcpkg-debug/src/config.h"
+      - "build.cmake/bin/"
+      - "build.cmake/src/config.h"
     expose_as: "Win32"
     name: "$CI_PROJECT_PATH_SLUG-$CI_COMMIT_REF_SLUG-$CI_COMMIT_SHORT_SHA-Win32"
 
   variables:
     PREFIX: i686-w64-mingw32
-    CC: /usr/bin/i686-w64-mingw32-gcc-posix
-    CXX: /usr/bin/i686-w64-mingw32-g++-posix
+    CC: /usr/lib/ccache/i686-w64-mingw32-gcc
+    CXX: /usr/lib/ccache/i686-w64-mingw32-g++
 
   script:
     - |
@@ -59,7 +55,7 @@ Windows x86:
         fi
 
         export VCPKG_ROOT=$(pwd)/build/vcpkg-root
-        export VCPKG_BINARY_SOURCES="clear;files,$(pwd)/build/vcpkg-binary-cache,readwrite"
+        export VCPKG_BINARY_SOURCES="clear;files,/opt/vcpkg.bsources,read;files,$(pwd)/build/vcpkg-binary-cache,readwrite"
 
         mkdir -p "build/vcpkg-binary-cache"
 
@@ -84,9 +80,7 @@ Windows x86:
     - - |
           # cmake
           echo -e "\e[0Ksection_start:`date +%s`:cmake[collapsed=false]\r\e[0KBuilding Makefiles"
-          # cmake
-          echo -e "\e[0Ksection_start:`date +%s`:cmake[collapsed=false]\r\e[0KBuilding Makefiles"
-      - cmake --preset ninja-x86_mingw_static_vcpkg-debug -G "Unix Makefiles" -DSRB2_USE_CCACHE=YES -DSRB2_CONFIG_ERRORMODE=ON -DCMAKE_TOOLCHAIN_FILE=$VCPKG_ROOT/scripts/buildsystems/vcpkg.cmake
+      - cmake -B build.cmake -DSRB2_USE_CCACHE=NO -DSRB2_CONFIG_ERRORMODE=ON -DCMAKE_TOOLCHAIN_FILE=$VCPKG_ROOT/scripts/buildsystems/vcpkg.cmake -DVCPKG_TARGET_TRIPLET=x86-mingw-static -DVCPKG_CHAINLOAD_TOOLCHAIN_FILE=$VCPKG_ROOT/scripts/toolchains/mingw.cmake -G "Unix Makefiles"
       - |
           # cmake
           echo -e "\e[0Ksection_end:`date +%s`:cmake\r\e[0K"
@@ -94,7 +88,7 @@ Windows x86:
     - - |
           # make
           echo -e "\e[0Ksection_start:`date +%s`:make[collapsed=false]\r\e[0KCompiling SRB2"
-      - cmake --build --preset ninja-x86_mingw_static_vcpkg-debug --parallel 1 -- --keep-going || cmake --build --preset ninja-x86_mingw_static_vcpkg-debug --parallel 1 -- --keep-going
+      - cmake --build build.cmake --parallel 1 --verbose
       - |
           # make
           echo -e "\e[0Ksection_end:`date +%s`:make\r\e[0K"
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 2cfb56f6e9645b126320f1242da095737ac866d5..fbc34173390a1be01be3058772629779558f5c4a 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -464,8 +464,13 @@ else()
 endif()
 
 if(TARGET miniupnpc::miniupnpc)
-	target_compile_definitions(SRB2SDL2 PRIVATE -DHAVE_MINIUPNPC)
-	target_link_libraries(SRB2SDL2 PRIVATE miniupnpc::miniupnpc)
+	if("${VCPKG_TARGET_TRIPLET}" MATCHES "-mingw-static$")
+		target_compile_definitions(SRB2SDL2 PRIVATE -DHAVE_MINIUPNPC -DMINIUPNP_STATICLIB)
+		target_link_libraries(SRB2SDL2 PRIVATE miniupnpc::miniupnpc -liphlpapi)
+	else()
+		target_compile_definitions(SRB2SDL2 PRIVATE -DHAVE_MINIUPNPC)
+		target_link_libraries(SRB2SDL2 PRIVATE miniupnpc::miniupnpc)
+	endif()
 	message(STATUS "miniupnpc Found")
 else()
 	message(STATUS "No miniupnpc Found")
diff --git a/src/m_menu.c b/src/m_menu.c
index 37d191a0df84158e31d0d782d6f4b2d6b819eadc..be1b421f75c29a87c98b9e0ab3b97c6566f13038 100644
--- a/src/m_menu.c
+++ b/src/m_menu.c
@@ -3892,6 +3892,9 @@ void M_Ticker(void)
 		M_SetupScreenshotMenu();
 
 #if defined (MASTERSERVER) && defined (HAVE_THREADS)
+	if (!netgame)
+		return;
+
 	I_lock_mutex(&ms_ServerList_mutex);
 	{
 		if (ms_ServerList)
diff --git a/src/netcode/http-mserv.c b/src/netcode/http-mserv.c
index 8ce20af956008d2e522a08dc0aa98756174252d8..0fe1e9934265c301c78e77c9650ea952c61cc68d 100644
--- a/src/netcode/http-mserv.c
+++ b/src/netcode/http-mserv.c
@@ -63,7 +63,11 @@ consvar_t cv_masterserver_token = CVAR_INIT
 
 static int hms_started;
 
+static boolean hms_args_checked;
+#ifndef NO_IPV6
 static boolean hms_allow_ipv6;
+#endif
+static boolean hms_allow_ipv4;
 
 static char *hms_api;
 #ifdef HAVE_THREADS
@@ -134,6 +138,18 @@ HMS_on_read (char *s, size_t _1, size_t n, void *userdata)
 	return n;
 }
 
+static void HMS_check_args_once(void)
+{
+	if (hms_args_checked)
+		return;
+
+#ifndef NO_IPV6
+	hms_allow_ipv6 = !M_CheckParm("-noipv6");
+#endif
+	hms_allow_ipv4 = !M_CheckParm("-noipv4");
+	hms_args_checked = true;
+}
+
 FUNCDEBUG static struct HMS_buffer *
 HMS_connect (int proto, const char *format, ...)
 {
@@ -152,7 +168,6 @@ HMS_connect (int proto, const char *format, ...)
 
 	if (! hms_started)
 	{
-		hms_allow_ipv6 = !M_CheckParm("-noipv6");
 		if (curl_global_init(CURL_GLOBAL_ALL) != 0)
 		{
 			Contact_error();
@@ -225,20 +240,27 @@ HMS_connect (int proto, const char *format, ...)
 		curl_easy_setopt(curl, CURLOPT_STDERR, logstream);
 	}
 
-	if (M_CheckParm("-bindaddr") && M_IsNextParm())
-	{
-		curl_easy_setopt(curl, CURLOPT_INTERFACE, M_GetNextParm());
-	}
-
 	curl_easy_setopt(curl, CURLOPT_URL, url);
 	curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
 
 #ifndef NO_IPV6
-	if (proto == PROTO_V6)
+	if (proto == PROTO_V6 || (proto == PROTO_ANY && !hms_allow_ipv4))
+	{
 		curl_easy_setopt(curl, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V6);
-	if (proto == PROTO_V4)
+		if (M_CheckParm("-bindaddr6") && M_IsNextParm())
+		{
+			curl_easy_setopt(curl, CURLOPT_INTERFACE, M_GetNextParm());
+		}
+	}
+	if (proto == PROTO_V4 || (proto == PROTO_ANY && !hms_allow_ipv6))
 #endif
+	{
 		curl_easy_setopt(curl, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
+		if (M_CheckParm("-bindaddr") && M_IsNextParm())
+		{
+			curl_easy_setopt(curl, CURLOPT_INTERFACE, M_GetNextParm());
+		}
+	}
 
 	curl_easy_setopt(curl, CURLOPT_TIMEOUT, cv_masterserver_timeout.value);
 	curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, HMS_on_read);
@@ -326,6 +348,8 @@ HMS_fetch_rooms (int joining, int query_id)
 
 	(void)query_id;
 
+	HMS_check_args_once();
+
 	hms = HMS_connect(PROTO_ANY, "rooms");
 
 	if (! hms)
@@ -420,18 +444,15 @@ int
 HMS_register (void)
 {
 	struct HMS_buffer *hms;
-	int ok;
+	int ok = 0;
 
 	char post[256];
 
 	char *title;
 
-	hms = HMS_connect(PROTO_V4, "rooms/%d/register", cv_masterserver_room_id.value);
+	HMS_check_args_once();
 
-	if (! hms)
-		return 0;
-
-	title = curl_easy_escape(hms->curl, cv_servername.string, 0);
+	title = curl_easy_escape(NULL, cv_servername.string, 0);
 
 	snprintf(post, sizeof post,
 			"port=%d&"
@@ -447,16 +468,24 @@ HMS_register (void)
 
 	curl_free(title);
 
-	curl_easy_setopt(hms->curl, CURLOPT_POSTFIELDS, post);
+	if (hms_allow_ipv4)
+	{
+		hms = HMS_connect(PROTO_V4, "rooms/%d/register", cv_masterserver_room_id.value);
 
-	ok = HMS_do(hms);
+		if (! hms)
+			return 0;
 
-	if (ok)
-	{
-		hms_server_token = strdup(strtok(hms->buffer, "\n"));
-	}
+		curl_easy_setopt(hms->curl, CURLOPT_POSTFIELDS, post);
 
-	HMS_end(hms);
+		ok = HMS_do(hms);
+
+		if (ok)
+		{
+			hms_server_token = strdup(strtok(hms->buffer, "\n"));
+		}
+
+		HMS_end(hms);
+	}
 
 #ifndef NO_IPV6
 	if (!hms_allow_ipv6)
@@ -488,7 +517,9 @@ HMS_unlist (void)
 	struct HMS_buffer *hms;
 	int ok = 0;
 
-	if (hms_server_token)
+	HMS_check_args_once();
+
+	if (hms_server_token && hms_allow_ipv4)
 	{
 		hms = HMS_connect(PROTO_V4, "servers/%s/unlist", hms_server_token);
 
@@ -535,6 +566,7 @@ HMS_update (void)
 
 	char *title;
 
+	HMS_check_args_once();
 	title = curl_easy_escape(NULL, cv_servername.string, 0);
 
 	snprintf(post, sizeof post,
@@ -544,7 +576,7 @@ HMS_update (void)
 
 	curl_free(title);
 
-	if (hms_server_token)
+	if (hms_server_token && hms_allow_ipv4)
 	{
 		hms = HMS_connect(PROTO_V4, "servers/%s/update", hms_server_token);
 
@@ -583,6 +615,8 @@ HMS_list_servers (void)
 	char *list;
 	char *p;
 
+	HMS_check_args_once();
+
 	hms = HMS_connect(PROTO_ANY, "servers");
 
 	if (! hms)
@@ -628,6 +662,8 @@ HMS_fetch_servers (msg_server_t *list, int room_number, int query_id)
 
 	int i;
 
+	HMS_check_args_once();
+
 	(void)query_id;
 
 	if (room_number > 0)
@@ -739,6 +775,8 @@ HMS_compare_mod_version (char *buffer, size_t buffer_size)
 	char *version;
 	char *version_name;
 
+	HMS_check_args_once();
+
 	hms = HMS_connect(PROTO_ANY, "versions/%d", MODID);
 
 	if (! hms)
diff --git a/src/netcode/i_tcp.c b/src/netcode/i_tcp.c
index 58fb921d6008e5d5b29c2cb181cdadb73dbe9c4a..2b8a10c9339cebc114540d0a845ee3ba75b80326 100644
--- a/src/netcode/i_tcp.c
+++ b/src/netcode/i_tcp.c
@@ -702,9 +702,13 @@ static void SOCK_Send(void)
 	else
 	{
 		c = SOCK_SendToAddr(nodesocket[doomcom->remotenode], &clientaddress[doomcom->remotenode]);
+		if (c == ERRSOCKET)
+		{
+			e = errno;
+		}
 	}
 
-	if (c == ERRSOCKET)
+	if (c == ERRSOCKET && e != -1) // -1 means no socket for the address family was found
 	{
 		if (!ALLOWEDERROR(e))
 			I_Error("SOCK_Send, error sending to node %d (%s) #%u, %s", doomcom->remotenode,
@@ -933,6 +937,7 @@ static boolean UDP_Socket(void)
 #ifdef HAVE_IPV6
 	const INT32 b_ipv6 = !M_CheckParm("-noipv6");
 #endif
+	const INT32 b_ipv4 = !M_CheckParm("-noipv4");
 	const char *serv;
 
 
@@ -960,11 +965,33 @@ static boolean UDP_Socket(void)
 	else
 		serv = clientport_name;
 
-	if (M_CheckParm("-bindaddr"))
+	if (b_ipv4)
 	{
-		while (M_IsNextParm())
+		if (M_CheckParm("-bindaddr"))
 		{
-			gaie = I_getaddrinfo(M_GetNextParm(), serv, &hints, &ai);
+			while (M_IsNextParm())
+			{
+				gaie = I_getaddrinfo(M_GetNextParm(), serv, &hints, &ai);
+				if (gaie == 0)
+				{
+					runp = ai;
+					while (runp != NULL && s < MAXNETNODES+1)
+					{
+						mysockets[s] = UDP_Bind(runp->ai_family, runp->ai_addr, (socklen_t)runp->ai_addrlen);
+						if (mysockets[s] != (SOCKET_TYPE)ERRSOCKET)
+						{
+							myfamily[s] = hints.ai_family;
+							s++;
+						}
+						runp = runp->ai_next;
+					}
+					I_freeaddrinfo(ai);
+				}
+			}
+		}
+		else
+		{
+			gaie = I_getaddrinfo("0.0.0.0", serv, &hints, &ai);
 			if (gaie == 0)
 			{
 				runp = ai;
@@ -975,6 +1002,13 @@ static boolean UDP_Socket(void)
 					{
 						myfamily[s] = hints.ai_family;
 						s++;
+#ifdef HAVE_MINIUPNPC
+						if (UPNP_support)
+						{
+							I_UPnP_rem(serverport_name, "UDP");
+							I_UPnP_add(NULL, serverport_name, "UDP");
+						}
+#endif
 					}
 					runp = runp->ai_next;
 				}
@@ -982,32 +1016,6 @@ static boolean UDP_Socket(void)
 			}
 		}
 	}
-	else
-	{
-		gaie = I_getaddrinfo("0.0.0.0", serv, &hints, &ai);
-		if (gaie == 0)
-		{
-			runp = ai;
-			while (runp != NULL && s < MAXNETNODES+1)
-			{
-				mysockets[s] = UDP_Bind(runp->ai_family, runp->ai_addr, (socklen_t)runp->ai_addrlen);
-				if (mysockets[s] != (SOCKET_TYPE)ERRSOCKET)
-				{
-					myfamily[s] = hints.ai_family;
-					s++;
-#ifdef HAVE_MINIUPNPC
-					if (UPNP_support)
-					{
-						I_UPnP_rem(serverport_name, "UDP");
-						I_UPnP_add(NULL, serverport_name, "UDP");
-					}
-#endif
-				}
-				runp = runp->ai_next;
-			}
-			I_freeaddrinfo(ai);
-		}
-	}
 #ifdef HAVE_IPV6
 	if (b_ipv6)
 	{
@@ -1072,11 +1080,14 @@ static boolean UDP_Socket(void)
 
 	s = 0;
 
-	// setup broadcast adress to BROADCASTADDR entry
-	broadcastaddress[s].any.sa_family = AF_INET;
-	broadcastaddress[s].ip4.sin_port = htons(atoi(DEFAULTPORT));
-	broadcastaddress[s].ip4.sin_addr.s_addr = htonl(INADDR_BROADCAST);
-	s++;
+	if (b_ipv4)
+	{
+		// setup broadcast adress to BROADCASTADDR entry
+		broadcastaddress[s].any.sa_family = AF_INET;
+		broadcastaddress[s].ip4.sin_port = htons(atoi(DEFAULTPORT));
+		broadcastaddress[s].ip4.sin_addr.s_addr = htonl(INADDR_BROADCAST);
+		s++;
+	}
 
 #ifdef HAVE_IPV6
 	if (b_ipv6)
@@ -1205,7 +1216,7 @@ static SINT8 SOCK_NetMakeNodewPort(const char *address, const char *port)
 	DEBFILE(va("Creating new node: %s@%s\n", address, port));
 
 	memset (&hints, 0x00, sizeof (hints));
-	hints.ai_flags = 0;
+	hints.ai_flags = AI_ADDRCONFIG;
 	hints.ai_family = AF_UNSPEC;
 	hints.ai_socktype = SOCK_DGRAM;
 	hints.ai_protocol = IPPROTO_UDP;
@@ -1235,7 +1246,7 @@ static SINT8 SOCK_NetMakeNodewPort(const char *address, const char *port)
 			}
 		}
 
-		if (i < mysocketses)
+		if (i >= mysocketses)
 			runp = runp->ai_next;
 		else
 			break;