Merge remote-tracking branch 'origin/master' into duel

This commit is contained in:
Antonio Martinez 2025-05-24 16:34:36 -04:00
commit 28f12acab1
825 changed files with 80518 additions and 15235 deletions

3
.gitattributes vendored
View file

@ -20,6 +20,9 @@
*.csproj* -crlf -whitespace
*.vcxproj* -crlf -whitespace
*.manifest -crlf -whitespace
# vcpkg
/vcpkg.json text=auto
/vcpkg-configuration.json text=auto
# Patches
/tools/SDL-1.2.14-gc/SDL-1.2.14-gc.patch -whitespace
#Appveyor

View file

@ -12,8 +12,7 @@ variables:
stages:
- build
- osxcross
default:
interruptible: true
artifacts:
expire_in: 1 day

View file

@ -3,8 +3,8 @@ Alpine 3 GCC Dedicated:
artifacts:
paths:
- "build.alpine3ded/bin/"
- "build.alpine3ded/src/config.h"
- "build.cmake/bin/"
- "build.cmake/src/config.h"
expose_as: "Apline-3-Dedicated"
name: "$CI_PROJECT_PATH_SLUG-$CI_COMMIT_REF_SLUG-$CI_COMMIT_SHORT_SHA-Apline-3-Dedicated"
@ -12,7 +12,7 @@ Alpine 3 GCC Dedicated:
- - |
# apk_toolchain
echo -e "\e[0Ksection_start:`date +%s`:apk_toolchain[collapsed=true]\r\e[0KInstalling toolchain packages"
- apk add gcc
- apk add g++
- |
# apk_toolchain
echo -e "\e[0Ksection_end:`date +%s`:apk_toolchain\r\e[0K"
@ -20,7 +20,7 @@ Alpine 3 GCC Dedicated:
- - |
# apk_development
echo -e "\e[0Ksection_start:`date +%s`:apk_development[collapsed=true]\r\e[0KInstalling development packages"
- apk add musl-dev libpng-dev curl-dev
- apk add cmake musl-dev sdl2-dev libpng-dev curl-dev elfutils-dev
- |
# apk_development
echo -e "\e[0Ksection_end:`date +%s`:apk_development\r\e[0K"
@ -28,7 +28,15 @@ Alpine 3 GCC Dedicated:
- - |
# cmake
echo -e "\e[0Ksection_start:`date +%s`:cmake[collapsed=false]\r\e[0KBuilding Makefiles"
- cmake -B build.alpine3ded -DSRB2_CONFIG_ENABLE_WEBM_MOVIES=OFF -G "Unix Makefiles"
- |
cmake \
--preset ninja-debug \
-B build.cmake \
-G "Unix Makefiles" \
-DCMAKE_COLOR_DIAGNOSTICS=OFF \
-DSRB2_CONFIG_ENABLE_WEBM_MOVIES=OFF \
-DSRB2_CONFIG_EXECINFO=NO \
-DSRB2_CONFIG_DEDICATED=ON
- |
# cmake
echo -e "\e[0Ksection_end:`date +%s`:cmake\r\e[0K"
@ -36,7 +44,7 @@ Alpine 3 GCC Dedicated:
- - |
# make
echo -e "\e[0Ksection_start:`date +%s`:make[collapsed=false]\r\e[0KCompiling SRB2"
- make --directory=build.alpine3ded --keep-going || make --directory=build.alpine3ded --keep-going
- cmake --build build.cmake --parallel 1
- |
# make
echo -e "\e[0Ksection_end:`date +%s`:make\r\e[0K"

View file

@ -15,10 +15,11 @@ 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"
expire_in: 1 day
before_script:
- - |
@ -50,7 +51,7 @@ Alpine 3 GCC:
- - |
# apk_common
echo -e "\e[0Ksection_start:`date +%s`:apk_common[collapsed=true]\r\e[0KInstalling common packages"
- apk add make git ccache nasm
- apk add cmake make git ccache nasm
- |
# apk_common
echo -e "\e[0Ksection_end:`date +%s`:apk_common\r\e[0K"
@ -58,26 +59,24 @@ Alpine 3 GCC:
- - |
# ccache_config
echo -e "\e[0Ksection_start:`date +%s`:ccache_config[collapsed=true]\r\e[0KSetting up ccache config"
- mkdir --parents --verbose ~/.ccache/
- touch ~/.ccache/ccache.conf
- |
# cache.conf
echo Adding ccache configution option
- |
# base_dir
echo base_dir = $PWD | tee -a ~/.ccache/ccache.conf
ccache --set-config base_dir=$CI_PROJECT_DIR
- |
# cache_dir
echo cache_dir = $PWD/ccache | tee -a ~/.ccache/ccache.conf
ccache --set-config cache_dir=$CI_PROJECT_DIR/build/ccache
- |
# compiler_check
echo compiler_check = content | tee -a ~/.ccache/ccache.conf
ccache --set-config compiler_check=content
- |
# stats_log
echo stats_log = $PWD/ccache_statslog | tee -a ~/.ccache/ccache.conf
ccache --set-config stats_log=$CI_PROJECT_DIR/build/ccache_statslog
- |
# max_size
echo max_size = 50M | tee -a ~/.ccache/ccache.conf
ccache --set-config max_size=300M
- |
# ccache_config
echo -e "\e[0Ksection_end:`date +%s`:ccache_config\r\e[0K"
@ -95,7 +94,7 @@ Alpine 3 GCC:
- - |
# apk_toolchain
echo -e "\e[0Ksection_start:`date +%s`:apk_toolchain[collapsed=true]\r\e[0KInstalling toolchain packages"
- apk add gcc
- apk add g++
- |
# apk_toolchain
echo -e "\e[0Ksection_end:`date +%s`:apk_toolchain\r\e[0K"
@ -103,7 +102,7 @@ Alpine 3 GCC:
- - |
# apk_development
echo -e "\e[0Ksection_start:`date +%s`:apk_development[collapsed=true]\r\e[0KInstalling development packages"
- apk add cmake musl-dev sdl2_mixer-dev libpng-dev curl-dev libgme-dev libopenmpt-dev miniupnpc-dev
- apk add cmake musl-dev sdl2-dev libpng-dev curl-dev elfutils-dev
- |
# apk_development
echo -e "\e[0Ksection_end:`date +%s`:apk_development\r\e[0K"
@ -111,7 +110,14 @@ Alpine 3 GCC:
- - |
# cmake
echo -e "\e[0Ksection_start:`date +%s`:cmake[collapsed=false]\r\e[0KBuilding Makefiles"
- cmake -B build.alpine3 -DSRB2_CONFIG_ENABLE_WEBM_MOVIES=OFF -G "Unix Makefiles"
- |
cmake \
--preset ninja-debug \
-B build.cmake \
-G "Unix Makefiles" \
-DCMAKE_COLOR_DIAGNOSTICS=OFF \
-DSRB2_CONFIG_ENABLE_WEBM_MOVIES=OFF \
-DSRB2_CONFIG_EXECINFO=NO
- |
# cmake
echo -e "\e[0Ksection_end:`date +%s`:cmake\r\e[0K"
@ -119,7 +125,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 -- --keep-going
- |
# make
echo -e "\e[0Ksection_end:`date +%s`:make\r\e[0K"

View file

@ -1,6 +1,8 @@
batocera:arm64:
extends: Debian stable:arm64
stage: build
when: manual
allow_failure: true
@ -16,7 +18,7 @@ batocera:arm64:
- - |
# apt_toolchain
echo -e "\e[0Ksection_start:`date +%s`:apt_toolchain[collapsed=true]\r\e[0KInstalling toolchain packages"
- apt-get install gcc-aarch64-linux-gnu || apt-get install gcc
- apt-get install g++-aarch64-linux-gnu || apt-get install g++
- |
# apt_toolchain
echo -e "\e[0Ksection_end:`date +%s`:apt_toolchain\r\e[0K"
@ -24,7 +26,7 @@ batocera:arm64:
- - |
# apt_development
echo -e "\e[0Ksection_start:`date +%s`:apt_development[collapsed=true]\r\e[0KInstalling development packages"
- apt-get install libsdl2-mixer-dev:arm64 libpng-dev:arm64 libcurl4-openssl-dev:arm64 libopenmpt-dev:arm64 libminiupnpc-dev:arm64
- apt-get install libsdl2-dev:arm64 libpng-dev:arm64 libcurl4-openssl-dev:arm64 libyuv-dev:arm64
- |
# apt_development
echo -e "\e[0Ksection_end:`date +%s`:apt_development\r\e[0K"
@ -32,7 +34,14 @@ batocera:arm64:
- - |
# cmake
echo -e "\e[0Ksection_start:`date +%s`:cmake[collapsed=false]\r\e[0KBuilding Makefiles"
- cmake -B build.cmake -DSRB2_CONFIG_ENABLE_WEBM_MOVIES=OFF -G "Unix Makefiles"
- |
cmake \
--preset ninja-debug \
-B build.cmake \
-G "Unix Makefiles" \
-DCMAKE_COLOR_DIAGNOSTICS=OFF \
-DSRB2_CONFIG_ENABLE_WEBM_MOVIES=OFF \
-DSRB2_CONFIG_FORCE_NO_MS_BITFIELDS=ON
- |
# cmake
echo -e "\e[0Ksection_end:`date +%s`:cmake\r\e[0K"
@ -40,7 +49,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 -- --keep-going
- |
# make
echo -e "\e[0Ksection_end:`date +%s`:make\r\e[0K"

View file

@ -1,6 +1,8 @@
Debian oldstable:amd64:
extends: Debian stable:amd64
stage: build
when: manual
image: git.do.srb2.org:5050/stjr/srb2ci/srb2ci:oldstable
@ -18,7 +20,7 @@ Debian oldstable:amd64:
- - |
# apt_toolchain
echo -e "\e[0Ksection_start:`date +%s`:apt_toolchain[collapsed=true]\r\e[0KInstalling toolchain packages"
- apt-get install gcc-x86-64-linux-gnu || apt-get install gcc
- apt-get install g++-x86-64-linux-gnu || apt-get install g++
- |
# apt_toolchain
echo -e "\e[0Ksection_end:`date +%s`:apt_toolchain\r\e[0K"
@ -26,7 +28,7 @@ Debian oldstable:amd64:
- - |
# apt_development
echo -e "\e[0Ksection_start:`date +%s`:apt_development[collapsed=true]\r\e[0KInstalling development packages"
- apt-get install libsdl2-mixer-dev:amd64 libpng-dev:amd64 libcurl4-openssl-dev:amd64 libopenmpt-dev:amd64 libminiupnpc-dev:amd64
- apt-get install libsdl2-dev:amd64 libpng-dev:amd64 libcurl4-openssl-dev:amd64
- |
# apt_development
echo -e "\e[0Ksection_end:`date +%s`:apt_development\r\e[0K"
@ -34,7 +36,16 @@ Debian oldstable:amd64:
- - |
# cmake
echo -e "\e[0Ksection_start:`date +%s`:cmake[collapsed=false]\r\e[0KBuilding Makefiles"
- cmake -B build.cmake -DSRB2_CONFIG_ENABLE_WEBM_MOVIES=OFF -G "Unix Makefiles"
- |
cmake \
-B build.cmake \
-G "Unix Makefiles" \
-DCMAKE_COLOR_DIAGNOSTICS=OFF \
-DCMAKE_C_FLAGS_RELWITHDEBINFO="-O3 -g -DNDEBUG" \
-DCMAKE_CXX_FLAGS_RELWITHDEBINFO="-O3 -g -DNDEBUG"
-DSRB2_CONFIG_DEV_BUILD=ON \
-DCMAKE_BUILD_TYPE=RelWithDebInfo \
-DSRB2_CONFIG_ENABLE_WEBM_MOVIES=OFF
- |
# cmake
echo -e "\e[0Ksection_end:`date +%s`:cmake\r\e[0K"
@ -42,7 +53,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 -- --keep-going
- |
# make
echo -e "\e[0Ksection_end:`date +%s`:make\r\e[0K"

View file

@ -1,6 +1,8 @@
Debian oldstable:arm64:
extends: Debian stable:arm64
stage: build
when: manual
image: git.do.srb2.org:5050/stjr/srb2ci/srb2ci:oldstable
@ -18,7 +20,7 @@ Debian oldstable:arm64:
- - |
# apt_toolchain
echo -e "\e[0Ksection_start:`date +%s`:apt_toolchain[collapsed=true]\r\e[0KInstalling toolchain packages"
- apt-get install gcc-aarch64-linux-gnu || apt-get install gcc
- apt-get install g++-aarch64-linux-gnu || apt-get install g++
- |
# apt_toolchain
echo -e "\e[0Ksection_end:`date +%s`:apt_toolchain\r\e[0K"
@ -26,7 +28,7 @@ Debian oldstable:arm64:
- - |
# apt_development
echo -e "\e[0Ksection_start:`date +%s`:apt_development[collapsed=true]\r\e[0KInstalling development packages"
- apt-get install libsdl2-mixer-dev:arm64 libpng-dev:arm64 libcurl4-openssl-dev:arm64 libopenmpt-dev:arm64 libminiupnpc-dev:arm64
- apt-get install libsdl2-dev:arm64 libpng-dev:arm64 libcurl4-openssl-dev:arm64
- |
# apt_development
echo -e "\e[0Ksection_end:`date +%s`:apt_development\r\e[0K"
@ -34,7 +36,17 @@ Debian oldstable:arm64:
- - |
# cmake
echo -e "\e[0Ksection_start:`date +%s`:cmake[collapsed=false]\r\e[0KBuilding Makefiles"
- cmake -B build.cmake -DSRB2_CONFIG_ENABLE_WEBM_MOVIES=OFF -G "Unix Makefiles"
- |
cmake \
-B build.cmake \
-G "Unix Makefiles" \
-DCMAKE_COLOR_DIAGNOSTICS=OFF \
-DCMAKE_C_FLAGS_RELWITHDEBINFO="-O3 -g -DNDEBUG" \
-DCMAKE_CXX_FLAGS_RELWITHDEBINFO="-O3 -g -DNDEBUG"
-DSRB2_CONFIG_DEV_BUILD=ON \
-DCMAKE_BUILD_TYPE=RelWithDebInfo \
-DSRB2_CONFIG_ENABLE_WEBM_MOVIES=OFF \
-DSRB2_CONFIG_FORCE_NO_MS_BITFIELDS=ON
- |
# cmake
echo -e "\e[0Ksection_end:`date +%s`:cmake\r\e[0K"
@ -42,7 +54,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 -- --keep-going
- |
# make
echo -e "\e[0Ksection_end:`date +%s`:make\r\e[0K"

View file

@ -12,7 +12,7 @@ Debian stable:amd64:
variables:
CC: x86_64-linux-gnu-gcc
LDFLAGS: -Wl,-fuse-ld=gold
CXX: x86_64-linux-gnu-g++
OBJCOPY: x86_64-linux-gnu-objcopy
OBJDUMP: x86_64-linux-gnu-objdump
PKG_CONFIG_PATH: /usr/lib/x86_64-linux-gnu/pkgconfig
@ -23,7 +23,7 @@ Debian stable:amd64:
- - |
# apt_toolchain
echo -e "\e[0Ksection_start:`date +%s`:apt_toolchain[collapsed=true]\r\e[0KInstalling toolchain packages"
- apt-get install gcc-x86-64-linux-gnu || apt-get install gcc
- apt-get install g++-x86-64-linux-gnu || apt-get install g++
- |
# apt_toolchain
echo -e "\e[0Ksection_end:`date +%s`:apt_toolchain\r\e[0K"
@ -31,7 +31,7 @@ Debian stable:amd64:
- - |
# apt_development
echo -e "\e[0Ksection_start:`date +%s`:apt_development[collapsed=true]\r\e[0KInstalling development packages"
- apt-get install libsdl2-mixer-dev:amd64 libpng-dev:amd64 libcurl4-openssl-dev:amd64 libgme-dev:amd64 libopenmpt-dev:amd64 libminiupnpc-dev:amd64
- apt-get install libsdl2-dev:amd64 libpng-dev:amd64 libcurl4-openssl-dev:amd64 libyuv-dev:amd64
- |
# apt_development
echo -e "\e[0Ksection_end:`date +%s`:apt_development\r\e[0K"
@ -40,11 +40,11 @@ Debian stable:amd64:
# cmake
echo -e "\e[0Ksection_start:`date +%s`:cmake[collapsed=false]\r\e[0KBuilding Makefiles"
- |
CCACHE=$(which ccache)
cmake -B build.cmake \
cmake \
--preset ninja-debug \
-B build.cmake \
-G "Unix Makefiles" \
-DCMAKE_C_COMPILER_LAUNCHER=$CCACHE \
-DCMAKE_CXX_COMPILER_LAUNCHER=$CCACHE \
-DCMAKE_COLOR_DIAGNOSTICS=OFF \
-DSRB2_CONFIG_ENABLE_WEBM_MOVIES=OFF
- |
# cmake
@ -53,7 +53,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 -- --keep-going
- |
# make
echo -e "\e[0Ksection_end:`date +%s`:make\r\e[0K"

View file

@ -14,16 +14,17 @@ Debian stable:arm64:
variables:
CC: aarch64-linux-gnu-gcc
LDFLAGS: -Wl,-fuse-ld=gold
CXX: aarch64-linux-gnu-g++
OBJCOPY: aarch64-linux-gnu-objcopy
OBJDUMP: aarch64-linux-gnu-objdump
LD: aarch64-linux-gnu-ld
PKG_CONFIG_PATH: /usr/lib/aarch64-linux-gnu/pkgconfig
script:
- - |
# apt_toolchain
echo -e "\e[0Ksection_start:`date +%s`:apt_toolchain[collapsed=true]\r\e[0KInstalling toolchain packages"
- apt-get install gcc-aarch64-linux-gnu || apt-get install gcc
- apt-get install g++-aarch64-linux-gnu || apt-get install g++
- |
# apt_toolchain
echo -e "\e[0Ksection_end:`date +%s`:apt_toolchain\r\e[0K"
@ -31,7 +32,7 @@ Debian stable:arm64:
- - |
# apt_development
echo -e "\e[0Ksection_start:`date +%s`:apt_development[collapsed=true]\r\e[0KInstalling development packages"
- apt-get install libsdl2-mixer-dev:arm64 libpng-dev:arm64 libcurl4-openssl-dev:arm64 libgme-dev:arm64 libopenmpt-dev:arm64 libminiupnpc-dev:arm64
- apt-get install libsdl2-dev:arm64 libpng-dev:arm64 libcurl4-openssl-dev:arm64 libyuv-dev:arm64
- |
# apt_development
echo -e "\e[0Ksection_end:`date +%s`:apt_development\r\e[0K"
@ -39,7 +40,14 @@ Debian stable:arm64:
- - |
# cmake
echo -e "\e[0Ksection_start:`date +%s`:cmake[collapsed=false]\r\e[0KBuilding Makefiles"
- cmake -B build.cmake -DSRB2_CONFIG_ENABLE_WEBM_MOVIES=OFF -G "Unix Makefiles"
- |
cmake \
--preset ninja-debug \
-B build.cmake \
-G "Unix Makefiles" \
-DCMAKE_COLOR_DIAGNOSTICS=OFF \
-DSRB2_CONFIG_ENABLE_WEBM_MOVIES=OFF \
-DSRB2_CONFIG_FORCE_NO_MS_BITFIELDS=ON
- |
# cmake
echo -e "\e[0Ksection_end:`date +%s`:cmake\r\e[0K"
@ -47,7 +55,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 -- --keep-going
- |
# make
echo -e "\e[0Ksection_end:`date +%s`:make\r\e[0K"

View file

@ -3,23 +3,20 @@ Debian stable Clang:
stage: build
when: manual
when: on_success
allow_failure: true
allow_failure: false
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"
variables:
CC: clang
CXX: clang
WFLAGS: -Wno-cast-align -Wno-implicit-const-int-float-conversion -Werror
CFLAGS: -Wno-cast-align -Wno-implicit-const-int-float-conversion -Werror
LDFLAGS: -Wl,-fuse-ld=gold
CXX: clang++
script:
- - |
@ -33,7 +30,7 @@ Debian stable Clang:
- - |
# apt_development
echo -e "\e[0Ksection_start:`date +%s`:apt_development[collapsed=true]\r\e[0KInstalling development packages"
- apt-get install libsdl2-mixer-dev libpng-dev libcurl4-openssl-dev libgme-dev libopenmpt-dev libminiupnpc-dev
- apt-get install libsdl2-dev libpng-dev libcurl4-openssl-dev libyuv-dev
- |
# apt_development
echo -e "\e[0Ksection_end:`date +%s`:apt_development\r\e[0K"
@ -41,7 +38,16 @@ Debian stable Clang:
- - |
# cmake
echo -e "\e[0Ksection_start:`date +%s`:cmake[collapsed=false]\r\e[0KBuilding Makefiles"
- cmake -B build.clang -DSRB2_CONFIG_ENABLE_WEBM_MOVIES=OFF -G "Unix Makefiles"
- |
cmake \
--preset ninja-debug \
-B build.cmake \
-G "Unix Makefiles" \
-DCMAKE_COLOR_DIAGNOSTICS=OFF \
-DSRB2_CONFIG_ENABLE_WEBM_MOVIES=OFF \
-DCPM_USE_LOCAL_PACKAGES:BOOL=ON \
-DSRB2_CONFIG_ENABLE_TESTS:BOOL=OFF \
-DSRB2_CONFIG_SYSTEM_LIBRARIES:BOOL=ON
- |
# cmake
echo -e "\e[0Ksection_end:`date +%s`:cmake\r\e[0K"
@ -49,7 +55,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 -- --keep-going
- |
# make
echo -e "\e[0Ksection_end:`date +%s`:make\r\e[0K"

View file

@ -14,15 +14,17 @@ Debian stable:i386:
variables:
CC: i686-linux-gnu-gcc
CXX: i686-linux-gnu-g++
OBJCOPY: i686-linux-gnu-objcopy
OBJDUMP: i686-linux-gnu-objdump
LD: i686-linux-gnu-ld
PKG_CONFIG_PATH: /usr/lib/i386-linux-gnu/pkgconfig
script:
- - |
# apt_toolchain
echo -e "\e[0Ksection_start:`date +%s`:apt_toolchain[collapsed=true]\r\e[0KInstalling toolchain packages"
- apt-get install gcc-i686-linux-gnu || apt-get install gcc
- apt-get install g++-i686-linux-gnu || apt-get install g++
- |
# apt_toolchain
echo -e "\e[0Ksection_end:`date +%s`:apt_toolchain\r\e[0K"
@ -30,7 +32,7 @@ Debian stable:i386:
- - |
# apt_development
echo -e "\e[0Ksection_start:`date +%s`:apt_development[collapsed=true]\r\e[0KInstalling development packages"
- apt-get install libsdl2-mixer-dev:i386 libpng-dev:i386 libcurl4-openssl-dev:i386 libgme-dev:i386 libopenmpt-dev:i386 libminiupnpc-dev:i386
- apt-get install libsdl2-dev:i386 libpng-dev:i386 libcurl4-openssl-dev:i386 libyuv-dev:i386
- |
# apt_development
echo -e "\e[0Ksection_end:`date +%s`:apt_development\r\e[0K"
@ -38,7 +40,13 @@ Debian stable:i386:
- - |
# cmake
echo -e "\e[0Ksection_start:`date +%s`:cmake[collapsed=false]\r\e[0KBuilding Makefiles"
- cmake -B build.cmake -DSRB2_CONFIG_ENABLE_WEBM_MOVIES=OFF -G "Unix Makefiles"
- |
cmake \
--preset ninja-debug \
-B build.cmake \
-G "Unix Makefiles" \
-DCMAKE_COLOR_DIAGNOSTICS=OFF \
-DSRB2_CONFIG_ENABLE_WEBM_MOVIES=OFF
- |
# cmake
echo -e "\e[0Ksection_end:`date +%s`:cmake\r\e[0K"
@ -46,7 +54,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 -- --keep-going
- |
# make
echo -e "\e[0Ksection_end:`date +%s`:make\r\e[0K"

View file

@ -9,14 +9,7 @@ Debian testing Clang:
artifacts:
paths:
- "build.clang/bin/"
- "build.clang/src/config.h"
- "build.cmake/bin/"
- "build.cmake/src/config.h"
expose_as: "testing-clang"
name: "$CI_PROJECT_PATH_SLUG-$CI_COMMIT_REF_SLUG-$CI_COMMIT_SHORT_SHA-testing-clang"
variables:
CC: 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

View file

@ -18,13 +18,13 @@ Debian testing GCC:
variables:
CC: gcc
LDFLAGS: -Wl,-fuse-ld=gold
CXX: g++
script:
- - |
# apt_toolchain
echo -e "\e[0Ksection_start:`date +%s`:apt_toolchain[collapsed=true]\r\e[0KInstalling toolchain packages"
- apt-get install gcc
- apt-get install g++
- |
# apt_toolchain
echo -e "\e[0Ksection_end:`date +%s`:apt_toolchain\r\e[0K"
@ -32,7 +32,7 @@ Debian testing GCC:
- - |
# apt_development
echo -e "\e[0Ksection_start:`date +%s`:apt_development[collapsed=true]\r\e[0KInstalling development packages"
- apt-get install libsdl2-mixer-dev libpng-dev libcurl4-openssl-dev libgme-dev libopenmpt-dev libminiupnpc-dev
- apt-get install libsdl2-dev libpng-dev libcurl4-openssl-dev libyuv-dev
- |
# apt_development
echo -e "\e[0Ksection_end:`date +%s`:apt_development\r\e[0K"
@ -40,7 +40,13 @@ Debian testing GCC:
- - |
# cmake
echo -e "\e[0Ksection_start:`date +%s`:cmake[collapsed=false]\r\e[0KBuilding Makefiles"
- cmake -B build.cmake -DSRB2_CONFIG_ENABLE_WEBM_MOVIES=OFF -G "Unix Makefiles"
- |
cmake \
--preset ninja-debug \
-B build.cmake \
-G "Unix Makefiles" \
-DCMAKE_COLOR_DIAGNOSTICS=OFF \
-DSRB2_CONFIG_ENABLE_WEBM_MOVIES=OFF
- |
# cmake
echo -e "\e[0Ksection_end:`date +%s`:cmake\r\e[0K"
@ -48,7 +54,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 -- --keep-going
- |
# make
echo -e "\e[0Ksection_end:`date +%s`:make\r\e[0K"

View file

@ -3,26 +3,57 @@ osxcross arm64:
stage: build
when: manual
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
allow_failure: true
- key: apt-$CI_JOB_IMAGE
paths:
- build/apt-cache
unprotect: true
- key: vcpkg-binary-cache-arm64-osx
paths:
- build/vcpkg-binary-cache
unprotect: true
artifacts:
paths:
- "build.osxcross/bin/"
- "build.osxcross/src/config.h"
expose_as: "Mac arm64"
name: "$CI_PROJECT_PATH_SLUG-$CI_COMMIT_REF_SLUG-$CI_COMMIT_SHORT_SHA-clang"
- "build.arm64/bin/"
- "build.arm64/dist/arm64.h"
- "build.arm64/src/config.h"
name: "$CI_PROJECT_PATH_SLUG-$CI_COMMIT_REF_SLUG-$CI_COMMIT_SHORT_SHA-arm64-apple-darwin"
variables:
OSXCROSS_HOST: arm64-apple-darwin21.4
LD: arm64-apple-darwin21.4-ld
CMAKE_TOOLCHAIN_FILE: /osxcross/toolchain.cmake
CCACHE_CPP2: yes
script:
- - |
# osxcross Config
echo -e "\e[0Ksection_start:`date +%s`:osxcross_Config[collapsed=true]\r\e[0Kosxcross Config"
- export VCPKG_CHAINLOAD_TOOLCHAIN_FILE=${OSXCROSS_TARGET_DIR}/toolchain.cmake
- export PATH="/opt/osxcross.arm64:${PATH}"
- $(osxcross-conf)
- export OSXCROSS_HOST=arm64-apple-${OSXCROSS_TARGET}
- export VCPKG_DEFAULT_TRIPLET=arm64-osx
- export CC=${OSXCROSS_TARGET_DIR}/bin/${OSXCROSS_HOST}-clang
- export CXX=${OSXCROSS_TARGET_DIR}/bin/${OSXCROSS_HOST}-clang++
- export SDKROOT=${OSXCROSS_SDK}
- |
# osxcross Config
echo -e "\e[0Ksection_end:`date +%s`:osxcross_Config\r\e[0K"
- - |
# 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 --static --arm64 curl || osxcross-macports install --verbose --static --arm64 curl || true
- osxcross-macports install --static --arm64 libpng libopus || osxcross-macports install --verbose --static --arm64 libpng libopus
- |
# apt_development
echo -e "\e[0Ksection_end:`date +%s`:macports_development\r\e[0K"
@ -30,7 +61,22 @@ 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_WEBM_MOVIES=OFF -G "Unix Makefiles"
- |
cmake \
--preset ninja-debug \
-B build.arm64 \
-G "Unix Makefiles" \
-DCMAKE_COLOR_DIAGNOSTICS=OFF \
-DSRB2_CONFIG_ENABLE_WEBM_MOVIES=OFF \
-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_SDL2_EXE_NAME=ringracers_$CI_PIPELINE_ID \
-DSRB2_CONFIG_FORCE_NO_MS_BITFIELDS:BOOL=ON \
-DCMAKE_C_COMPILER_LAUNCHER=ccache \
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache
- |
# make
echo -e "\e[0Ksection_end:`date +%s`:make\r\e[0K"
@ -38,7 +84,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 -- --keep-going
- |
# 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 build.arm64/src/config.h build.arm64/dist/arm64.h
- |
# make
echo -e "\e[0Ksection_end:`date +%s`:copy\r\e[0K"

View file

@ -17,11 +17,6 @@ osxcross x86_64:
- build/apt-cache
unprotect: true
- key: vcpkg-root
paths:
- build/vcpkg-root
unprotect: true
- key: vcpkg-binary-cache-x64-osx
paths:
- build/vcpkg-binary-cache
@ -29,41 +24,36 @@ osxcross x86_64:
artifacts:
paths:
- "build.osxcross/bin/"
- "build.osxcross/src/config.h"
expose_as: "Mac x86_64"
name: "$CI_PROJECT_PATH_SLUG-$CI_COMMIT_REF_SLUG-$CI_COMMIT_SHORT_SHA-clang"
- "build.x86_64/bin/"
- "build.x86_64/dist/x86_64.h"
- "build.x86_64/src/config.h"
name: "$CI_PROJECT_PATH_SLUG-$CI_COMMIT_REF_SLUG-$CI_COMMIT_SHORT_SHA-x86_64-apple-darwin"
variables:
OSXCROSS_HOST: x86_64-apple-darwin21.4
LD: x86_64-apple-darwin21.4-ld
CMAKE_TOOLCHAIN_FILE: /osxcross/toolchain.cmake
CCACHE_CPP2: yes
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,$(pwd)/build/vcpkg-binary-cache,readwrite"
mkdir -p "build/vcpkg-binary-cache"
echo -e "\e[0Ksection_end:`date +%s`:vcpkg-root\r\e[0K"
- - |
# osxcross Config
echo -e "\e[0Ksection_start:`date +%s`:osxcross_Config[collapsed=true]\r\e[0Kosxcross Config"
- export VCPKG_CHAINLOAD_TOOLCHAIN_FILE=${OSXCROSS_TARGET_DIR}/toolchain.cmake
- export PATH="/opt/osxcross.x86_64:${PATH}"
- $(osxcross-conf)
- export OSXCROSS_HOST=x86_64-apple-${OSXCROSS_TARGET}
- export VCPKG_DEFAULT_TRIPLET=x64-osx
- export CC=${OSXCROSS_TARGET_DIR}/bin/${OSXCROSS_HOST}-clang
- export CXX=${OSXCROSS_TARGET_DIR}/bin/${OSXCROSS_HOST}-clang++
- export SDKROOT=${OSXCROSS_SDK}
- |
# osxcross Config
echo -e "\e[0Ksection_end:`date +%s`:osxcross_Config\r\e[0K"
- - |
# 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 --static curl || osxcross-macports install --verbose --static curl || true
- osxcross-macports install --static libpng libopus || osxcross-macports install --verbose --static libpng libopus
- |
# apt_development
echo -e "\e[0Ksection_end:`date +%s`:macports_development\r\e[0K"
@ -71,7 +61,21 @@ 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_WEBM_MOVIES=OFF -G "Unix Makefiles"
- |
cmake \
--preset ninja-debug \
-B build.x86_64 \
-G "Unix Makefiles" \
-DCMAKE_COLOR_DIAGNOSTICS=OFF \
-DSRB2_CONFIG_ENABLE_WEBM_MOVIES=OFF \
-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_SDL2_EXE_NAME=ringracers_$CI_PIPELINE_ID \
-DCMAKE_C_COMPILER_LAUNCHER=ccache \
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache
- |
# make
echo -e "\e[0Ksection_end:`date +%s`:make\r\e[0K"
@ -79,37 +83,16 @@ 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 -- --keep-going
- |
# 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
# 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
- |
# 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
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"
# make
echo -e "\e[0Ksection_end:`date +%s`:copy\r\e[0K"

View file

@ -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/ringracers_$CI_PIPELINE_ID.app/Contents/MacOS/ringracers_$CI_PIPELINE_ID build.*/bin/ringracers_$CI_PIPELINE_ID.app/Contents/MacOS/ringracers_$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/ringracers_$CI_PIPELINE_ID.app/Contents/MacOS/ringracers_$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/ringracers_$CI_PIPELINE_ID.app/Contents/MacOS/ringracers_$CI_PIPELINE_ID -verify_arch x86_64
- |
# x86_64-verify
echo -e "\e[0Ksection_end:`date +%s`:x86_64-verify\r\e[0K"

View file

@ -5,8 +5,29 @@ Windows x64:
when: manual
timeout: 2h
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-binary-cache-x64-mingw-static
paths:
- build/vcpkg-binary-cache
unprotect: true
artifacts:
paths:
- "build.cmake/bin/"
@ -15,13 +36,26 @@ Windows x64:
name: "$CI_PROJECT_PATH_SLUG-$CI_COMMIT_REF_SLUG-$CI_COMMIT_SHORT_SHA-Win64"
variables:
PREFIX: x86_64-w64-mingw32
VCPKG_TARGET_TRIPLET: x64-mingw-static
CC: x86_64-w64-mingw32-gcc
CXX: x86_64-w64-mingw32-g++
LD: x86_64-w64-mingw32-ld
script:
- |
# vcpkg
echo -e "\e[0Ksection_start:`date +%s`:vcpkg-root[collapsed=true]\r\e[0KSetting vcpkg cache"
export VCPKG_DEFAULT_BINARY_CACHE="$(pwd)/build/vcpkg-binary-cache"
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"
- apt-get install gcc-mingw-w64-x86-64-win32
- apt-get install g++-mingw-w64-x86-64-win32
- |
# apt_toolchain
echo -e "\e[0Ksection_end:`date +%s`:apt_toolchain\r\e[0K"
@ -37,7 +71,18 @@ Windows x64:
- - |
# cmake
echo -e "\e[0Ksection_start:`date +%s`:cmake[collapsed=false]\r\e[0KBuilding Makefiles"
- cmake -B build.cmake -DSRB2_CONFIG_ENABLE_WEBM_MOVIES=OFF -DSRB2_CONFIG_ENABLE_DISCORDRPC=OFF -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 \
--preset ninja-debug \
-B build.cmake \
-G "Unix Makefiles" \
-DCMAKE_COLOR_DIAGNOSTICS=OFF \
-DVCPKG_CHAINLOAD_TOOLCHAIN_FILE=$VCPKG_ROOT/scripts/toolchains/mingw.cmake \
-DSRB2_CONFIG_ENABLE_WEBM_MOVIES=OFF \
-DSRB2_CONFIG_ENABLE_DISCORDRPC=OFF \
-DCMAKE_TOOLCHAIN_FILE=${VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake \
-DVCPKG_TARGET_TRIPLET=${VCPKG_TARGET_TRIPLET} \
-DSRB2_CONFIG_ALWAYS_MAKE_DEBUGLINK=ON
- |
# cmake
echo -e "\e[0Ksection_end:`date +%s`:cmake\r\e[0K"
@ -45,7 +90,7 @@ Windows x64:
- - |
# 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 -- --keep-going
- |
# make
echo -e "\e[0Ksection_end:`date +%s`:make\r\e[0K"

View file

@ -5,6 +5,8 @@ Windows x86:
when: on_success
timeout: 2h
cache:
- key: ccache-$CI_JOB_NAME_SLUG-$CI_COMMIT_REF_SLUG
fallback_keys:
@ -19,11 +21,6 @@ Windows x86:
- build/apt-cache
unprotect: true
- key: vcpkg-root
paths:
- build/vcpkg-root
unprotect: true
- key: vcpkg-binary-cache-x86-mingw-static
paths:
- build/vcpkg-binary-cache
@ -31,33 +28,23 @@ 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
VCPKG_TARGET_TRIPLET: x86-mingw-static
CC: i686-w64-mingw32-gcc
CXX: i686-w64-mingw32-g++
LD: i686-w64-mingw32-ld
script:
- |
# vcpkg
echo -e "\e[0Ksection_start:`date +%s`:vcpkg-root[collapsed=true]\r\e[0KUpdating vcpkg"
echo -e "\e[0Ksection_start:`date +%s`:vcpkg-root[collapsed=true]\r\e[0KSetting vcpkg cache"
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,$(pwd)/build/vcpkg-binary-cache,readwrite"
export VCPKG_DEFAULT_BINARY_CACHE="$(pwd)/build/vcpkg-binary-cache"
mkdir -p "build/vcpkg-binary-cache"
@ -66,7 +53,7 @@ Windows x86:
- - |
# apt_toolchain
echo -e "\e[0Ksection_start:`date +%s`:apt_toolchain[collapsed=true]\r\e[0KInstalling toolchain packages"
- apt-get install gcc-mingw-w64-i686-win32
- apt-get install g++-mingw-w64-i686-win32
- |
# apt_toolchain
echo -e "\e[0Ksection_end:`date +%s`:apt_toolchain\r\e[0K"
@ -83,18 +70,17 @@ Windows x86:
# cmake
echo -e "\e[0Ksection_start:`date +%s`:cmake[collapsed=false]\r\e[0KBuilding Makefiles"
- |
CCACHE=$(which ccache)
cmake \
--preset ninja-x86_mingw_static_vcpkg-debug \
--preset ninja-debug \
-B build.cmake \
-G "Unix Makefiles" \
-DCMAKE_C_COMPILER_LAUNCHER=$CCACHE \
-DCMAKE_CXX_COMPILER_LAUNCHER=$CCACHE \
-DCMAKE_C_COMPILER=/usr/bin/i686-w64-mingw32-gcc-posix \
-DCMAKE_CXX_COMPILER=/usr/bin/i686-w64-mingw32-g++-posix \
-DCMAKE_COLOR_DIAGNOSTICS=OFF \
-DVCPKG_CHAINLOAD_TOOLCHAIN_FILE=$VCPKG_ROOT/scripts/toolchains/mingw.cmake \
-DSRB2_CONFIG_ENABLE_WEBM_MOVIES=OFF \
-DSRB2_CONFIG_ENABLE_DISCORDRPC=OFF \
-DCMAKE_TOOLCHAIN_FILE=${VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake \
-DVCPKG_TARGET_TRIPLET=${VCPKG_TARGET_TRIPLET} \
-DSRB2_CONFIG_ALWAYS_MAKE_DEBUGLINK=ON
- |
# cmake
echo -e "\e[0Ksection_end:`date +%s`:cmake\r\e[0K"
@ -102,37 +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 -- --keep-going
- |
# 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"

View file

@ -15,6 +15,9 @@
- build/apt-cache
unprotect: true
artifacts:
expire_in: 1 day
before_script:
- - |
# debconf
@ -61,7 +64,7 @@
- - |
# apt_update
echo -e "\e[0Ksection_start:`date +%s`:apt_update[collapsed=true]\r\e[0KUpdating APT listing"
- apt-get update
- timeout 2m apt-get update || timeout 2m apt-get update
- |
# apt_update
echo -e "\e[0Ksection_end:`date +%s`:apt_update\r\e[0K"
@ -93,26 +96,24 @@
- - |
# ccache_config
echo -e "\e[0Ksection_start:`date +%s`:ccache_config[collapsed=true]\r\e[0KSetting up ccache config"
- mkdir --parents --verbose ~/.ccache/
- touch ~/.ccache/ccache.conf
- |
# cache.conf
echo Adding ccache configution option
- |
# base_dir
echo base_dir = $CI_PROJECT_DIR | tee --append ~/.ccache/ccache.conf
ccache --set-config base_dir=$CI_PROJECT_DIR
- |
# cache_dir
echo cache_dir = $CI_PROJECT_DIR/build/ccache | tee --append ~/.ccache/ccache.conf
ccache --set-config cache_dir=$CI_PROJECT_DIR/build/ccache
- |
# compiler_check
echo compiler_check = content | tee --append ~/.ccache/ccache.conf
ccache --set-config compiler_check=content
- |
# stats_log
echo stats_log = $CI_PROJECT_DIR/build/ccache_statslog | tee --append ~/.ccache/ccache.conf
ccache --set-config stats_log=$CI_PROJECT_DIR/build/ccache_statslog || true
- |
# max_size
echo max_size = 300M | tee --append ~/.ccache/ccache.conf
ccache --set-config max_size=300M
- |
# ccache_config
echo -e "\e[0Ksection_end:`date +%s`:ccache_config\r\e[0K"

View file

@ -53,7 +53,19 @@ SET(CPACK_OUTPUT_FILE_PREFIX package)
include(CPack)
# Options
if("${CMAKE_SYSTEM_NAME}" MATCHES Windows)
if(DEFINED VCPKG_TARGET_TRIPLET)
set(SRB2_CONFIG_SYSTEM_LIBRARIES_DEFAULT ON)
else()
set(SRB2_CONFIG_SYSTEM_LIBRARIES_DEFAULT OFF)
endif()
else()
set(SRB2_CONFIG_SYSTEM_LIBRARIES_DEFAULT ON)
endif()
# Clang tidy options will be ignored if CMAKE_<LANG>_CLANG_TIDY are set.
option(SRB2_CONFIG_ENABLE_CLANG_TIDY_C "Enable default clang-tidy check configuration for C" OFF)
option(SRB2_CONFIG_ENABLE_CLANG_TIDY_CXX "Enable default clang-tidy check configuration for C++" OFF)
option(
SRB2_CONFIG_STATIC_STDLIB
"Link static version of standard library. All dependencies must also be static"
@ -70,8 +82,10 @@ option(SRB2_CONFIG_ALWAYS_MAKE_DEBUGLINK "Always make a debuglink .debug." OFF)
option(SRB2_CONFIG_TESTERS "Compile a build for testers." OFF)
option(SRB2_CONFIG_MOBJCONSISTANCY "Compile with MOBJCONSISTANCY defined." OFF)
option(SRB2_CONFIG_PACKETDROP "Compile with PACKETDROP defined." OFF)
option(SRB2_CONFIG_EXECINFO "Enable stack trace dump support." ON)
option(SRB2_CONFIG_ZDEBUG "Compile with ZDEBUG defined." OFF)
option(SRB2_CONFIG_SKIP_COMPTIME "Skip regenerating comptime. To speed up iterative debug builds in IDEs." OFF)
option(SRB2_CONFIG_FORCE_NO_MS_BITFIELDS "Compile without -mno-ms-bitfields compiler flag" OFF)
# SRB2_CONFIG_PROFILEMODE is probably superceded by some CMake setting.
option(SRB2_CONFIG_PROFILEMODE "Compile for profiling (GCC only)." OFF)
option(SRB2_CONFIG_TRACY "Compile with Tracy profiling enabled" OFF)
@ -94,12 +108,23 @@ if("${CMAKE_HOST_SYSTEM_NAME}" STREQUAL Windows)
endif()
endif()
# Dependencies
add_subdirectory(thirdparty)
if(SRB2_CONFIG_SHARED_INTERNAL_LIBRARIES)
set(SRB2_INTERNAL_LIBRARY_TYPE SHARED)
set(NOT_SRB2_CONFIG_SHARED_INTERNAL_LIBRARIES OFF)
else()
set(SRB2_INTERNAL_LIBRARY_TYPE STATIC)
set(NOT_SRB2_CONFIG_SHARED_INTERNAL_LIBRARIES ON)
endif()
find_package(ZLIB REQUIRED)
find_package(PNG REQUIRED)
find_package(SDL2 CONFIG REQUIRED)
find_package(CURL REQUIRED)
find_package(Opus REQUIRED)
# Use the one in thirdparty/fmt to guarantee a minimum version
#find_package(FMT CONFIG REQUIRED)

View file

@ -101,88 +101,113 @@
"name": "ninja-debug",
"hidden": false,
"binaryDir": "build/${presetName}",
"inherits": ["__debug", "__ninja"]
"inherits": [ "__debug", "__ninja" ]
},
{
"name": "ninja-develop",
"hidden": false,
"binaryDir": "build/${presetName}",
"inherits": ["__develop", "__ninja"]
"inherits": [ "__develop", "__ninja" ]
},
{
"name": "ninja-release",
"hidden": false,
"binaryDir": "build/${presetName}",
"inherits": ["__release", "__ninja"]
"inherits": [ "__release", "__ninja" ]
},
{
"name": "ninja-testers",
"hidden": false,
"binaryDir": "build/${presetName}",
"inherits": ["__testers", "__ninja"]
"inherits": [ "__testers", "__ninja" ]
},
{
"name": "ninja-vcpkg-debug",
"hidden": false,
"binaryDir": "build/${presetName}",
"inherits": [ "__debug", "__ninja", "__vcpkg-toolchain" ]
},
{
"name": "ninja-vcpkg-develop",
"hidden": false,
"binaryDir": "build/${presetName}",
"inherits": [ "__develop", "__ninja", "__vcpkg-toolchain" ]
},
{
"name": "ninja-vcpkg-release",
"hidden": false,
"binaryDir": "build/${presetName}",
"inherits": [ "__release", "__ninja", "__vcpkg-toolchain" ]
},
{
"name": "ninja-vcpkg-testers",
"hidden": false,
"binaryDir": "build/${presetName}",
"inherits": [ "__testers", "__ninja", "__vcpkg-toolchain" ]
},
{
"name": "ninja-x86_mingw_static_vcpkg-debug",
"hidden": false,
"binaryDir": "build/${presetName}",
"inherits": ["__debug", "__compiler-mingw-w64-i686", "__ninja", "__vcpkg-toolchain", "__mingw-static"]
"inherits": [ "__debug", "__compiler-mingw-w64-i686", "__ninja", "__vcpkg-toolchain", "__mingw-static" ]
},
{
"name": "ninja-x86_mingw_static_vcpkg-develop",
"hidden": false,
"binaryDir": "build/${presetName}",
"inherits": ["__develop", "__compiler-mingw-w64-i686", "__ninja", "__vcpkg-toolchain", "__mingw-static"]
"inherits": [ "__develop", "__compiler-mingw-w64-i686", "__ninja", "__vcpkg-toolchain", "__mingw-static" ]
},
{
"name": "ninja-x86_mingw_static_vcpkg-release",
"hidden": false,
"binaryDir": "build/${presetName}",
"inherits": ["__release", "__compiler-mingw-w64-i686", "__ninja", "__vcpkg-toolchain", "__mingw-static"]
"inherits": [ "__release", "__compiler-mingw-w64-i686", "__ninja", "__vcpkg-toolchain", "__mingw-static" ]
},
{
"name": "ninja-x86_mingw_static_vcpkg-testers",
"hidden": false,
"binaryDir": "build/${presetName}",
"inherits": ["__testers", "__compiler-mingw-w64-i686", "__ninja", "__vcpkg-toolchain", "__mingw-static"]
"inherits": [ "__testers", "__compiler-mingw-w64-i686", "__ninja", "__vcpkg-toolchain", "__mingw-static" ]
},
{
"name": "ninja-x64_osx_vcpkg-debug",
"hidden": false,
"binaryDir": "build/${presetName}",
"inherits": ["__debug", "__ninja", "__vcpkg-toolchain", "__osx_x64"]
"inherits": [ "__debug", "__ninja", "__vcpkg-toolchain", "__osx_x64" ]
},
{
"name": "ninja-x64_osx_vcpkg-develop",
"hidden": false,
"binaryDir": "build/${presetName}",
"inherits": ["__develop", "__ninja", "__vcpkg-toolchain", "__osx_x64"]
"inherits": [ "__develop", "__ninja", "__vcpkg-toolchain", "__osx_x64" ]
},
{
"name": "ninja-x64_osx_vcpkg-release",
"hidden": false,
"binaryDir": "build/${presetName}",
"inherits": ["__release", "__ninja", "__vcpkg-toolchain", "__osx_x64"]
"inherits": [ "__release", "__ninja", "__vcpkg-toolchain", "__osx_x64" ]
},
{
"name": "ninja-arm64_osx_vcpkg-debug",
"hidden": false,
"binaryDir": "build/${presetName}",
"inherits": ["__debug", "__ninja", "__vcpkg-toolchain", "__osx_arm64"]
"inherits": [ "__debug", "__ninja", "__vcpkg-toolchain", "__osx_arm64" ]
},
{
"name": "ninja-arm64_osx_vcpkg-develop",
"hidden": false,
"binaryDir": "build/${presetName}",
"inherits": ["__develop", "__ninja", "__vcpkg-toolchain", "__osx_arm64"]
"inherits": [ "__develop", "__ninja", "__vcpkg-toolchain", "__osx_arm64" ]
},
{
"name": "ninja-arm64_osx_vcpkg-release",
"hidden": false,
"binaryDir": "build/${presetName}",
"inherits": ["__release", "__ninja", "__vcpkg-toolchain", "__osx_arm64"]
"inherits": [ "__release", "__ninja", "__vcpkg-toolchain", "__osx_arm64" ]
}
],

View file

@ -1616,7 +1616,7 @@ met:
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
@ -1641,6 +1641,16 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- stb_vorbis + stb_rect_pack
Copyright (c) 2017 Sean Barrett
https://github.com/nothings/stb
- Vulkan Headers
Copyright (c) 2015-2023 The Khronos Group Inc.
https://github.com/KhronosGroup/Vulkan-Headers
- volk
Copyright (c) 2018-2025 Arseny Kapoulkine
https://github.com/zeux/volk
- VulkanMemoryAllocator
Copyright (c) 2017-2025 Advanced Micro Devices, Inc.
https://github.com/GPUOpen-LibrariesAndSDKs/VulkanMemoryAllocator
--------------------------------------------------------------------------------
Permission is hereby granted, free of charge, to any person obtaining a copy

View file

@ -39,7 +39,6 @@ set(SRB2_ASSETS_GAME
"scripts.pk3"
"staffghosts.pk3"
"unlocks.pk3"
"shaders.pk3"
)
list(TRANSFORM SRB2_ASSETS_GAME PREPEND "/")
list(TRANSFORM SRB2_ASSETS_GAME PREPEND "${SRB2_ASSET_DIRECTORY_ABSOLUTE}")

View file

@ -0,0 +1,7 @@
find_package(Opus CONFIG)
if(NOT TARGET Opus::opus)
find_package(PkgConfig REQUIRED)
pkg_check_modules(Opus REQUIRED IMPORTED_TARGET opus)
set_target_properties(PkgConfig::Opus PROPERTIES IMPORTED_GLOBAL TRUE)
add_library(Opus::opus ALIAS PkgConfig::Opus)
endif()

273
docs/udmf.txt Normal file
View file

@ -0,0 +1,273 @@
===============================================================================
Universal Doom Map Format - Ring Racers extensions v1.0 - 20.09.2024
Copyright (C) 2025 Sally Cochenour.
Copyright (C) 2025 Kart Krew Dev.
Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.2
or any later version published by the Free Software Foundation;
with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
===============================================================================
This document serves to only specify changes that "Dr. Robotnik's Ring Racers"
makes to the base UDMF specification.
=======================================
I. Grammar / Syntax
=======================================
No changes were made.
=======================================
II. Implementation Semantics
=======================================
------------------------------------
II.A : Storage and Retrieval of Data
------------------------------------
No changes were made.
-----------------------------------
II.B : Storage Within Archive Files
-----------------------------------
Between the TEXTMAP and ENDMAP lumps, Ring Racers supports the following
additional lumps:
BEHAVIOR = Compiled ACS code.
ZNODES = Compiled extended / GL friendly nodes. These are required.
PICTURE = A Doom graphic lump, expected to be 320x200. Intended to be a
screenshot of the map itself. This is used by the game for level
select menus.
MINIMAP = A Doom graphic lump, expected to be 100x100. Intended to be a
an overview of the map. This is used by the game for the minimap
on-screen HUD.
ENCORE = A Doom flat lump, expected to be 16x16. Describes a color remap
palette to use in Encore Mode.
TWEAKMAP = A Doom flat lump, expected to be 16x16. Describes a color remap
palette to use outside of Encore Mode.
Any lumps not listed or specified in the original document will be ignored by
the game. In particular, the "SCRIPTS" lump is considered to be ACS source
code, and is garantueed to be ignored by the engine.
--------------------------------
II.C : Implementation Dependence
--------------------------------
Ring Racers does not aspire for Doom backwards compatibility, thus it does not
support any of the namespaces in the original document, and only implements
its own: "ringracers". Any maps not using the "ringracers" namespace is
considered unsupported.
=======================================
III. Standardized Fields
=======================================
Ring Racers' namespace implements the following additional fields:
version = <integer>; // Specifies the map format version.
// This is used for resolving backwards compatibility issues.
// Note that this doesn't map directly to specification version;
// it means behavior of an already existing field or action special
// was changed.
// 0 / default - RR indev
// 1 - RR v2.0, spec v1.0
// 2 - RR v2.4, spec v1.0
linedef
{
moreids = <string>; // Additional IDs, specified as a space separated list of numbers (e.g. "2 666 1003 4505")
arg5 = <integer>; // Argument 5. Default = 0.
arg6 = <integer>; // Argument 6. Default = 0.
arg7 = <integer>; // Argument 7. Default = 0.
arg8 = <integer>; // Argument 8. Default = 0.
arg9 = <integer>; // Argument 9. Default = 0.
stringarg0 = <string>; // String argument 0. This replaces usage of 'arg0' when specified.
stringarg1 = <string>; // String argument 1. This replaces usage of 'arg1' when specified.
alpha = <float>; // Transparency value of the mid-textures. Default = 1.0.
renderstyle = <string>; // The rendering mode to use for the mid-textures.
// Can be "translucent", "add", "subtract", "reversesubtract", "modulate", or "fog".
// Default = "translucent".
// The following flags default to false.
blockplayers = <bool>; // true = line blocks players.
skewtd = <bool>; // true = upper and lower textures are skewed to match slopes.
noskew = <bool>; // true = mid-textures are not skewed to match slopes.
midpeg = <bool>; // true = invert mid-texture unpegged behavior.
midsolid = <bool>; // true = mid-texture has collision.
wrapmidtex = <bool>; // true = mid-textures are wrapped.
nonet = <bool>; // true = special is disabled in networked multiplayer games.
netonly = <bool>; // true = special is only enabled in networked multiplayer games.
notbouncy = <bool>; // true = disable bouncing collision.
transfer = <bool>; // true = use FOF transfer properties effect.
}
sidedef
{
repeatcnt = <integer>; // Number of times to mid-texture wrap. Default = 0.
}
vertex
{
zfloor = <float>; // The floor height at this vertex, for vertex slopes.
zceiling = <float>; // The ceiling height at this vertex, for vertex slopes
}
sector
{
lightfloor = <integer>; // The floor's light level. Default is 0.
lightceiling = <integer>; // The ceiling's light level. Default is 0.
lightfloorabsolute = <bool>; // true = 'lightfloor' is an absolute value. Default is
// relative to the owning sector's light level.
lightceilingabsolute = <bool>; // true = 'lightceiling' is an absolute value. Default is
// relative to the owning sector's light level.
moreids = <string>; // Additional IDs, specified as a space separated list of numbers (e.g. "2 666 1003 4505")
xpanningfloor = <float>; // X texture offset of floor texture, Default = 0.0.
ypanningfloor = <float>; // Y texture offset of floor texture, Default = 0.0.
xpanningceiling = <float>; // X texture offset of ceiling texture, Default = 0.0.
ypanningceiling = <float>; // Y texture offset of ceiling texture, Default = 0.0.
rotationfloor = <float>; // Rotation of floor texture in degrees, Default = 0.0.
rotationceiling = <float>; // Rotation of ceiling texture in degrees, Default = 0.0.
floorplane_a = <float>; // Define the plane equation for the sector's floor. Default is a horizontal plane at 'heightfloor'.
floorplane_b = <float>; // 'heightfloor' will still be used to calculate texture alignment.
floorplane_c = <float>; // The plane equation will only be used if all 4 values are given.
floorplane_d = <float>;
ceilingplane_a = <float>; // Define the plane equation for the sector's ceiling. Default is a horizontal plane at 'heightceiling'.
ceilingplane_b = <float>; // 'heightceiling' will still be used to calculate texture alignment.
ceilingplane_c = <float>; // The plane equation will only be used if all 4 values are given.
ceilingplane_d = <float>;
friction = <float>; // Sector's friction. Default = 0.90625.
gravity = <float>; // Sector's gravity multiplier. Default = 1.0.
damagetype = <string>; // Damage inflicted by the sector.
// Can be "None", "Generic", "Lava", "DeathPit", "Instakill", or "Stumble".
// Default = "None".
action = <integer>; // Sector action, same as line special. Default = 0.
arg0 = <integer>; // Argument 0. Default = 0.
arg1 = <integer>; // Argument 1. Default = 0.
arg2 = <integer>; // Argument 2. Default = 0.
arg3 = <integer>; // Argument 3. Default = 0.
arg4 = <integer>; // Argument 4. Default = 0.
arg5 = <integer>; // Argument 5. Default = 0.
arg6 = <integer>; // Argument 6. Default = 0.
arg7 = <integer>; // Argument 7. Default = 0.
arg8 = <integer>; // Argument 8. Default = 0.
arg9 = <integer>; // Argument 9. Default = 0.
stringarg0 = <integer>; // String argument 0. This replaces usage of 'arg0' when specified.
stringarg1 = <integer>; // String argument 1. This replaces usage of 'arg1' when specified.
lightcolor = <integer>; // Sector's light color as RRGGBB value. Default = 0x000000.
lightalpha = <integer>; // Sector's light color alpha value. Default = 25.
fadecolor = <integer>; // Sector's fog color as RRGGBB value. Default = 0x000000.
fadealpha = <integer>; // Sector's fog color alpha value. Default = 25.
fadestart = <integer>; // Sector's fog start distance. Default = 0.
fadeend = <integer>; // Sector's fog end distance. Default = 31.
// The following flags default to false.
colormapfog = <bool>; // true = render transparent planes at light level instead of fullbright
colormapfadesprites = <bool>; // true = fog color affects fullbright sprites
colormapprotected = <bool>; // true = colormap cannot be changed at run-time
flipspecial_nofloor = <bool>; // true = plane touch specials aren't ran when on the floor
flipspecial_ceiling = <bool>; // true = plane touch specials are ran when on the ceiling
triggerspecial_touch = <bool>; // true = specials are ran when touching edges of sector
triggerspecial_headbump = <bool>; // true = plane touch specials are ran when touching the opposite plane than gravity
invertprecip = <bool>; // true = precipitation spawning rules are inverted
gravityflip = <bool>; // true = flip gravity of objects in this sector
heatwave = <bool>; // true = add heat wave screen effect
noclipcamera = <bool>; // true = camera is not blocked by this sector
ripple_floor = <bool>; // true = add ripple effect to floor
ripple_ceiling = <bool>; // true = add ripple effect to ceiling
invertencore = <bool>; // true = encore remap rules are inverted
flatlighting = <bool>; // true = directional lighting is forced off
forcedirectionallighting = <bool>; // true = directional lighting is forced on
nostepup = <bool>; // true = objects can't step up
doublestepup = <bool>; // true = objects have increased step up
nostepdown = <bool>; // true = objects can't step down
cheatcheckactivator = <bool>; // true = players activate cheat checks when in this sector
exit = <bool>; // true = players finish match when entering sector
deleteitems = <bool>; // true = items instantly explode when entering sector
fan = <bool>; // true = players are propelled upwards in this sector
zoomtubestart = <bool>; // true = sector is start of a zoom tube
zoomtubeend = <bool>; // true = sector is end of a zoom tube
repeatspecial = <bool>; // true = repeatable action
continuousspecial = <bool>; // true = action is executed every game tick
playerenter = <bool>; // true = player activates when entering
playerfloor = <bool>; // true = player activates when touching floor
playerceiling = <bool>; // true = player activates when touching ceiling
monsterenter = <bool>; // true = enemy activates when entering
monsterfloor = <bool>; // true = enemy activates when touching floor
monsterceiling = <bool>; // true = enemy activates when touching ceiling
missileenter = <bool>; // true = items / projectiles activate when entering
missilefloor = <bool>; // true = items / projectiles activate when touching floor
missileceiling = <bool>; // true = items / projectiles activate when touching ceiling
}
thing
{
pitch = <integer>; // Pitch of thing in degrees. Default = 0 (horizontal).
roll = <integer>; // Pitch of thing in degrees. Default = 0 (horizontal).
scalex = <float>; // Vertical visual scale on thing. Default = 1.0.
scaley = <float>; // Horizontal visual scale on thing. Default = 1.0.
scale = <float>; // Vertical and horizontal visual scale on thing. Default = 1.0.
mobjscale = <float>; // Physical scale on thing. Default = 1.0.
foflayer = <integer>; // Which FOF is treated as the base floor/ceiling.
// This changes what 'height' is relative to.
// Default = 0, for no FOF.
// Action special arguments
arg5 = <integer>; // Argument 5. Default = 0.
arg6 = <integer>; // Argument 6. Default = 0.
arg7 = <integer>; // Argument 7. Default = 0.
arg8 = <integer>; // Argument 8. Default = 0.
arg9 = <integer>; // Argument 9. Default = 0.
stringarg0 = <string>; // String argument 0. This replaces usage of 'arg0' when specified.
stringarg1 = <string>; // String argument 1. This replaces usage of 'arg1' when specified.
// These arguments modify object behavior on a per-type basis.
// Not to be confused with action special arguments.
thingarg0 = <integer>; // Argument 0. Default = 0.
thingarg1 = <integer>; // Argument 1. Default = 0.
thingarg2 = <integer>; // Argument 2. Default = 0.
thingarg3 = <integer>; // Argument 3. Default = 0.
thingarg4 = <integer>; // Argument 4. Default = 0.
thingarg5 = <integer>; // Argument 5. Default = 0.
thingarg6 = <integer>; // Argument 6. Default = 0.
thingarg7 = <integer>; // Argument 7. Default = 0.
thingarg8 = <integer>; // Argument 8. Default = 0.
thingarg9 = <integer>; // Argument 9. Default = 0.
thingstringarg0 = <integer>; // String argument 0. This replaces usage of 'thingarg0' when specified.
thingstringarg1 = <integer>; // String argument 1. This replaces usage of 'thingarg1' when specified.
// Following flags default to false.
flip = <bool>; // true = object has reversed gravity
}
=======================================
Changelog
=======================================
1.0: 20.09.2024
- Initial document created.

View file

@ -6,14 +6,14 @@ add_executable(SRB2SDL2 MACOSX_BUNDLE WIN32
string.c
d_main.cpp
d_clisrv.c
d_net.c
d_net.cpp
d_netfil.c
d_netcmd.c
dehacked.c
deh_soc.c
deh_lua.c
deh_tables.c
z_zone.c
z_zone.cpp
f_finale.c
f_wipe.cpp
g_build_ticcmd.cpp
@ -60,7 +60,7 @@ add_executable(SRB2SDL2 MACOSX_BUNDLE WIN32
p_maputl.c
p_mobj.c
p_polyobj.c
p_saveg.c
p_saveg.cpp
p_setup.cpp
p_sight.c
p_spec.c
@ -77,7 +77,7 @@ add_executable(SRB2SDL2 MACOSX_BUNDLE WIN32
r_debug_parser.cpp
r_debug_printer.cpp
r_draw.cpp
r_fps.c
r_fps.cpp
r_main.cpp
r_plane.cpp
r_segs.cpp
@ -87,7 +87,7 @@ add_executable(SRB2SDL2 MACOSX_BUNDLE WIN32
r_spritefx.cpp
r_things.cpp
r_bbox.c
r_textures.c
r_textures.cpp
r_textures_dups.cpp
r_patch.cpp
r_patchrotation.c
@ -137,7 +137,7 @@ add_executable(SRB2SDL2 MACOSX_BUNDLE WIN32
k_bot.cpp
k_botitem.cpp
k_botsearch.cpp
k_grandprix.c
k_grandprix.cpp
k_boss.c
k_hud.cpp
k_hud_track.cpp
@ -167,6 +167,7 @@ add_executable(SRB2SDL2 MACOSX_BUNDLE WIN32
music.cpp
music_manager.cpp
sanitize.cpp
p_deepcopy.cpp
)
if(SRB2_CONFIG_ENABLE_WEBM_MOVIES)
@ -201,11 +202,14 @@ add_custom_target(_SRB2_reconf ALL
)
add_dependencies(SRB2SDL2 _SRB2_reconf)
if("${CMAKE_COMPILER_IS_GNUCC}" AND "${CMAKE_SYSTEM_NAME}" MATCHES "Windows")
if(("${CMAKE_COMPILER_IS_GNUCC}" OR CMAKE_CXX_COMPILER_ID STREQUAL "Clang") AND "${CMAKE_SYSTEM_NAME}" MATCHES "Windows")
target_link_options(SRB2SDL2 PRIVATE "-Wl,--disable-dynamicbase")
if("${SRB2_CONFIG_STATIC_STDLIB}")
# On MinGW with internal libraries, link the standard library statically
target_link_options(SRB2SDL2 PRIVATE "-static")
target_link_options(SRB2SDL2 PRIVATE -Wl,--add-stdcall-alias -static-libgcc -static-libstdc++ -static -lpthread)
set(THREADS_PREFER_PTHREAD_FLAG TRUE)
find_package(Threads REQUIRED)
target_link_libraries(SRB2SDL2 PRIVATE Threads::Threads)
endif()
if(CMAKE_SIZEOF_VOID_P EQUAL 4)
target_link_options(SRB2SDL2 PRIVATE "-Wl,--large-address-aware")
@ -239,6 +243,10 @@ if (UNIX)
target_compile_definitions(SRB2SDL2 PRIVATE -DUNIXCOMMON)
endif()
if (BSD MATCHES "FreeBSD")
target_compile_definitions(SRB2SDL2 PRIVATE -DFREEBSD)
endif()
if(CMAKE_COMPILER_IS_GNUCC)
find_program(OBJCOPY objcopy)
endif()
@ -250,6 +258,11 @@ if("${CMAKE_SYSTEM_NAME}" MATCHES "Linux")
endif()
endif()
if("${CMAKE_SYSTEM_NAME}" MATCHES "Haiku")
target_compile_definitions(SRB2SDL2 PRIVATE -DNOEXECINFO)
target_link_libraries(SRB2SDL2 PRIVATE network)
endif()
if("${CMAKE_SYSTEM_NAME}" MATCHES "Darwin")
target_compile_definitions(SRB2SDL2 PRIVATE -DMACOSX)
endif()
@ -257,6 +270,7 @@ endif()
target_link_libraries(SRB2SDL2 PRIVATE ZLIB::ZLIB)
target_link_libraries(SRB2SDL2 PRIVATE PNG::PNG)
target_link_libraries(SRB2SDL2 PRIVATE CURL::libcurl)
target_link_libraries(SRB2SDL2 PRIVATE Opus::opus)
if("${CMAKE_SYSTEM_NAME}" MATCHES "FreeBSD")
target_link_libraries(SRB2SDL2 PRIVATE -lexecinfo)
target_link_libraries(SRB2SDL2 PRIVATE -lpthread)
@ -408,10 +422,12 @@ endif()
# Compatibility flag with later versions of GCC
# We should really fix our code to not need this
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
check_cxx_compiler_flag("-mno-ms-bitfields" HAS_NO_MS_BITFIELDS)
if(HAS_NO_MS_BITFIELDS)
target_compile_options(SRB2SDL2 PRIVATE -mno-ms-bitfields)
if (NOT SRB2_CONFIG_FORCE_NO_MS_BITFIELDS)
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
check_cxx_compiler_flag("-mno-ms-bitfields" HAS_NO_MS_BITFIELDS)
if(HAS_NO_MS_BITFIELDS)
target_compile_options(SRB2SDL2 PRIVATE -mno-ms-bitfields)
endif()
endif()
endif()
@ -581,6 +597,11 @@ endif()
if(SRB2_CONFIG_PACKETDROP)
target_compile_definitions(SRB2SDL2 PRIVATE -DPACKETDROP)
endif()
if(SRB2_CONFIG_EXECINFO)
else()
target_compile_definitions(SRB2SDL2 PRIVATE -DNOEXECINFO)
message(STATUS "You have disabled stack trace dump support")
endif()
if(SRB2_CONFIG_ZDEBUG)
target_compile_definitions(SRB2SDL2 PRIVATE -DZDEBUG)
endif()
@ -609,32 +630,182 @@ endif()
add_subdirectory(hud)
add_subdirectory(modp_b64)
# strip debug symbols into separate file when using gcc.
# strip debug symbols into separate file when using gcc or clang.
# to be consistent with Makefile, don't generate for OS X.
if((CMAKE_COMPILER_IS_GNUCC) AND NOT ("${CMAKE_SYSTEM_NAME}" MATCHES Darwin))
if((CMAKE_COMPILER_IS_GNUCC OR CMAKE_CXX_COMPILER_ID STREQUAL "Clang") AND NOT ("${CMAKE_SYSTEM_NAME}" MATCHES Darwin))
if(${CMAKE_BUILD_TYPE} MATCHES RelWithDebInfo OR SRB2_CONFIG_ALWAYS_MAKE_DEBUGLINK)
message(STATUS "Will make separate debug symbols in *.debug")
add_custom_command(TARGET SRB2SDL2 POST_BUILD
COMMAND ${OBJCOPY} ${OBJCOPY_ONLY_KEEP_DEBUG} $<TARGET_FILE:SRB2SDL2> $<TARGET_FILE:SRB2SDL2>.debug
COMMAND ${CMAKE_OBJCOPY} ${OBJCOPY_ONLY_KEEP_DEBUG} $<TARGET_FILE:SRB2SDL2> $<TARGET_FILE:SRB2SDL2>.debug
# mold linker: .gnu_debuglink is present by default, so --add-gnu-debuglink would fail
COMMAND ${OBJCOPY} --strip-debug --remove-section=.gnu_debuglink $<TARGET_FILE:SRB2SDL2>
COMMAND ${OBJCOPY} --add-gnu-debuglink=$<TARGET_FILE:SRB2SDL2>.debug $<TARGET_FILE:SRB2SDL2>
COMMAND ${CMAKE_OBJCOPY} --strip-debug --remove-section=.gnu_debuglink $<TARGET_FILE:SRB2SDL2>
COMMAND ${CMAKE_OBJCOPY} --add-gnu-debuglink=$<TARGET_FILE:SRB2SDL2>.debug $<TARGET_FILE:SRB2SDL2>
)
endif()
endif()
# copy DLLs to bin/ directory if building internal shared on windows
if("${CMAKE_SYSTEM_NAME}" STREQUAL Windows AND NOT "${SRB2_CONFIG_INTERNAL_LIBRARIES}" AND "${SRB2_CONFIG_SHARED_INTERNAL_LIBRARIES}")
if("${CMAKE_SYSTEM_NAME}" STREQUAL Windows AND NOT "${SRB2_CONFIG_INTERNAL_LIBRARIES}")
# also copy implicitly linked system libraries
set(ADDITIONAL_DLLS "")
if("${CMAKE_C_COMPILER_ID}" STREQUAL GNU)
# also copy implicitly linked system libraries
get_filename_component(MINGW_BIN_PATH ${CMAKE_CXX_COMPILER} PATH)
list(APPEND ADDITIONAL_DLLS
"libgcc_s_dw2-1.dll"
"libstdc++-6.dll"
"libwinpthread-1.dll"
if("${CMAKE_CXX_COMPILER_ID}" STREQUAL GNU)
string(CONCAT gcc_search_dirs_path "${CMAKE_BINARY_DIR}" /gcc_search_dirs.txt)
#message(STATUS gcc_search_dirs_path=${gcc_search_dirs_path})
execute_process(
COMMAND ${CMAKE_CXX_COMPILER} -print-search-dirs
OUTPUT_FILE "${gcc_search_dirs_path}"
#OUTPUT_VARIABLE gcc_search_dirs
)
list(TRANSFORM ADDITIONAL_DLLS PREPEND "${MINGW_BIN_PATH}/")
file(READ "${gcc_search_dirs_path}" gcc_search_dirs)
#message(STATUS gcc_search_dirs=${gcc_search_dirs})
#set(gcc_install_dir "${gcc_search_dirs}")
#string(REGEX MATCH "install: =[ \t]*([^\r\n]*)" gcc_install_dir "${gcc_install_dir}" )
#set(gcc_install_dir "${CMAKE_MATCH_1}")
#message(STATUS gcc_install_dir="${gcc_install_dir}")
string(CONCAT gcc_search_dirs_install_path_1 "${CMAKE_BINARY_DIR}" /gcc_search_dirs_install_1.txt)
#message(STATUS gcc_search_dirs_install_path_1=${gcc_search_dirs_install_path_1})
execute_process(
COMMAND grep "^install:"
INPUT_FILE "${gcc_search_dirs_path}"
OUTPUT_FILE "${gcc_search_dirs_install_path_1}"
)
string(CONCAT gcc_search_dirs_install_path_2 "${CMAKE_BINARY_DIR}" /gcc_search_dirs_install_2.txt)
#message(STATUS gcc_search_dirs_install_path_2=${gcc_search_dirs_install_path_2})
execute_process(
COMMAND sed -e "s/^install: //" -e "s,=/,/,g"
INPUT_FILE "${gcc_search_dirs_install_path_1}"
OUTPUT_FILE "${gcc_search_dirs_install_path_2}"
)
if(NOT ("${CMAKE_HOST_SYSTEM_NAME}" STREQUAL "Windows"))
string(REPLACE ":" ";" gcc_install_dir "${gcc_install_dir}")
endif()
file(READ ${gcc_search_dirs_install_path_2} gcc_install_dir)
#set(gcc_programs_dir "${gcc_search_dirs}")
#string(REGEX MATCH "programs: =[ \t]*([^\r\n]*)" gcc_programs_dir "${gcc_programs_dir}" )
#set(gcc_programs_dir "${CMAKE_MATCH_1}")
#message(STATUS gcc_programs_dir="${gcc_programs_dir}")
string(CONCAT gcc_search_dirs_programs_path_1 "${CMAKE_BINARY_DIR}" /gcc_search_dirs_programs_1.txt)
#message(STATUS gcc_search_dirs_programs_path_1=${gcc_search_dirs_programs_path_1})
execute_process(
COMMAND grep "^programs:"
INPUT_FILE "${gcc_search_dirs_path}"
OUTPUT_FILE "${gcc_search_dirs_programs_path_1}"
)
string(CONCAT gcc_search_dirs_programs_path_2 "${CMAKE_BINARY_DIR}" /gcc_search_dirs_programs_2.txt)
#message(STATUS gcc_search_dirs_programs_path_2=${gcc_search_dirs_programs_path_2})
execute_process(
COMMAND sed -e "s/^programs: =//" -e "s,=/,/,g"
INPUT_FILE "${gcc_search_dirs_programs_path_1}"
OUTPUT_FILE "${gcc_search_dirs_programs_path_2}"
)
file(READ ${gcc_search_dirs_programs_path_2} gcc_programs_dir)
if(NOT ("${CMAKE_HOST_SYSTEM_NAME}" STREQUAL "Windows"))
string(REPLACE ":" ";" gcc_programs_dir "${gcc_programs_dir}")
endif()
#set(gcc_libraries_dir "${gcc_search_dirs}")
#string(REGEX MATCH "libraries: =[ \t]*([^\r\n]*)" gcc_libraries_dir "${gcc_libraries_dir}" )
#set(gcc_libraries_dir "${CMAKE_MATCH_1}")
#message(STATUS gcc_libraries_dir="${gcc_libraries_dir}")
string(CONCAT gcc_search_dirs_libraries_path_1 "${CMAKE_BINARY_DIR}" /gcc_search_dirs_libraries_1.txt)
#message(STATUS gcc_search_dirs_libraries_path_1=${gcc_search_dirs_libraries_path_1})
execute_process(
COMMAND grep "^libraries:"
INPUT_FILE "${gcc_search_dirs_path}"
OUTPUT_FILE "${gcc_search_dirs_libraries_path_1}"
)
string(CONCAT gcc_search_dirs_libraries_path_2 "${CMAKE_BINARY_DIR}" /gcc_search_dirs_libraries_2.txt)
#message(STATUS gcc_search_dirs_libraries_path_2=${gcc_search_dirs_libraries_path_2})
execute_process(
COMMAND sed -e "s/^libraries: =//" -e "s,=/,/,g"
INPUT_FILE "${gcc_search_dirs_libraries_path_1}"
OUTPUT_FILE "${gcc_search_dirs_libraries_path_2}"
)
file(READ ${gcc_search_dirs_libraries_path_2} gcc_libraries_dir)
if(NOT ("${CMAKE_HOST_SYSTEM_NAME}" STREQUAL "Windows"))
string(REPLACE ":" ";" gcc_libraries_dir "${gcc_libraries_dir}")
endif()
#list(LENGTH gcc_install_dir gcc_install_dir_len)
#list(LENGTH gcc_programs_dir gcc_programs_dir_len)
#list(LENGTH gcc_libraries_dir gcc_libraries_dir_len)
#message(STATUS gcc_install_dir_len="${gcc_install_dir_len}")
#message(STATUS gcc_install_dir="${gcc_install_dir}")
#message(STATUS gcc_programs_dir_len="${gcc_programs_dir_len}")
#message(STATUS gcc_programs_dir="${gcc_programs_dir}")
#message(STATUS gcc_libraries_dir_len="${gcc_libraries_dir_len}")
#message(STATUS gcc_libraries_dir="${gcc_libraries_dir}")
get_filename_component(CMAKE_CXX_COMPILER_DIR ${CMAKE_CXX_COMPILER} DIRECTORY)
#message(STATUS CMAKE_CXX_COMPILER_DIR="${CMAKE_CXX_COMPILER_DIR}")
set(OLD_CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES})
set(CMAKE_FIND_LIBRARY_SUFFIXES "" ${CMAKE_FIND_LIBRARY_SUFFIXES})
set(OLD_CMAKE_FIND_LIBRARY_PREFIXES ${CMAKE_FIND_LIBRARY_PREFIXES})
set(CMAKE_FIND_LIBRARY_PREFIXES "" ${CMAKE_FIND_LIBRARY_PREFIXES})
find_library(LIBUNWIND
NAMES "libunwind.dll"
PATHS ${gcc_programs_dir} ${CMAKE_CXX_COMPILER_DIR}
)
if (LIBUNWIND)
#message(STATUS LIBUNWIND="${LIBUNWIND}")
list(APPEND ADDITIONAL_DLLS ${LIBUNWIND})
endif()
unset(LIBUNWIND)
find_library(LIBGCC
NAMES "libgcc_s_dw2-1.dll" "libgcc_s_sjlj-1.dll" "libgcc_s_seh-1.dll"
PATHS ${gcc_programs_dir} ${CMAKE_CXX_COMPILER_DIR}
)
if (LIBGCC)
#message(STATUS LIBGCC="${LIBGCC}")
list(APPEND ADDITIONAL_DLLS ${LIBGCC})
endif()
unset(LIBGCC)
find_library(LIBSTDCPP
NAMES "libstdc++-6.dll" "libc++.dll"
PATHS ${gcc_programs_dir} ${CMAKE_CXX_COMPILER_DIR}
)
if (LIBSTDCPP)
#message(STATUS LIBSTDCPP="${LIBSTDCPP}")
list(APPEND ADDITIONAL_DLLS ${LIBSTDCPP})
endif()
unset(LIBSTDCPP)
find_library(LIBPTHREAD
NAMES "winpthread-1.dll" "libwinpthread-1.dll" "pthreadGC2.dll"
PATHS ${gcc_libraries_dir} ${CMAKE_CXX_COMPILER_DIR}
)
if(LIBPTHREAD)
#message(STATUS LIBPTHREAD="${LIBPTHREAD}")
list(APPEND ADDITIONAL_DLLS ${LIBPTHREAD})
endif()
set(CMAKE_FIND_LIBRARY_SUFFIXES ${OLD_CMAKE_FIND_LIBRARY_SUFFIXES})
set(CMAKE_FIND_LIBRARY_PREFIXES ${OLD_CMAKE_FIND_LIBRARY_PREFIXES})
unset(LIBPTHREAD)
unset(gcc_install_dir)
unset(gcc_programs_dir)
unset(gcc_libraries_dir)
unset(OLD_CMAKE_FIND_LIBRARY_SUFFIXES)
unset(OLD_CMAKE_FIND_LIBRARY_PREFIXES)
#message(STATUS ADDITIONAL_DLLS="${ADDITIONAL_DLLS}")
endif()
add_custom_command(TARGET SRB2SDL2 POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different
@ -646,3 +817,11 @@ if("${CMAKE_SYSTEM_NAME}" STREQUAL Windows AND NOT "${SRB2_CONFIG_INTERNAL_LIBRA
COMMENT "Copying runtime DLLs"
)
endif()
# Setup clang-tidy
if(SRB2_CONFIG_ENABLE_CLANG_TIDY_C)
target_set_default_clang_tidy(SRB2SDL2 C "-*,clang-analyzer-*,-clang-analyzer-cplusplus-*")
endif()
if(SRB2_CONFIG_ENABLE_CLANG_TIDY_CXX)
target_set_default_clang_tidy(SRB2SDL2 CXX "-*,clang-analyzer-*,modernize-*")
endif()

View file

@ -1,8 +1,8 @@
// DR. ROBOTNIK'S RING RACERS
//-----------------------------------------------------------------------------
// Copyright (C) 2016 by James Haley, David Hill, et al. (Team Eternity)
// Copyright (C) 2024 by Sally "TehRealSalt" Cochenour
// Copyright (C) 2024 by Kart Krew
// Copyright (C) 2025 by Sally "TehRealSalt" Cochenour
// Copyright (C) 2025 by Kart Krew
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.

View file

@ -1,8 +1,8 @@
// DR. ROBOTNIK'S RING RACERS
//-----------------------------------------------------------------------------
// Copyright (C) 2016 by James Haley, David Hill, et al. (Team Eternity)
// Copyright (C) 2024 by Sally "TehRealSalt" Cochenour
// Copyright (C) 2024 by Kart Krew
// Copyright (C) 2025 by Sally "TehRealSalt" Cochenour
// Copyright (C) 2025 by Kart Krew
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
@ -1147,6 +1147,37 @@ bool CallFunc_SetLineTexture(ACSVM::Thread *thread, const ACSVM::Word *argV, ACS
return false;
}
/*--------------------------------------------------
bool CallFunc_SetLineBlocking(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC)
Changes a linedef's blocking flag.
--------------------------------------------------*/
bool CallFunc_SetLineBlocking(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC)
{
mtag_t tag = 0;
UINT32 blocking = 0;
INT32 lineId = -1;
tag = argV[0];
if (argV[1] != 0)
{
blocking = ML_IMPASSABLE;
}
TAG_ITER_LINES(tag, lineId)
{
line_t *line = &lines[lineId];
if (line->flags & ML_TWOSIDED) // disallow changing this for 1-sided lines
{
line->flags = (line->flags & ~ML_IMPASSABLE) | blocking;
}
}
return false;
}
/*--------------------------------------------------
bool CallFunc_SetLineSpecial(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC)
@ -1271,7 +1302,7 @@ bool CallFunc_EndPrintBold(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM
bool CallFunc_PlayerTeam(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC)
{
auto info = &static_cast<Thread *>(thread)->info;
UINT8 teamID = 0;
UINT8 teamID = TEAM_UNASSIGNED;
(void)argV;
(void)argC;
@ -1280,7 +1311,7 @@ bool CallFunc_PlayerTeam(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::
&& (info->mo != NULL && P_MobjWasRemoved(info->mo) == false)
&& (info->mo->player != NULL))
{
teamID = info->mo->player->ctfteam;
teamID = info->mo->player->team;
}
thread->dataStk.push(teamID);
@ -1882,8 +1913,9 @@ bool CallFunc_GetGrabbedSprayCan(ACSVM::Thread *thread, const ACSVM::Word *argV,
&& gamemap-1 < basenummapheaders)
{
// See also P_SprayCanInit
UINT16 can_id = mapheaderinfo[gamemap-1]->cache_spraycan;
UINT16 can_id = mapheaderinfo[gamemap-1]->records.spraycan;
// Intentionally not affected by MCAN_BONUS
if (can_id < gamedata->numspraycans)
{
UINT16 col = gamedata->spraycans[can_id].col;

View file

@ -1,8 +1,8 @@
// DR. ROBOTNIK'S RING RACERS
//-----------------------------------------------------------------------------
// Copyright (C) 2016 by James Haley, David Hill, et al. (Team Eternity)
// Copyright (C) 2024 by Sally "TehRealSalt" Cochenour
// Copyright (C) 2024 by Kart Krew
// Copyright (C) 2025 by Sally "TehRealSalt" Cochenour
// Copyright (C) 2025 by Kart Krew
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
@ -57,6 +57,7 @@ bool CallFunc_IsNetworkGame(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSV
bool CallFunc_SectorSound(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC);
bool CallFunc_AmbientSound(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC);
bool CallFunc_SetLineTexture(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC);
bool CallFunc_SetLineBlocking(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC);
bool CallFunc_SetLineSpecial(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC);
bool CallFunc_ThingSound(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC);
bool CallFunc_EndPrintBold(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC);

View file

@ -1,8 +1,8 @@
// DR. ROBOTNIK'S RING RACERS
//-----------------------------------------------------------------------------
// Copyright (C) 2016 by James Haley, David Hill, et al. (Team Eternity)
// Copyright (C) 2024 by Sally "TehRealSalt" Cochenour
// Copyright (C) 2024 by Kart Krew
// Copyright (C) 2025 by Sally "TehRealSalt" Cochenour
// Copyright (C) 2025 by Kart Krew
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
@ -88,7 +88,7 @@ Environment::Environment()
addCodeDataACS0( 95, {"", 2, addCallFunc(CallFunc_AmbientSound)});
addCodeDataACS0( 97, {"", 4, addCallFunc(CallFunc_SetLineTexture)});
addCodeDataACS0( 98, {"", 2, addCallFunc(CallFunc_SetLineBlocking)});
addCodeDataACS0( 99, {"", 7, addCallFunc(CallFunc_SetLineSpecial)});
addCodeDataACS0(100, {"", 3, addCallFunc(CallFunc_ThingSound)});
addCodeDataACS0(101, {"", 0, addCallFunc(CallFunc_EndPrintBold)});
@ -228,8 +228,7 @@ void Environment::loadModule(ACSVM::Module *module)
if (name->i == (size_t)LUMPERROR)
{
// No lump given for module.
CONS_Alert(CONS_WARNING, "Could not find ACS module \"%s\"; scripts will not function properly!\n", name->s->str);
return; //throw ACSVM::ReadError("file open failure");
throw ACSVM::ReadError("invalid lump");
}
lumpLen = W_LumpLength(name->i);
@ -280,9 +279,7 @@ void Environment::loadModule(ACSVM::Module *module)
}
else
{
// Unlike Hexen, a BEHAVIOR lump is not required.
// Simply ignore in this instance.
CONS_Debug(DBG_SETUP, "ACS module has no data, ignoring...\n");
throw ACSVM::ReadError("file empty");
}
}

View file

@ -1,8 +1,8 @@
// DR. ROBOTNIK'S RING RACERS
//-----------------------------------------------------------------------------
// Copyright (C) 2016 by James Haley, David Hill, et al. (Team Eternity)
// Copyright (C) 2024 by Sally "TehRealSalt" Cochenour
// Copyright (C) 2024 by Kart Krew
// Copyright (C) 2025 by Sally "TehRealSalt" Cochenour
// Copyright (C) 2025 by Kart Krew
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.

View file

@ -1,8 +1,8 @@
// DR. ROBOTNIK'S RING RACERS
//-----------------------------------------------------------------------------
// Copyright (C) 2016 by James Haley, David Hill, et al. (Team Eternity)
// Copyright (C) 2024 by Sally "TehRealSalt" Cochenour
// Copyright (C) 2024 by Kart Krew
// Copyright (C) 2025 by Sally "TehRealSalt" Cochenour
// Copyright (C) 2025 by Kart Krew
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
@ -142,6 +142,13 @@ void ACS_LoadLevelScripts(size_t mapID)
map->active = true;
// Insert BEHAVIOR lump into the list.
virtres_t *vRes = vres_GetMap(mapheaderinfo[mapID]->lumpnum);
auto _ = srb2::finally([vRes]() { vres_Free(vRes); });
// Unlike Hexen, a BEHAVIOR lump is not required.
// Simply ignore in this instance.
virtlump_t *vLump = vres_Find(vRes, "BEHAVIOR");
if (vLump != nullptr && vLump->size > 0)
{
ACSVM::ModuleName name = ACSVM::ModuleName(
env->getString( mapheaderinfo[mapID]->lumpname ),
@ -150,6 +157,7 @@ void ACS_LoadLevelScripts(size_t mapID)
);
modules.push_back(env->getModule(name));
CONS_Debug(DBG_SETUP, "Found BEHAVIOR lump.\n");
}
if (modules.empty() == false)
@ -562,8 +570,10 @@ void ACS_Archive(savebuffer_t *save)
std::ostream stream{&buffer};
ACSVM::Serial serial{stream};
#if 0
// Enable debug signatures.
serial.signs = true;
#endif
try
{

View file

@ -1,8 +1,8 @@
// DR. ROBOTNIK'S RING RACERS
//-----------------------------------------------------------------------------
// Copyright (C) 2016 by James Haley, David Hill, et al. (Team Eternity)
// Copyright (C) 2024 by Sally "TehRealSalt" Cochenour
// Copyright (C) 2024 by Kart Krew
// Copyright (C) 2025 by Sally "TehRealSalt" Cochenour
// Copyright (C) 2025 by Kart Krew
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.

View file

@ -1,8 +1,8 @@
// DR. ROBOTNIK'S RING RACERS
//-----------------------------------------------------------------------------
// Copyright (C) 2016 by James Haley, David Hill, et al. (Team Eternity)
// Copyright (C) 2024 by Sally "TehRealSalt" Cochenour
// Copyright (C) 2024 by Kart Krew
// Copyright (C) 2025 by Sally "TehRealSalt" Cochenour
// Copyright (C) 2025 by Kart Krew
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.

View file

@ -1,8 +1,8 @@
// DR. ROBOTNIK'S RING RACERS
//-----------------------------------------------------------------------------
// Copyright (C) 2016 by James Haley, David Hill, et al. (Team Eternity)
// Copyright (C) 2024 by Sally "TehRealSalt" Cochenour
// Copyright (C) 2024 by Kart Krew
// Copyright (C) 2025 by Sally "TehRealSalt" Cochenour
// Copyright (C) 2025 by Kart Krew
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.

View file

@ -1,8 +1,8 @@
// DR. ROBOTNIK'S RING RACERS
//-----------------------------------------------------------------------------
// Copyright (C) 2016 by James Haley, David Hill, et al. (Team Eternity)
// Copyright (C) 2024 by Sally "TehRealSalt" Cochenour
// Copyright (C) 2024 by Kart Krew
// Copyright (C) 2025 by Sally "TehRealSalt" Cochenour
// Copyright (C) 2025 by Kart Krew
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.

View file

@ -1,8 +1,8 @@
// DR. ROBOTNIK'S RING RACERS
//-----------------------------------------------------------------------------
// Copyright (C) 2016 by James Haley, David Hill, et al. (Team Eternity)
// Copyright (C) 2024 by Sally "TehRealSalt" Cochenour
// Copyright (C) 2024 by Kart Krew
// Copyright (C) 2025 by Sally "TehRealSalt" Cochenour
// Copyright (C) 2025 by Kart Krew
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.

View file

@ -75,6 +75,7 @@ add_library(acsvm ${ACSVM_SHARED_DECL}
Types.hpp
Vector.hpp
)
target_compile_features(acsvm PRIVATE cxx_std_17)
ACSVM_INSTALL_LIB(acsvm)

View file

@ -10,7 +10,7 @@
##
##-----------------------------------------------------------------------------
cmake_minimum_required(VERSION 2.6)
cmake_minimum_required(VERSION 3.14)
cmake_policy(SET CMP0017 NEW)

View file

@ -1,7 +1,7 @@
// DR. ROBOTNIK'S RING RACERS
//-----------------------------------------------------------------------------
// Copyright (C) 2024 by Vivian "toastergrl" Grannell.
// Copyright (C) 2024 by Kart Krew.
// Copyright (C) 2025 by Vivian "toastergrl" Grannell.
// Copyright (C) 2025 by Kart Krew.
// Copyright (C) 2020 by Sonic Team Junior.
// Copyright (C) 2000 by DooM Legacy Team.
// Copyright (C) 1996 by id Software, Inc.

View file

@ -1,7 +1,7 @@
// DR. ROBOTNIK'S RING RACERS
//-----------------------------------------------------------------------------
// Copyright (C) 2024 by Vivian "toastergrl" Grannell.
// Copyright (C) 2024 by Kart Krew.
// Copyright (C) 2025 by Vivian "toastergrl" Grannell.
// Copyright (C) 2025 by Kart Krew.
// Copyright (C) 2020 by Sonic Team Junior.
// Copyright (C) 2000 by DooM Legacy Team.
// Copyright (C) 1996 by id Software, Inc.

View file

@ -1,6 +1,6 @@
// DR. ROBOTNIK'S RING RACERS
//-----------------------------------------------------------------------------
// Copyright (C) 2024 by Kart Krew.
// Copyright (C) 2025 by Kart Krew.
// Copyright (C) 2020 by Sonic Team Junior.
//
// This program is free software distributed under the

View file

@ -1,6 +1,6 @@
// DR. ROBOTNIK'S RING RACERS
//-----------------------------------------------------------------------------
// Copyright (C) 2024 by Kart Krew.
// Copyright (C) 2025 by Kart Krew.
// Copyright (C) 2020 by Sonic Team Junior.
//
// This program is free software distributed under the

View file

@ -1,6 +1,6 @@
// DR. ROBOTNIK'S RING RACERS
//-----------------------------------------------------------------------------
// Copyright (C) 2024 by Kart Krew.
// Copyright (C) 2025 by Kart Krew.
// Copyright (C) 2020 by Sonic Team Junior.
//
// This program is free software distributed under the

View file

@ -1,6 +1,6 @@
// DR. ROBOTNIK'S RING RACERS
//-----------------------------------------------------------------------------
// Copyright (C) 2024 by Kart Krew.
// Copyright (C) 2025 by Kart Krew.
// Copyright (C) 2020 by Sonic Team Junior.
//
// This program is free software distributed under the

View file

@ -1,6 +1,6 @@
// DR. ROBOTNIK'S RING RACERS
//-----------------------------------------------------------------------------
// Copyright (C) 2024 by Kart Krew.
// Copyright (C) 2025 by Kart Krew.
// Copyright (C) 2020 by Sonic Team Junior.
//
// This program is free software distributed under the

View file

@ -1,6 +1,6 @@
// DR. ROBOTNIK'S RING RACERS
//-----------------------------------------------------------------------------
// Copyright (C) 2024 by Kart Krew.
// Copyright (C) 2025 by Kart Krew.
// Copyright (C) 2020 by Sonic Team Junior.
//
// This program is free software distributed under the

View file

@ -1,6 +1,6 @@
// DR. ROBOTNIK'S RING RACERS
//-----------------------------------------------------------------------------
// Copyright (C) 2024 by Kart Krew.
// Copyright (C) 2025 by Kart Krew.
// Copyright (C) 2020 by Sonic Team Junior.
//
// This program is free software distributed under the

View file

@ -71,7 +71,7 @@ apng_create_info_struct (png_structp pngp)
{
apng_infop ainfop;
(void)pngp;
if (( ainfop = calloc(sizeof (apng_info),1) ))
if (( ainfop = calloc(1, sizeof (apng_info)) ))
{
apng_set_write_fn(pngp, ainfop, 0, 0, 0, 0, 0);
apng_set_set_acTL_fn(pngp, ainfop, 0);

View file

@ -1,7 +1,7 @@
// DR. ROBOTNIK'S RING RACERS
//-----------------------------------------------------------------------------
// Copyright (C) 2024 by James Robert Roman
// Copyright (C) 2024 by Kart Krew
// Copyright (C) 2025 by James Robert Roman
// Copyright (C) 2025 by Kart Krew
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.

View file

@ -1,6 +1,6 @@
// DR. ROBOTNIK'S RING RACERS
//-----------------------------------------------------------------------------
// Copyright (C) 2024 by Kart Krew.
// Copyright (C) 2025 by Kart Krew.
// Copyright (C) 2020 by Sonic Team Junior.
// Copyright (C) 2000 by DooM Legacy Team.
//

View file

@ -1,7 +1,7 @@
// DR. ROBOTNIK'S RING RACERS
//-----------------------------------------------------------------------------
// Copyright (C) 2024 by Ronald "Eidolon" Kinard
// Copyright (C) 2024 by Kart Krew
// Copyright (C) 2025 by Ronald "Eidolon" Kinard
// Copyright (C) 2025 by Kart Krew
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.

View file

@ -1,7 +1,7 @@
// DR. ROBOTNIK'S RING RACERS
//-----------------------------------------------------------------------------
// Copyright (C) 2024 by Ronald "Eidolon" Kinard
// Copyright (C) 2024 by Kart Krew
// Copyright (C) 2025 by Ronald "Eidolon" Kinard
// Copyright (C) 2025 by Kart Krew
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.

View file

@ -1,7 +1,7 @@
// DR. ROBOTNIK'S RING RACERS
//-----------------------------------------------------------------------------
// Copyright (C) 2024 by Ronald "Eidolon" Kinard
// Copyright (C) 2024 by Kart Krew
// Copyright (C) 2025 by Ronald "Eidolon" Kinard
// Copyright (C) 2025 by Kart Krew
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.

View file

@ -1,7 +1,7 @@
// DR. ROBOTNIK'S RING RACERS
//-----------------------------------------------------------------------------
// Copyright (C) 2024 by Ronald "Eidolon" Kinard
// Copyright (C) 2024 by Kart Krew
// Copyright (C) 2025 by Ronald "Eidolon" Kinard
// Copyright (C) 2025 by Kart Krew
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.

View file

@ -1,7 +1,7 @@
// DR. ROBOTNIK'S RING RACERS
//-----------------------------------------------------------------------------
// Copyright (C) 2024 by Ronald "Eidolon" Kinard
// Copyright (C) 2024 by Kart Krew
// Copyright (C) 2025 by Ronald "Eidolon" Kinard
// Copyright (C) 2025 by Kart Krew
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.

View file

@ -1,7 +1,7 @@
// DR. ROBOTNIK'S RING RACERS
//-----------------------------------------------------------------------------
// Copyright (C) 2024 by Ronald "Eidolon" Kinard
// Copyright (C) 2024 by Kart Krew
// Copyright (C) 2025 by Ronald "Eidolon" Kinard
// Copyright (C) 2025 by Kart Krew
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.

View file

@ -1,7 +1,7 @@
// DR. ROBOTNIK'S RING RACERS
//-----------------------------------------------------------------------------
// Copyright (C) 2024 by Ronald "Eidolon" Kinard
// Copyright (C) 2024 by Kart Krew
// Copyright (C) 2025 by Ronald "Eidolon" Kinard
// Copyright (C) 2025 by Kart Krew
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.

View file

@ -1,7 +1,7 @@
// DR. ROBOTNIK'S RING RACERS
//-----------------------------------------------------------------------------
// Copyright (C) 2024 by Ronald "Eidolon" Kinard
// Copyright (C) 2024 by Kart Krew
// Copyright (C) 2025 by Ronald "Eidolon" Kinard
// Copyright (C) 2025 by Kart Krew
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.

View file

@ -1,7 +1,7 @@
// DR. ROBOTNIK'S RING RACERS
//-----------------------------------------------------------------------------
// Copyright (C) 2024 by Ronald "Eidolon" Kinard
// Copyright (C) 2024 by Kart Krew
// Copyright (C) 2025 by Ronald "Eidolon" Kinard
// Copyright (C) 2025 by Kart Krew
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.

View file

@ -1,7 +1,7 @@
// DR. ROBOTNIK'S RING RACERS
//-----------------------------------------------------------------------------
// Copyright (C) 2024 by Ronald "Eidolon" Kinard
// Copyright (C) 2024 by Kart Krew
// Copyright (C) 2025 by Ronald "Eidolon" Kinard
// Copyright (C) 2025 by Kart Krew
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.

View file

@ -1,7 +1,7 @@
// DR. ROBOTNIK'S RING RACERS
//-----------------------------------------------------------------------------
// Copyright (C) 2024 by Ronald "Eidolon" Kinard
// Copyright (C) 2024 by Kart Krew
// Copyright (C) 2025 by Ronald "Eidolon" Kinard
// Copyright (C) 2025 by Kart Krew
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.

View file

@ -1,7 +1,7 @@
// DR. ROBOTNIK'S RING RACERS
//-----------------------------------------------------------------------------
// Copyright (C) 2024 by Ronald "Eidolon" Kinard
// Copyright (C) 2024 by Kart Krew
// Copyright (C) 2025 by Ronald "Eidolon" Kinard
// Copyright (C) 2025 by Kart Krew
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.

View file

@ -1,7 +1,7 @@
// DR. ROBOTNIK'S RING RACERS
//-----------------------------------------------------------------------------
// Copyright (C) 2024 by Ronald "Eidolon" Kinard
// Copyright (C) 2024 by Kart Krew
// Copyright (C) 2025 by Ronald "Eidolon" Kinard
// Copyright (C) 2025 by Kart Krew
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
@ -76,7 +76,7 @@ Ogg::Ogg() noexcept : memory_data_(), instance_(nullptr)
{
}
Ogg::Ogg(std::vector<std::byte> data) : memory_data_(std::move(data)), instance_(nullptr)
Ogg::Ogg(Vector<std::byte> data) : memory_data_(std::move(data)), instance_(nullptr)
{
_init_with_data();
}
@ -153,8 +153,8 @@ OggComment Ogg::comment() const
stb_vorbis_comment c_comment = stb_vorbis_get_comment(instance_);
return OggComment {
std::string(c_comment.vendor),
std::vector<std::string>(c_comment.comment_list, c_comment.comment_list + c_comment.comment_list_length)};
String(c_comment.vendor),
Vector<String>(c_comment.comment_list, c_comment.comment_list + c_comment.comment_list_length)};
}
std::size_t Ogg::sample_rate() const

View file

@ -1,7 +1,7 @@
// DR. ROBOTNIK'S RING RACERS
//-----------------------------------------------------------------------------
// Copyright (C) 2024 by Ronald "Eidolon" Kinard
// Copyright (C) 2024 by Kart Krew
// Copyright (C) 2025 by Ronald "Eidolon" Kinard
// Copyright (C) 2025 by Kart Krew
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
@ -35,19 +35,19 @@ public:
struct OggComment
{
std::string vendor;
std::vector<std::string> comments;
String vendor;
Vector<String> comments;
};
class Ogg final
{
std::vector<std::byte> memory_data_;
Vector<std::byte> memory_data_;
stb_vorbis* instance_;
public:
Ogg() noexcept;
explicit Ogg(std::vector<std::byte> data);
explicit Ogg(Vector<std::byte> data);
explicit Ogg(tcb::span<std::byte> data);
Ogg(const Ogg&) = delete;
@ -77,7 +77,7 @@ private:
template <typename I, typename std::enable_if_t<srb2::io::IsInputStreamV<I>, int> = 0>
inline Ogg load_ogg(I& stream)
{
std::vector<std::byte> data = srb2::io::read_to_vec(stream);
srb2::Vector<std::byte> data = srb2::io::read_to_vec(stream);
return Ogg {std::move(data)};
}

View file

@ -1,7 +1,7 @@
// DR. ROBOTNIK'S RING RACERS
//-----------------------------------------------------------------------------
// Copyright (C) 2024 by Ronald "Eidolon" Kinard
// Copyright (C) 2024 by Kart Krew
// Copyright (C) 2025 by Ronald "Eidolon" Kinard
// Copyright (C) 2025 by Kart Krew
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.

View file

@ -1,7 +1,7 @@
// DR. ROBOTNIK'S RING RACERS
//-----------------------------------------------------------------------------
// Copyright (C) 2024 by Ronald "Eidolon" Kinard
// Copyright (C) 2024 by Kart Krew
// Copyright (C) 2025 by Ronald "Eidolon" Kinard
// Copyright (C) 2025 by Kart Krew
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.

View file

@ -1,7 +1,7 @@
// DR. ROBOTNIK'S RING RACERS
//-----------------------------------------------------------------------------
// Copyright (C) 2024 by Ronald "Eidolon" Kinard
// Copyright (C) 2024 by Kart Krew
// Copyright (C) 2025 by Ronald "Eidolon" Kinard
// Copyright (C) 2025 by Kart Krew
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.

View file

@ -1,7 +1,7 @@
// DR. ROBOTNIK'S RING RACERS
//-----------------------------------------------------------------------------
// Copyright (C) 2024 by Ronald "Eidolon" Kinard
// Copyright (C) 2024 by Kart Krew
// Copyright (C) 2025 by Ronald "Eidolon" Kinard
// Copyright (C) 2025 by Kart Krew
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.

View file

@ -1,7 +1,7 @@
// DR. ROBOTNIK'S RING RACERS
//-----------------------------------------------------------------------------
// Copyright (C) 2024 by Ronald "Eidolon" Kinard
// Copyright (C) 2024 by Kart Krew
// Copyright (C) 2025 by Ronald "Eidolon" Kinard
// Copyright (C) 2025 by Kart Krew
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.

View file

@ -1,7 +1,7 @@
// DR. ROBOTNIK'S RING RACERS
//-----------------------------------------------------------------------------
// Copyright (C) 2024 by Ronald "Eidolon" Kinard
// Copyright (C) 2024 by Kart Krew
// Copyright (C) 2025 by Ronald "Eidolon" Kinard
// Copyright (C) 2025 by Kart Krew
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.

View file

@ -1,7 +1,7 @@
// DR. ROBOTNIK'S RING RACERS
//-----------------------------------------------------------------------------
// Copyright (C) 2024 by Ronald "Eidolon" Kinard
// Copyright (C) 2024 by Kart Krew
// Copyright (C) 2025 by Ronald "Eidolon" Kinard
// Copyright (C) 2025 by Kart Krew
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.

View file

@ -1,7 +1,7 @@
// DR. ROBOTNIK'S RING RACERS
//-----------------------------------------------------------------------------
// Copyright (C) 2024 by Ronald "Eidolon" Kinard
// Copyright (C) 2024 by Kart Krew
// Copyright (C) 2025 by Ronald "Eidolon" Kinard
// Copyright (C) 2025 by Kart Krew
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.

View file

@ -1,7 +1,7 @@
// DR. ROBOTNIK'S RING RACERS
//-----------------------------------------------------------------------------
// Copyright (C) 2024 by Ronald "Eidolon" Kinard
// Copyright (C) 2024 by Kart Krew
// Copyright (C) 2025 by Ronald "Eidolon" Kinard
// Copyright (C) 2025 by Kart Krew
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.

View file

@ -1,7 +1,7 @@
// DR. ROBOTNIK'S RING RACERS
//-----------------------------------------------------------------------------
// Copyright (C) 2024 by Ronald "Eidolon" Kinard
// Copyright (C) 2024 by Kart Krew
// Copyright (C) 2025 by Ronald "Eidolon" Kinard
// Copyright (C) 2025 by Kart Krew
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
@ -126,9 +126,9 @@ void visit_tag(Visitor& visitor, io::SpanStream& stream, const TagHeader& header
stream.seek(io::SeekFrom::kStart, dest);
}
std::vector<uint8_t> read_uint8_samples_from_stream(io::SpanStream& stream, std::size_t count)
Vector<uint8_t> read_uint8_samples_from_stream(io::SpanStream& stream, std::size_t count)
{
std::vector<uint8_t> samples;
Vector<uint8_t> samples;
samples.reserve(count);
for (std::size_t i = 0; i < count; i++)
{
@ -137,9 +137,9 @@ std::vector<uint8_t> read_uint8_samples_from_stream(io::SpanStream& stream, std:
return samples;
}
std::vector<int16_t> read_int16_samples_from_stream(io::SpanStream& stream, std::size_t count)
Vector<int16_t> read_int16_samples_from_stream(io::SpanStream& stream, std::size_t count)
{
std::vector<int16_t> samples;
Vector<int16_t> samples;
samples.reserve(count);
for (std::size_t i = 0; i < count; i++)
{
@ -177,7 +177,7 @@ Wav::Wav(tcb::span<std::byte> data)
}
std::optional<FmtTag> read_fmt;
std::variant<std::vector<uint8_t>, std::vector<int16_t>> interleaved_samples;
std::variant<Vector<uint8_t>, Vector<int16_t>> interleaved_samples;
while (stream.seek(io::SeekFrom::kCurrent, 0) < riff_end)
{
@ -247,7 +247,7 @@ template <typename T>
std::size_t read_samples(
std::size_t channels,
std::size_t offset,
const std::vector<T>& samples,
const Vector<T>& samples,
tcb::span<audio::Sample<1>> buffer
) noexcept
{
@ -281,8 +281,8 @@ std::size_t read_samples(
std::size_t Wav::get_samples(std::size_t offset, tcb::span<audio::Sample<1>> buffer) const noexcept
{
auto samples_visitor = srb2::Overload {
[&](const std::vector<uint8_t>& samples) { return read_samples<uint8_t>(channels(), offset, samples, buffer); },
[&](const std::vector<int16_t>& samples)
[&](const Vector<uint8_t>& samples) { return read_samples<uint8_t>(channels(), offset, samples, buffer); },
[&](const Vector<int16_t>& samples)
{ return read_samples<int16_t>(channels(), offset, samples, buffer); }};
return std::visit(samples_visitor, interleaved_samples_);
@ -291,7 +291,7 @@ std::size_t Wav::get_samples(std::size_t offset, tcb::span<audio::Sample<1>> buf
std::size_t Wav::interleaved_length() const noexcept
{
auto samples_visitor = srb2::Overload {
[](const std::vector<uint8_t>& samples) { return samples.size(); },
[](const std::vector<int16_t>& samples) { return samples.size(); }};
[](const Vector<uint8_t>& samples) { return samples.size(); },
[](const Vector<int16_t>& samples) { return samples.size(); }};
return std::visit(samples_visitor, interleaved_samples_);
}

View file

@ -1,7 +1,7 @@
// DR. ROBOTNIK'S RING RACERS
//-----------------------------------------------------------------------------
// Copyright (C) 2024 by Ronald "Eidolon" Kinard
// Copyright (C) 2024 by Kart Krew
// Copyright (C) 2025 by Ronald "Eidolon" Kinard
// Copyright (C) 2025 by Kart Krew
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
@ -15,10 +15,10 @@
#include <cstdint>
#include <type_traits>
#include <variant>
#include <vector>
#include <tcb/span.hpp>
#include "../core/vector.hpp"
#include "../io/streams.hpp"
#include "sample.hpp"
@ -27,7 +27,7 @@ namespace srb2::audio
class Wav final
{
std::variant<std::vector<uint8_t>, std::vector<int16_t>> interleaved_samples_;
std::variant<Vector<uint8_t>, Vector<int16_t>> interleaved_samples_;
std::size_t channels_ = 1;
std::size_t sample_rate_ = 44100;
@ -46,7 +46,7 @@ public:
template <typename I, typename std::enable_if_t<srb2::io::IsInputStreamV<I>, int> = 0>
inline Wav load_wav(I& stream)
{
std::vector<std::byte> data = srb2::io::read_to_vec(stream);
Vector<std::byte> data = srb2::io::read_to_vec(stream);
return Wav {data};
}

View file

@ -1,7 +1,7 @@
// DR. ROBOTNIK'S RING RACERS
//-----------------------------------------------------------------------------
// Copyright (C) 2024 by Ronald "Eidolon" Kinard
// Copyright (C) 2024 by Kart Krew
// Copyright (C) 2025 by Ronald "Eidolon" Kinard
// Copyright (C) 2025 by Kart Krew
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.

View file

@ -1,7 +1,7 @@
// DR. ROBOTNIK'S RING RACERS
//-----------------------------------------------------------------------------
// Copyright (C) 2024 by Ronald "Eidolon" Kinard
// Copyright (C) 2024 by Kart Krew
// Copyright (C) 2025 by Ronald "Eidolon" Kinard
// Copyright (C) 2025 by Kart Krew
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.

View file

@ -1,7 +1,7 @@
// DR. ROBOTNIK'S RING RACERS
//-----------------------------------------------------------------------------
// Copyright (C) 2024 by Ronald "Eidolon" Kinard
// Copyright (C) 2024 by Kart Krew
// Copyright (C) 2025 by Ronald "Eidolon" Kinard
// Copyright (C) 2025 by Kart Krew
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
@ -50,7 +50,7 @@ Xmp<C>::Xmp() : data_(), instance_(nullptr), module_loaded_(false), looping_(fal
}
template <size_t C>
Xmp<C>::Xmp(std::vector<std::byte> data)
Xmp<C>::Xmp(Vector<std::byte> data)
: data_(std::move(data)), instance_(nullptr), module_loaded_(false), looping_(false)
{
_init();

View file

@ -1,7 +1,7 @@
// DR. ROBOTNIK'S RING RACERS
//-----------------------------------------------------------------------------
// Copyright (C) 2024 by Ronald "Eidolon" Kinard
// Copyright (C) 2024 by Kart Krew
// Copyright (C) 2025 by Ronald "Eidolon" Kinard
// Copyright (C) 2025 by Kart Krew
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
@ -15,11 +15,11 @@
#include <cstddef>
#include <exception>
#include <utility>
#include <vector>
#include <tcb/span.hpp>
#include <xmp.h>
#include "../core/vector.hpp"
#include "../io/streams.hpp"
namespace srb2::audio
@ -37,7 +37,7 @@ public:
template <size_t C>
class Xmp final
{
std::vector<std::byte> data_;
Vector<std::byte> data_;
xmp_context instance_;
bool module_loaded_;
bool looping_;
@ -45,7 +45,7 @@ class Xmp final
public:
Xmp();
explicit Xmp(std::vector<std::byte> data);
explicit Xmp(Vector<std::byte> data);
explicit Xmp(tcb::span<std::byte> data);
Xmp(const Xmp<C>&) = delete;
@ -74,7 +74,7 @@ extern template class Xmp<2>;
template <size_t C, typename I, typename std::enable_if_t<srb2::io::IsInputStreamV<I>, int> = 0>
inline Xmp<C> load_xmp(I& stream)
{
std::vector<std::byte> data = srb2::io::read_to_vec(stream);
Vector<std::byte> data = srb2::io::read_to_vec(stream);
return Xmp<C> {std::move(data)};
}

View file

@ -1,7 +1,7 @@
// DR. ROBOTNIK'S RING RACERS
//-----------------------------------------------------------------------------
// Copyright (C) 2024 by Ronald "Eidolon" Kinard
// Copyright (C) 2024 by Kart Krew
// Copyright (C) 2025 by Ronald "Eidolon" Kinard
// Copyright (C) 2025 by Kart Krew
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
@ -12,6 +12,8 @@
#include <cmath>
#include "../core/vector.hpp"
using namespace srb2;
using namespace srb2::audio;

View file

@ -1,7 +1,7 @@
// DR. ROBOTNIK'S RING RACERS
//-----------------------------------------------------------------------------
// Copyright (C) 2024 by Ronald "Eidolon" Kinard
// Copyright (C) 2024 by Kart Krew
// Copyright (C) 2025 by Ronald "Eidolon" Kinard
// Copyright (C) 2025 by Kart Krew
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
@ -14,6 +14,8 @@
#include "source.hpp"
#include "xmp.hpp"
#include "../core/vector.hpp"
namespace srb2::audio
{
@ -21,7 +23,7 @@ template <size_t C>
class XmpPlayer final : public Source<C>
{
Xmp<C> xmp_;
std::vector<std::array<int16_t, C>> buf_;
srb2::Vector<std::array<int16_t, C>> buf_;
public:
XmpPlayer(Xmp<C>&& xmp);

View file

@ -1,6 +1,6 @@
// DR. ROBOTNIK'S RING RACERS
//-----------------------------------------------------------------------------
// Copyright (C) 2024 by Kart Krew.
// Copyright (C) 2025 by Kart Krew.
// Copyright (C) 2020 by Sonic Team Junior.
// Copyright (C) 2000 by DooM Legacy Team.
//

View file

@ -1,6 +1,6 @@
// DR. ROBOTNIK'S RING RACERS
//-----------------------------------------------------------------------------
// Copyright (C) 2024 by Kart Krew.
// Copyright (C) 2025 by Kart Krew.
// Copyright (C) 2020 by Sonic Team Junior.
// Copyright (C) 2000 by DooM Legacy Team.
//
@ -102,6 +102,18 @@ CV_PossibleValue_t gpdifficulty_cons_t[] = {
{KARTGP_MASTER, "Master"},
{0, NULL}
};
CV_PossibleValue_t descriptiveinput_cons_t[] = {
{0, "\"Emulator\""},
{1, "Modern"},
{2, "Modern Flip"},
{3, "6Bt. (Auto)"},
{4, "6Bt. (A)"},
{5, "6Bt. (B)"},
{6, "6Bt. (C)"},
{7, "6Bt. (D)"},
{8, "6Bt. (E)"},
{0, NULL}
};
// Filter consvars by EXECVERSION
// First implementation is 2 (1.0.2), so earlier configs default at 1 (1.0.0)
@ -855,8 +867,19 @@ static void COM_Exec_f(void)
if (!COM_CheckParm("-silent"))
CONS_Printf(M_GetText("executing %s\n"), COM_Argv(1));
// insert text file into the command buffer
COM_ImmedExecute((char *)buf);
if (COM_CheckParm("-immediate"))
{
// immediately parses and executes all lines
// sidesteps wait from all sources, even self
COM_ImmedExecute((char *)buf);
}
else
{
// insert text file into the command buffer
// delays execution if interpreting wait cmd
COM_BufAddTextEx((char *)buf, com_flags);
COM_BufAddTextEx("\n", com_flags);
}
// free buffer
Z_Free(buf);

View file

@ -1,6 +1,6 @@
// DR. ROBOTNIK'S RING RACERS
//-----------------------------------------------------------------------------
// Copyright (C) 2024 by Kart Krew.
// Copyright (C) 2025 by Kart Krew.
// Copyright (C) 2020 by Sonic Team Junior.
// Copyright (C) 2000 by DooM Legacy Team.
//
@ -233,7 +233,7 @@ extern CV_PossibleValue_t CV_TrueFalse[];
// SRB2kart
// the KARTSPEED and KARTGP were previously defined here, but moved to doomstat to avoid circular dependencies
extern CV_PossibleValue_t kartspeed_cons_t[], dummykartspeed_cons_t[], gpdifficulty_cons_t[];
extern CV_PossibleValue_t kartspeed_cons_t[], dummykartspeed_cons_t[], gpdifficulty_cons_t[], descriptiveinput_cons_t[];
extern consvar_t cv_cheats;
extern consvar_t cv_execversion;

View file

@ -1,6 +1,6 @@
// DR. ROBOTNIK'S RING RACERS
//-----------------------------------------------------------------------------
// Copyright (C) 2024 by Kart Krew.
// Copyright (C) 2025 by Kart Krew.
// Copyright (C) 2020 by Sonic Team Junior.
//
// This program is free software distributed under the

View file

@ -1,6 +1,6 @@
// DR. ROBOTNIK'S RING RACERS
//-----------------------------------------------------------------------------
// Copyright (C) 2024 by Kart Krew.
// Copyright (C) 2025 by Kart Krew.
// Copyright (C) 2020 by Sonic Team Junior.
// Copyright (C) 2000 by DooM Legacy Team.
//

View file

@ -1,6 +1,6 @@
// DR. ROBOTNIK'S RING RACERS
//-----------------------------------------------------------------------------
// Copyright (C) 2024 by Kart Krew.
// Copyright (C) 2025 by Kart Krew.
// Copyright (C) 2020 by Sonic Team Junior.
// Copyright (C) 2000 by DooM Legacy Team.
//

View file

@ -1,8 +1,17 @@
target_sources(SRB2SDL2 PRIVATE
hash_map.hpp
hash_set.cpp
hash_set.hpp
json.cpp
json.hpp
memory.cpp
memory.h
spmc_queue.hpp
static_vec.hpp
string.cpp
string.h
thread_pool.cpp
thread_pool.h
vector.cpp
vector.hpp
)

687
src/core/hash_map.hpp Normal file
View file

@ -0,0 +1,687 @@
// DR. ROBOTNIK'S RING RACERS
//-----------------------------------------------------------------------------
// Copyright (C) 2025 by Ronald "Eidolon" Kinard
// Copyright (C) 2025 by Kart Krew
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
// See the 'LICENSE' file for more details.
//-----------------------------------------------------------------------------
#ifndef SRB2_CORE_HASH_MAP_HPP
#define SRB2_CORE_HASH_MAP_HPP
#include <algorithm>
#include <cstdint>
#include <functional>
#include <initializer_list>
#include <memory>
#include <stdexcept>
#include <utility>
#include "../cxxutil.hpp"
namespace srb2
{
template <typename V>
class HashSet;
template <typename K, typename V>
class HashMap
{
struct Elem;
using Hasher = std::hash<K>;
using KeyEqual = std::equal_to<K>;
public:
using Entry = std::pair<K, V>;
class ConstIter;
class Iter
{
const HashMap* self_;
uint32_t bucket_;
Elem* cur_;
Iter(const HashMap* self, uint32_t bucket, Elem* cur)
: self_(self)
, bucket_(bucket)
, cur_(cur)
{}
Iter(const ConstIter& r)
: self_(r.iter_.self_)
, bucket_(r.iter_.bucket_)
, cur_(r.iter_.cur_)
{}
friend class HashMap;
friend class HashSet<K>;
friend class ConstIter;
public:
Iter() : Iter(nullptr, 0, nullptr) {}
Iter(const Iter&) = default;
Iter(Iter&&) noexcept = default;
~Iter() = default;
Iter& operator=(const Iter&) = default;
Iter& operator=(Iter&&) noexcept = default;
Entry& operator*() const noexcept { return cur_->entry; }
Entry* operator->() const noexcept { return &cur_->entry; }
bool operator==(const Iter& r) const noexcept
{
return self_ == r.self_ && bucket_ == r.bucket_ && cur_ == r.cur_;
}
bool operator!=(const Iter& r) const noexcept { return !(*this == r); }
Iter& operator++()
{
if (cur_ == nullptr)
{
return *this;
}
if (cur_->next == nullptr)
{
do
{
if (bucket_ < self_->buckets_ - 1)
{
bucket_++;
cur_ = self_->heads_[bucket_];
}
else
{
self_ = nullptr;
bucket_ = 0;
cur_ = nullptr;
return *this;
}
} while (cur_ == nullptr);
}
else
{
cur_ = cur_->next;
}
return *this;
}
Iter operator++(int)
{
Iter itr = *this;
++(*this);
return itr;
}
};
class ConstIter
{
mutable Iter iter_;
friend class HashMap;
public:
ConstIter() : iter_() {}
ConstIter(const ConstIter&) = default;
ConstIter(ConstIter&&) noexcept = default;
~ConstIter() = default;
ConstIter& operator=(const ConstIter&) = default;
ConstIter& operator=(ConstIter&&) noexcept = default;
ConstIter(const Iter& iter) : iter_(iter) {}
const Entry& operator*() const noexcept { return iter_.cur_->entry; }
const Entry* operator->() const noexcept { return &iter_.cur_->entry; }
bool operator==(const ConstIter& r) const noexcept { return iter_ == r.iter_; }
bool operator!=(const ConstIter& r) const noexcept { return !(*this == r); }
ConstIter& operator++() noexcept
{
++iter_;
return *this;
}
ConstIter operator++(int) noexcept
{
ConstIter itr = *this;
++*this;
return itr;
}
};
// iter traits
using key_type = K;
using mapped_type = V;
using value_type = Entry;
using size_type = uint32_t;
using difference_type = int64_t;
using hasher = Hasher;
using key_equal = KeyEqual;
using reference = Entry&;
using const_reference = const Entry&;
using pointer = Entry*;
using const_pointer = const Entry*;
using iterator = Iter;
using const_iterator = ConstIter;
private:
struct Elem
{
Elem* prev;
Elem* next;
Entry entry;
};
Elem** heads_ = nullptr;
size_t size_ = 0;
uint32_t buckets_;
Hasher hasher_;
KeyEqual key_equal_;
constexpr static uint32_t kDefaultBuckets = 16;
void init_buckets()
{
if (buckets_ == 0)
{
buckets_ = kDefaultBuckets;
}
std::allocator<Elem*> allocator;
heads_ = allocator.allocate(buckets_);
for (uint32_t i = 0; i < buckets_; i++)
{
heads_[i] = nullptr;
}
}
void init_if_needed()
{
if (heads_ == nullptr)
{
init_buckets();
}
}
void rehash_if_needed(size_t target_size)
{
if (target_size >= buckets_)
{
rehash(std::max<size_t>(target_size, buckets_ * 2));
}
}
friend class Iter;
friend class ConstIter;
public:
HashMap() : heads_(nullptr), size_(0), buckets_(0), hasher_(), key_equal_()
{
}
HashMap(uint32_t buckets)
: heads_(nullptr)
, size_(0)
, buckets_(buckets)
, hasher_()
, key_equal_()
{
init_buckets();
}
HashMap(const HashMap& r)
{
*this = r;
}
HashMap(HashMap&& r) noexcept
{
buckets_ = r.buckets_;
r.buckets_ = 0;
size_ = r.size_;
r.size_ = 0;
heads_ = r.heads_;
r.heads_ = nullptr;
hasher_ = r.hasher_;
r.hasher_ = {};
key_equal_ = r.key_equal_;
r.key_equal_ = {};
};
~HashMap()
{
clear();
}
HashMap(std::initializer_list<Entry> list) : HashMap(list.size())
{
for (auto v : list)
{
insert(v);
}
}
HashMap& operator=(const HashMap& r)
{
clear();
buckets_ = r.buckets_;
if (buckets_ == 0)
{
return *this;
}
init_buckets();
for (auto itr = r.begin(); itr != r.end(); itr++)
{
insert({itr->first, itr->second});
}
return *this;
}
HashMap& operator=(HashMap&& r) noexcept
{
std::swap(buckets_, r.buckets_);
std::swap(size_, r.size_);
std::swap(heads_, r.heads_);
std::swap(hasher_, r.hasher_);
std::swap(key_equal_, r.key_equal_);
return *this;
};
constexpr bool empty() const noexcept { return size_ == 0; }
constexpr size_t size() const noexcept { return size_; }
constexpr uint32_t buckets() const noexcept { return buckets_; }
Iter begin() noexcept
{
if (size_ == 0)
{
return end();
}
Iter ret = end();
for (uint32_t i = 0; i < buckets_; i++)
{
Elem* ptr = heads_[i];
if (ptr != nullptr)
{
ret = Iter { this, i, ptr };
break;
}
}
return ret;
}
ConstIter cbegin() const noexcept
{
ConstIter ret = end();
for (uint32_t i = 0; i < buckets_; i++)
{
Elem* ptr = heads_[i];
if (ptr != nullptr)
{
ret = ConstIter { Iter { this, i, ptr } };
break;
}
}
return ret;
}
ConstIter begin() const noexcept { return cbegin(); }
constexpr Iter end() noexcept { return Iter(); }
constexpr ConstIter cend() const noexcept { return ConstIter(); }
constexpr ConstIter end() const noexcept { return cend(); }
void clear()
{
if (heads_)
{
std::allocator<Elem> elem_allocator;
for (uint32_t i = 0; i < buckets_; i++)
{
auto itr = heads_[i];
while (itr != nullptr)
{
auto nextitr = itr->next;
itr->~Elem();
elem_allocator.deallocate(itr, 1);
itr = nextitr;
}
}
std::allocator<Elem*> buckets_allocator;
buckets_allocator.deallocate(heads_, buckets_);
}
heads_ = nullptr;
size_ = 0;
}
Iter find(const K& key)
{
if (buckets_ == 0 || heads_ == nullptr)
{
return end();
}
uint32_t bucket = (hasher_)(key) % buckets_;
for (Elem* p = heads_[bucket]; p != nullptr; p = p->next)
{
if ((key_equal_)(p->entry.first, key))
{
return Iter { this, bucket, p };
}
};
return end();
}
ConstIter find(const K& key) const
{
Iter iter = const_cast<HashMap*>(this)->find(key);
return ConstIter { iter };
}
std::pair<Iter, bool> insert(const Entry& value)
{
Entry copy = value;
return insert(std::move(copy));
}
void rehash(uint32_t count)
{
count = size_ > count ? size_ : count;
HashMap rehashed { count };
for (Iter itr = begin(); itr != end();)
{
Iter itrcopy = itr;
++itr;
uint32_t oldbucket = itrcopy.bucket_;
if (heads_[oldbucket] == itrcopy.cur_)
{
heads_[oldbucket] = nullptr;
}
itrcopy.self_ = &rehashed;
itrcopy.bucket_ = (rehashed.hasher_)(itrcopy.cur_->entry.first) % count;
Elem* p = rehashed.heads_[itrcopy.bucket_];
if (p == nullptr)
{
p = rehashed.heads_[itrcopy.bucket_] = itrcopy.cur_;
size_ -= 1;
rehashed.size_ += 1;
if (p->next)
{
p->next->prev = nullptr;
}
if (p->prev)
{
p->prev->next = nullptr;
}
p->next = nullptr;
p->prev = nullptr;
}
else
{
for (; p != nullptr; p = p->next)
{
if (p->next != nullptr)
{
continue;
}
p->next = itrcopy.cur_;
size_ -= 1;
rehashed.size_ += 1;
p->next->prev = p;
p->next->next = nullptr;
break;
}
}
}
if (heads_)
{
std::allocator<Elem*> buckets_allocator;
buckets_allocator.deallocate(heads_, buckets_);
heads_ = nullptr;
}
*this = std::move(rehashed);
}
std::pair<Iter, bool> insert(Entry&& value)
{
std::pair<Iter, bool> ret { end(), false };
std::allocator<Elem> allocator;
init_if_needed();
rehash_if_needed(size_ + 1);
uint32_t bucket = (hasher_)(value.first) % buckets_;
Elem* p = heads_[bucket];
if (p == nullptr)
{
// Make a new slot
ret.second = true;
Elem* newslot = allocator.allocate(1);
newslot->prev = nullptr;
newslot->next = nullptr;
heads_[bucket] = newslot;
new (&newslot->entry) Entry { std::move(value) };
size_++;
ret.first = Iter { this, bucket, newslot };
return ret;
}
for(; p != nullptr;)
{
if ((key_equal_)(p->entry.first, value.first))
{
ret.second = false;
ret.first = Iter { this, bucket, p };
return ret;
}
if (p->next == nullptr)
{
// Make a new slot
ret.second = true;
Elem* newslot = allocator.allocate(1);
newslot->prev = p;
newslot->next = nullptr;
p->next = newslot;
new (&newslot->entry) Entry { std::move(value) };
size_++;
ret.first = Iter { this, bucket, newslot };
return ret;
}
p = p->next;
}
return ret;
}
template <typename M>
std::pair<Iter, bool> insert_or_assign(const K& key, M&& value)
{
K kcopy = key;
return insert_or_assign(std::move(kcopy), std::forward<M>(value));
}
template <typename M>
std::pair<Iter, bool> insert_or_assign(K&& key, M&& value)
{
std::pair<Iter, bool> ret { find(key), false };
if (ret.first != end())
{
ret.first->second = std::forward<M>(value);
}
else
{
ret = insert({ std::move(key), std::forward<M>(value) });
}
return ret;
}
template <typename ...Args>
std::pair<Iter, bool> emplace(Args&&... args)
{
Entry entry { std::forward<Args>(args)... };
return insert(std::move(entry));
}
template <typename ...Args>
std::pair<Iter, bool> try_emplace(const K& key, Args&&... args)
{
Iter itr = find(key);
if (itr != end())
{
return { itr, false };
}
return insert({ key, V(std::forward<Args>(args)...) });
}
template <typename ...Args>
std::pair<Iter, bool> try_emplace(K&& key, Args... args)
{
std::pair<Iter, bool> ret { end(), false };
return insert({ std::move(key), V(std::forward<Args>(args)...)});
}
V& operator[](const K& key)
{
K copy { key };
return this->operator[](std::move(copy));
}
V& operator[](K&& key)
{
std::allocator<Elem> allocator;
init_if_needed();
rehash_if_needed(size_ + 1);
uint32_t bucket = (hasher_)(key) % buckets_;
Elem* p = heads_[bucket];
if (p == nullptr)
{
// Make a new slot
Elem* newslot = allocator.allocate(1);
newslot->prev = nullptr;
newslot->next = nullptr;
heads_[bucket] = newslot;
new (&newslot->entry) Entry { std::move(key), {} };
size_++;
return newslot->entry.second;
}
for (; p != nullptr;)
{
if ((key_equal_)(p->entry.first, key))
{
return p->entry.second;
}
if (p->next == nullptr)
{
// Make a new slot
Elem* newslot = allocator.allocate(1);
newslot->prev = p;
newslot->next = nullptr;
p->next = newslot;
new (&newslot->entry) Entry { std::move(key), {} };
size_++;
return newslot->entry.second;
}
p = p->next;
}
return end()->second;
}
V& at(const K& key)
{
auto itr = find(key);
if (itr == end())
{
throw std::out_of_range("key not found");
}
return itr->second;
}
const V& at(const K& key) const
{
auto itr = find(key);
if (itr == cend())
{
throw std::out_of_range("key not found");
}
return itr->second;
}
Iter erase(Iter pos)
{
Iter ret = pos;
if (pos == end())
{
return end();
}
std::allocator<Elem> allocator;
uint32_t bucket = (hasher_)(pos.cur_->entry.first) % buckets_;
Elem* p = heads_[bucket];
for (; p != nullptr;)
{
if ((key_equal_)(p->entry.first, pos.cur_->entry.first))
{
// found it; remove, return next iter
++ret;
if (p->next != nullptr)
{
p->next->prev = p->prev;
}
if (p->prev != nullptr)
{
p->prev->next = p->next;
}
if (p == heads_[bucket])
{
heads_[bucket] = p->next;
}
p->~Elem();
allocator.deallocate(p, 1);
size_ -= 1;
return ret;
}
p = p->next;
}
return ret;
}
Iter erase(ConstIter pos)
{
return erase(pos.iter_);
}
uint32_t erase(const K& key)
{
Iter pos = find(key);
if (pos != end())
{
erase(pos);
return 1;
}
return 0;
}
};
} // namespace srb2
#endif // SRB2_CORE_HASH_MAP_HPP

32
src/core/hash_set.cpp Normal file
View file

@ -0,0 +1,32 @@
// DR. ROBOTNIK'S RING RACERS
//-----------------------------------------------------------------------------
// Copyright (C) 2025 by Ronald "Eidolon" Kinard
// Copyright (C) 2025 by Kart Krew
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
// See the 'LICENSE' file for more details.
//-----------------------------------------------------------------------------
#include "hash_set.hpp"
#include <string>
#include "string.h"
namespace srb2
{
template class HashSet<bool>;
template class HashSet<uint8_t>;
template class HashSet<uint16_t>;
template class HashSet<uint32_t>;
template class HashSet<uint64_t>;
template class HashSet<int8_t>;
template class HashSet<int16_t>;
template class HashSet<int32_t>;
template class HashSet<int64_t>;
template class HashSet<String>;
template class HashSet<std::string>;
} // namespace srb2

214
src/core/hash_set.hpp Normal file
View file

@ -0,0 +1,214 @@
// DR. ROBOTNIK'S RING RACERS
//-----------------------------------------------------------------------------
// Copyright (C) 2025 by Ronald "Eidolon" Kinard
// Copyright (C) 2025 by Kart Krew
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
// See the 'LICENSE' file for more details.
//-----------------------------------------------------------------------------
#ifndef SRB2_CORE_HASH_SET_HPP
#define SRB2_CORE_HASH_SET_HPP
#include <cstdint>
#include <string>
#include "hash_map.hpp"
#include "string.h"
namespace srb2
{
template <typename V>
class HashSet
{
using Inner = HashMap<V, uint8_t>;
public:
class Iter
{
typename Inner::Iter iter_;
Iter(typename Inner::Iter iter) : iter_(iter) {}
friend class HashSet;
friend class ConstIter;
public:
Iter() = default;
Iter(const Iter&) = default;
Iter(Iter&&) noexcept = default;
~Iter() = default;
Iter& operator=(const Iter&) = default;
Iter& operator=(Iter&&) noexcept = default;
bool operator==(const Iter& r) const noexcept { return iter_ == r.iter_; }
bool operator!=(const Iter& r) const noexcept { return !(*this == r); }
V& operator*() const noexcept { return iter_->first; }
V* operator->() const noexcept { return &iter_->first; }
Iter& operator++() noexcept
{
++iter_;
return *this;
}
Iter operator++(int) noexcept
{
Iter self = *this;
++*this;
return self;
}
};
class ConstIter
{
typename Inner::ConstIter iter_;
friend class HashSet;
friend class Iter;
public:
ConstIter() = default;
ConstIter(const ConstIter&) = default;
ConstIter(ConstIter&&) noexcept = default;
~ConstIter() = default;
ConstIter(const Iter& iter) : iter_(iter.iter_) {}
ConstIter(const typename Inner::ConstIter& iter) : iter_(iter) {}
ConstIter& operator=(const ConstIter&) = default;
ConstIter& operator=(ConstIter&&) noexcept = default;
bool operator==(const ConstIter& r) const noexcept { return iter_ == r.iter_; }
bool operator!=(const ConstIter& r) const noexcept { return !(*this == r); }
const V& operator*() const noexcept { return iter_->first; }
const V* operator->() const noexcept { return &iter_->first; }
ConstIter& operator++() noexcept
{
++iter_;
return *this;
}
ConstIter operator++(int) noexcept
{
ConstIter self = *this;
++*this;
return self;
}
};
private:
Inner map_;
public:
using key_type = V;
using value_type = V;
using size_type = typename Inner::size_type;
using difference_type = typename Inner::difference_type;
using hasher = typename Inner::hasher;
using key_equal = typename Inner::key_equal;
using reference = V&;
using const_reference = const V&;
using pointer = V*;
using const_pointer = const V*;
using iterator = Iter;
using const_iterator = ConstIter;
HashSet() = default;
HashSet(const HashSet&) = default;
HashSet(HashSet&&) noexcept = default;
~HashSet() = default;
HashSet& operator=(const HashSet&) = default;
HashSet& operator=(HashSet&&) noexcept = default;
Iter begin() { return map_.begin(); }
Iter end() { return map_.end(); }
ConstIter cbegin() const { return map_.cbegin(); }
ConstIter cend() const { return map_.cend(); }
ConstIter begin() const { return cbegin(); }
ConstIter end() const { return cend(); }
bool empty() const noexcept { return map_.empty(); }
size_t size() const noexcept { return map_.size(); }
void clear() { map_.clear(); }
std::pair<Iter, bool> insert(const V& value)
{
V copy { value };
return insert(std::move(copy));
}
std::pair<Iter, bool> insert(V&& value)
{
return emplace(std::move(value));
}
template <typename ...Args>
std::pair<Iter, bool> emplace(Args&&... args)
{
std::pair<Iter, bool> res;
auto [map_iter, map_inserted] = map_.emplace(std::forward<Args&&>(args)..., 0);
res.first = map_iter;
res.second = map_inserted;
return res;
}
Iter erase(Iter pos)
{
auto map_ret = map_.erase(pos.iter_);
return map_ret;
}
Iter erase(ConstIter pos)
{
auto map_ret = map_.erase(pos.iter_);
return map_ret;
}
Iter erase(ConstIter first, ConstIter last)
{
ConstIter iter;
for (iter = first; iter != last;)
{
iter = erase(iter);
}
return typename Inner::Iter(iter.iter_);
}
Iter find(const V& value)
{
auto map_ret = map_.find(value);
return map_ret;
}
ConstIter find(const V& value) const
{
auto map_ret = map_.find(value);
return map_ret;
}
void rehash(size_t count)
{
map_.rehash(count);
}
};
extern template class HashSet<bool>;
extern template class HashSet<uint8_t>;
extern template class HashSet<uint16_t>;
extern template class HashSet<uint32_t>;
extern template class HashSet<uint64_t>;
extern template class HashSet<int8_t>;
extern template class HashSet<int16_t>;
extern template class HashSet<int32_t>;
extern template class HashSet<int64_t>;
extern template class HashSet<String>;
extern template class HashSet<std::string>;
} // namespace srb2
#endif // SRB2_CORE_HASH_SET_HPP

1809
src/core/json.cpp Normal file

File diff suppressed because it is too large Load diff

533
src/core/json.hpp Normal file
View file

@ -0,0 +1,533 @@
// DR. ROBOTNIK'S RING RACERS
//-----------------------------------------------------------------------------
// Copyright (C) 2025 by Ronald "Eidolon" Kinard
// Copyright (C) 2025 by Kart Krew
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
// See the 'LICENSE' file for more details.
//-----------------------------------------------------------------------------
#ifndef SRB2_CORE_JSON_HPP
#define SRB2_CORE_JSON_HPP
#include <array>
#include <cstdint>
#include <stdexcept>
#include <string>
#include <type_traits>
#include <unordered_map>
#include <vector>
#include <tcb/span.hpp>
#include "hash_map.hpp"
#include "string.h"
#include "vector.hpp"
#include "json_macro.inl"
namespace srb2
{
class JsonValue;
using JsonArray = Vector<JsonValue>;
using JsonObject = HashMap<String, JsonValue>;
class JsonError : public std::runtime_error
{
public:
JsonError(const std::string& what);
JsonError(const char* what);
JsonError(const JsonError&) noexcept;
};
class JsonParseError : public JsonError
{
public:
JsonParseError(const std::string& what);
JsonParseError(const char* what);
JsonParseError(const JsonParseError&) noexcept;
};
class JsonValue
{
public:
enum class Type : int
{
kNull,
kBoolean,
kNumber,
kString,
kArray,
kObject
};
private:
Type type_;
union {
struct {} dummy;
bool boolean_;
double number_;
String string_;
JsonArray array_;
JsonObject object_;
};
static void value_to_ubjson(srb2::Vector<std::byte>& out);
static void value_to_ubjson(srb2::Vector<std::byte>& out, bool value);
static void value_to_ubjson(srb2::Vector<std::byte>& out, double value);
static void value_to_ubjson(srb2::Vector<std::byte>& out, uint64_t value);
static void value_to_ubjson(srb2::Vector<std::byte>& out, const String& value, bool include_type);
static void value_to_ubjson(srb2::Vector<std::byte>& out, const JsonArray& value);
static void value_to_ubjson(srb2::Vector<std::byte>& out, const JsonObject& value);
void do_to_ubjson(srb2::Vector<std::byte>& out) const;
public:
JsonValue();
JsonValue(const JsonValue&);
JsonValue(JsonValue&&) noexcept;
~JsonValue();
JsonValue& operator=(const JsonValue&);
JsonValue& operator=(JsonValue&&) noexcept;
JsonValue(const String& value);
JsonValue(String&& value);
JsonValue(const JsonArray& value);
JsonValue(JsonArray&& value);
JsonValue(const JsonObject& value);
JsonValue(JsonObject&& value);
JsonValue(float value);
JsonValue(double value);
JsonValue(int8_t value);
JsonValue(int16_t value);
JsonValue(int32_t value);
JsonValue(int64_t value);
JsonValue(uint8_t value);
JsonValue(uint16_t value);
JsonValue(uint32_t value);
JsonValue(uint64_t value);
JsonValue(bool value);
static JsonValue array() { return JsonValue(JsonArray()); }
static JsonValue object() { return JsonValue(JsonObject()); }
bool operator==(const JsonValue& rhs) const;
bool operator!=(const JsonValue& rhs) const { return !(*this == rhs); }
void to_json(JsonValue& to) const;
void from_json(const JsonValue& from);
String to_json_string() const;
static JsonValue from_json_string(const String& str);
srb2::Vector<std::byte> to_ubjson() const;
static JsonValue from_ubjson(tcb::span<const std::byte> ubjson);
constexpr Type type() const noexcept { return type_; }
template <typename V> V get() const;
constexpr bool is_null() const noexcept { return type_ == Type::kNull; }
constexpr bool is_boolean() const noexcept { return type_ == Type::kBoolean; }
constexpr bool is_number() const noexcept { return type_ == Type::kNumber; }
constexpr bool is_string() const noexcept { return type_ == Type::kString; }
constexpr bool is_array() const noexcept { return type_ == Type::kArray; }
constexpr bool is_object() const noexcept { return type_ == Type::kObject; }
JsonArray& as_array();
JsonObject& as_object();
const JsonArray& as_array() const;
const JsonObject& as_object() const;
JsonValue& at(uint32_t i);
const JsonValue& at(uint32_t i) const;
JsonValue& at(const char* key);
JsonValue& at(const String& key);
const JsonValue& at(const char* key) const;
const JsonValue& at(const String& key) const;
template <typename V>
V value(const char* key, const V& def) const;
template <typename V>
V value(const String& key, const V& def) const;
template <typename V>
V value(const char* key, V&& def) const;
template <typename V>
V value(const String& key, V&& def) const;
bool contains(const char* key) const;
bool contains(const String& key) const;
JsonValue& operator[](uint32_t i);
JsonValue& operator[](const char* key);
JsonValue& operator[](const String& key);
};
void to_json(JsonValue& to, bool value);
void to_json(JsonValue& to, int8_t value);
void to_json(JsonValue& to, int16_t value);
void to_json(JsonValue& to, int32_t value);
void to_json(JsonValue& to, int64_t value);
void to_json(JsonValue& to, uint8_t value);
void to_json(JsonValue& to, uint16_t value);
void to_json(JsonValue& to, uint32_t value);
void to_json(JsonValue& to, uint64_t value);
void to_json(JsonValue& to, float value);
void to_json(JsonValue& to, double value);
void to_json(JsonValue& to, const String& value);
void to_json(JsonValue& to, const JsonArray& value);
void to_json(JsonValue& to, const JsonObject& value);
void from_json(const JsonValue& to, bool& value);
void from_json(const JsonValue& to, int8_t& value);
void from_json(const JsonValue& to, int16_t& value);
void from_json(const JsonValue& to, int32_t& value);
void from_json(const JsonValue& to, int64_t& value);
void from_json(const JsonValue& to, uint8_t& value);
void from_json(const JsonValue& to, uint16_t& value);
void from_json(const JsonValue& to, uint32_t& value);
void from_json(const JsonValue& to, uint64_t& value);
void from_json(const JsonValue& to, float& value);
void from_json(const JsonValue& to, double& value);
void from_json(const JsonValue& to, String& value);
void from_json(const JsonValue& to, JsonArray& value);
void from_json(const JsonValue& to, JsonObject& value);
template <typename T, size_t S>
inline void to_json(JsonValue& to, const std::array<T, S>& v)
{
JsonArray arr;
for (auto itr = v.begin(); itr != v.end(); itr++)
{
JsonValue conv;
to_json(conv, *itr);
arr.push_back(conv);
}
to = JsonValue(std::move(arr));
}
template <typename T, size_t S>
inline void from_json(const JsonValue& to, std::array<T, S>& v)
{
if (!to.is_array())
{
throw JsonError("json value must be an array");
}
const JsonArray& arr = to.as_array();
size_t si = 0;
for (auto& i : arr)
{
if (si >= v.size())
{
break;
}
T conv;
from_json(i, conv);
v[si] = std::move(conv);
si++;
}
}
template <typename T, typename A>
inline void to_json(JsonValue& to, const std::vector<T, A>& v)
{
JsonArray arr;
for (auto itr = v.begin(); itr != v.end(); itr++)
{
JsonValue conv;
to_json(conv, *itr);
arr.push_back(conv);
}
to = JsonValue(std::move(arr));
}
template <typename T, typename A>
inline void from_json(const JsonValue& to, std::vector<T, A>& v)
{
if (!to.is_array())
{
throw JsonError("json value must be an array");
}
v.clear();
const JsonArray& arr = to.as_array();
for (auto& i : arr)
{
T conv;
from_json(i, conv);
v.push_back(std::move(conv));
}
}
template <typename T>
inline void to_json(JsonValue& to, const srb2::Vector<T>& v)
{
JsonArray arr;
for (auto itr = v.begin(); itr != v.end(); itr++)
{
JsonValue conv;
to_json(conv, *itr);
arr.push_back(conv);
}
to = JsonValue(std::move(arr));
}
template <typename T>
inline void from_json(const JsonValue& to, srb2::Vector<T>& v)
{
if (!to.is_array())
{
throw JsonError("json value must be an array");
}
v.clear();
const JsonArray& arr = to.as_array();
for (auto& i : arr)
{
T conv;
from_json(i, conv);
v.push_back(std::move(conv));
}
}
template <typename K, typename V, typename H, typename E, typename A>
inline void to_json(JsonValue& to, const std::unordered_map<K, V, H, E, A>& v)
{
JsonObject obj;
for (auto itr = v.begin(); itr != v.end(); itr++)
{
to_json(obj[itr->first], itr->second);
}
to = JsonValue(std::move(obj));
}
template <typename K, typename V, typename H, typename E, typename A>
inline void from_json(const JsonValue& to, std::unordered_map<K, V, H, E, A>& v)
{
if (!to.is_object())
{
throw JsonError("json value must be an object");
}
v.clear();
const JsonObject& obj = to.as_object();
for (auto itr = obj.begin(); itr != obj.end(); itr++)
{
V conv;
from_json(itr->second, conv);
v[itr->first] = std::move(conv);
}
}
template <typename K, typename V>
inline void to_json(JsonValue& to, const srb2::HashMap<K, V>& v)
{
JsonObject obj;
for (auto itr = v.begin(); itr != v.end(); itr++)
{
to_json(obj[itr->first], itr->second);
}
to = JsonValue(std::move(obj));
}
template <typename K, typename V>
inline void from_json(const JsonValue& to, srb2::HashMap<K, V>& v)
{
if (!to.is_object())
{
throw JsonError("json value must be an object");
}
v.clear();
const JsonObject& obj = to.as_object();
for (auto itr = obj.begin(); itr != obj.end(); itr++)
{
V conv;
from_json(itr->second, conv);
v[itr->first] = std::move(conv);
}
}
void from_json(const JsonValue& to, std::string& v);
void to_json(JsonValue& to, const std::string& v);
// template <typename K, typename V>
// inline void to_json(JsonValue& to, const srb2::OAHashMap<K, V>& v)
// {
// JsonObject obj;
// for (auto itr = v.begin(); itr != v.end(); itr++)
// {
// to_json(obj[itr->first], itr->second);
// }
// to = JsonValue(std::move(obj));
// }
// template <typename K, typename V>
// inline void from_json(const JsonValue& to, srb2::OAHashMap<K, V>& v)
// {
// if (!to.is_object())
// {
// throw JsonError("json value must be an object");
// }
// v.clear();
// const JsonObject& obj = to.as_object();
// for (auto itr = obj.begin(); itr != obj.end(); itr++)
// {
// V conv;
// from_json(itr->second, conv);
// v[itr->first] = std::move(conv);
// }
// }
//
template <typename V>
inline V JsonValue::get() const
{
V v;
from_json(*this, v);
return v;
}
template <typename V>
inline V JsonValue::value(const char* key, const V& def) const
{
V copy { def };
return value(key, std::move(copy));
}
template <typename V>
inline V JsonValue::value(const String& key, const V& def) const
{
return value(key.c_str(), def);
}
template <typename V>
inline V JsonValue::value(const char* key, V&& def) const
{
const JsonObject& obj = as_object();
auto itr = obj.find(key);
if (itr != obj.end())
{
return itr->second.get<V>();
}
return def;
}
template <> bool JsonValue::get() const;
template <> int8_t JsonValue::get() const;
template <> int16_t JsonValue::get() const;
template <> int32_t JsonValue::get() const;
template <> int64_t JsonValue::get() const;
template <> uint8_t JsonValue::get() const;
template <> uint16_t JsonValue::get() const;
template <> uint32_t JsonValue::get() const;
template <> uint64_t JsonValue::get() const;
template <> float JsonValue::get() const;
template <> double JsonValue::get() const;
template <> String JsonValue::get() const;
template <> std::string JsonValue::get() const;
template <> std::string_view JsonValue::get() const;
template <> JsonArray JsonValue::get() const;
template <> JsonObject JsonValue::get() const;
template <> JsonValue JsonValue::get() const;
inline bool operator==(const JsonValue& lhs, bool rhs)
{
if (!lhs.is_boolean())
{
return false;
}
return lhs.get<bool>() == rhs;
}
inline bool operator==(const JsonValue& lhs, int64_t rhs)
{
if (!lhs.is_number())
{
return false;
}
return lhs.get<int64_t>() == rhs;
}
inline bool operator==(const JsonValue& lhs, uint64_t rhs)
{
if (!lhs.is_number())
{
return false;
}
return lhs.get<uint64_t>() == rhs;
}
inline bool operator==(const JsonValue& lhs, double rhs)
{
if (!lhs.is_number())
{
return false;
}
return lhs.get<double>() == rhs;
}
inline bool operator==(const JsonValue& lhs, std::string_view rhs)
{
if (!lhs.is_string())
{
return false;
}
return lhs.get<std::string_view>() == rhs;
}
inline bool operator==(const JsonValue& lhs, const JsonArray& rhs)
{
if (!lhs.is_array())
{
return false;
}
return lhs.as_array() == rhs;
}
inline bool operator==(const JsonValue& lhs, const JsonObject& rhs)
{
if (!lhs.is_object())
{
return false;
}
return lhs.as_object() == rhs;
}
inline bool operator!=(const JsonValue& lhs, bool rhs)
{
return !(lhs == rhs);
}
inline bool operator!=(const JsonValue& lhs, int64_t rhs)
{
return !(lhs == rhs);
}
inline bool operator!=(const JsonValue& lhs, uint64_t rhs)
{
return !(lhs == rhs);
}
inline bool operator!=(const JsonValue& lhs, double rhs)
{
return !(lhs == rhs);
}
inline bool operator!=(const JsonValue& lhs, std::string_view rhs)
{
return !(lhs == rhs);
}
inline bool operator!=(const JsonValue& lhs, const JsonArray& rhs)
{
return !(lhs == rhs);
}
inline bool operator!=(const JsonValue& lhs, const JsonObject& rhs)
{
return !(lhs == rhs);
}
extern template class Vector<srb2::JsonValue>;
extern template class HashMap<String, srb2::JsonValue>;
} // namespace srb2
#endif // SRB2_CORE_JSON_HPP

185
src/core/json_macro.inl Normal file
View file

@ -0,0 +1,185 @@
// __ _____ _____ _____
// __| | __| | | | JSON for Modern C++
// | | |__ | | | | | | version 3.11.3
// |_____|_____|_____|_|___| https://github.com/nlohmann/json
//
// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>
// SPDX-FileCopyrightText: 2016-2021 Evan Nemerson <evan@nemerson.com>
// SPDX-License-Identifier: MIT
// file: macro_scope.hpp
// This file is derived from nlohmman json's codegen macros and thus is provided under its license.
#define SRB2_JSON_EXPAND( x ) x
#define SRB2_JSON_GET_MACRO(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, NAME,...) NAME
#define SRB2_JSON_PASTE(...) SRB2_JSON_EXPAND(SRB2_JSON_GET_MACRO(__VA_ARGS__, \
SRB2_JSON_PASTE64, \
SRB2_JSON_PASTE63, \
SRB2_JSON_PASTE62, \
SRB2_JSON_PASTE61, \
SRB2_JSON_PASTE60, \
SRB2_JSON_PASTE59, \
SRB2_JSON_PASTE58, \
SRB2_JSON_PASTE57, \
SRB2_JSON_PASTE56, \
SRB2_JSON_PASTE55, \
SRB2_JSON_PASTE54, \
SRB2_JSON_PASTE53, \
SRB2_JSON_PASTE52, \
SRB2_JSON_PASTE51, \
SRB2_JSON_PASTE50, \
SRB2_JSON_PASTE49, \
SRB2_JSON_PASTE48, \
SRB2_JSON_PASTE47, \
SRB2_JSON_PASTE46, \
SRB2_JSON_PASTE45, \
SRB2_JSON_PASTE44, \
SRB2_JSON_PASTE43, \
SRB2_JSON_PASTE42, \
SRB2_JSON_PASTE41, \
SRB2_JSON_PASTE40, \
SRB2_JSON_PASTE39, \
SRB2_JSON_PASTE38, \
SRB2_JSON_PASTE37, \
SRB2_JSON_PASTE36, \
SRB2_JSON_PASTE35, \
SRB2_JSON_PASTE34, \
SRB2_JSON_PASTE33, \
SRB2_JSON_PASTE32, \
SRB2_JSON_PASTE31, \
SRB2_JSON_PASTE30, \
SRB2_JSON_PASTE29, \
SRB2_JSON_PASTE28, \
SRB2_JSON_PASTE27, \
SRB2_JSON_PASTE26, \
SRB2_JSON_PASTE25, \
SRB2_JSON_PASTE24, \
SRB2_JSON_PASTE23, \
SRB2_JSON_PASTE22, \
SRB2_JSON_PASTE21, \
SRB2_JSON_PASTE20, \
SRB2_JSON_PASTE19, \
SRB2_JSON_PASTE18, \
SRB2_JSON_PASTE17, \
SRB2_JSON_PASTE16, \
SRB2_JSON_PASTE15, \
SRB2_JSON_PASTE14, \
SRB2_JSON_PASTE13, \
SRB2_JSON_PASTE12, \
SRB2_JSON_PASTE11, \
SRB2_JSON_PASTE10, \
SRB2_JSON_PASTE9, \
SRB2_JSON_PASTE8, \
SRB2_JSON_PASTE7, \
SRB2_JSON_PASTE6, \
SRB2_JSON_PASTE5, \
SRB2_JSON_PASTE4, \
SRB2_JSON_PASTE3, \
SRB2_JSON_PASTE2, \
SRB2_JSON_PASTE1)(__VA_ARGS__))
#define SRB2_JSON_PASTE2(func, v1) func(v1)
#define SRB2_JSON_PASTE3(func, v1, v2) SRB2_JSON_PASTE2(func, v1) SRB2_JSON_PASTE2(func, v2)
#define SRB2_JSON_PASTE4(func, v1, v2, v3) SRB2_JSON_PASTE2(func, v1) SRB2_JSON_PASTE3(func, v2, v3)
#define SRB2_JSON_PASTE5(func, v1, v2, v3, v4) SRB2_JSON_PASTE2(func, v1) SRB2_JSON_PASTE4(func, v2, v3, v4)
#define SRB2_JSON_PASTE6(func, v1, v2, v3, v4, v5) SRB2_JSON_PASTE2(func, v1) SRB2_JSON_PASTE5(func, v2, v3, v4, v5)
#define SRB2_JSON_PASTE7(func, v1, v2, v3, v4, v5, v6) SRB2_JSON_PASTE2(func, v1) SRB2_JSON_PASTE6(func, v2, v3, v4, v5, v6)
#define SRB2_JSON_PASTE8(func, v1, v2, v3, v4, v5, v6, v7) SRB2_JSON_PASTE2(func, v1) SRB2_JSON_PASTE7(func, v2, v3, v4, v5, v6, v7)
#define SRB2_JSON_PASTE9(func, v1, v2, v3, v4, v5, v6, v7, v8) SRB2_JSON_PASTE2(func, v1) SRB2_JSON_PASTE8(func, v2, v3, v4, v5, v6, v7, v8)
#define SRB2_JSON_PASTE10(func, v1, v2, v3, v4, v5, v6, v7, v8, v9) SRB2_JSON_PASTE2(func, v1) SRB2_JSON_PASTE9(func, v2, v3, v4, v5, v6, v7, v8, v9)
#define SRB2_JSON_PASTE11(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10) SRB2_JSON_PASTE2(func, v1) SRB2_JSON_PASTE10(func, v2, v3, v4, v5, v6, v7, v8, v9, v10)
#define SRB2_JSON_PASTE12(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11) SRB2_JSON_PASTE2(func, v1) SRB2_JSON_PASTE11(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11)
#define SRB2_JSON_PASTE13(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12) SRB2_JSON_PASTE2(func, v1) SRB2_JSON_PASTE12(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12)
#define SRB2_JSON_PASTE14(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13) SRB2_JSON_PASTE2(func, v1) SRB2_JSON_PASTE13(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13)
#define SRB2_JSON_PASTE15(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14) SRB2_JSON_PASTE2(func, v1) SRB2_JSON_PASTE14(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14)
#define SRB2_JSON_PASTE16(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15) SRB2_JSON_PASTE2(func, v1) SRB2_JSON_PASTE15(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15)
#define SRB2_JSON_PASTE17(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16) SRB2_JSON_PASTE2(func, v1) SRB2_JSON_PASTE16(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16)
#define SRB2_JSON_PASTE18(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17) SRB2_JSON_PASTE2(func, v1) SRB2_JSON_PASTE17(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17)
#define SRB2_JSON_PASTE19(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18) SRB2_JSON_PASTE2(func, v1) SRB2_JSON_PASTE18(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18)
#define SRB2_JSON_PASTE20(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19) SRB2_JSON_PASTE2(func, v1) SRB2_JSON_PASTE19(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19)
#define SRB2_JSON_PASTE21(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20) SRB2_JSON_PASTE2(func, v1) SRB2_JSON_PASTE20(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20)
#define SRB2_JSON_PASTE22(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21) SRB2_JSON_PASTE2(func, v1) SRB2_JSON_PASTE21(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21)
#define SRB2_JSON_PASTE23(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22) SRB2_JSON_PASTE2(func, v1) SRB2_JSON_PASTE22(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22)
#define SRB2_JSON_PASTE24(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23) SRB2_JSON_PASTE2(func, v1) SRB2_JSON_PASTE23(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23)
#define SRB2_JSON_PASTE25(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24) SRB2_JSON_PASTE2(func, v1) SRB2_JSON_PASTE24(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24)
#define SRB2_JSON_PASTE26(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25) SRB2_JSON_PASTE2(func, v1) SRB2_JSON_PASTE25(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25)
#define SRB2_JSON_PASTE27(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26) SRB2_JSON_PASTE2(func, v1) SRB2_JSON_PASTE26(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26)
#define SRB2_JSON_PASTE28(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27) SRB2_JSON_PASTE2(func, v1) SRB2_JSON_PASTE27(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27)
#define SRB2_JSON_PASTE29(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28) SRB2_JSON_PASTE2(func, v1) SRB2_JSON_PASTE28(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28)
#define SRB2_JSON_PASTE30(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29) SRB2_JSON_PASTE2(func, v1) SRB2_JSON_PASTE29(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29)
#define SRB2_JSON_PASTE31(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30) SRB2_JSON_PASTE2(func, v1) SRB2_JSON_PASTE30(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30)
#define SRB2_JSON_PASTE32(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31) SRB2_JSON_PASTE2(func, v1) SRB2_JSON_PASTE31(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31)
#define SRB2_JSON_PASTE33(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32) SRB2_JSON_PASTE2(func, v1) SRB2_JSON_PASTE32(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32)
#define SRB2_JSON_PASTE34(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33) SRB2_JSON_PASTE2(func, v1) SRB2_JSON_PASTE33(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33)
#define SRB2_JSON_PASTE35(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34) SRB2_JSON_PASTE2(func, v1) SRB2_JSON_PASTE34(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34)
#define SRB2_JSON_PASTE36(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35) SRB2_JSON_PASTE2(func, v1) SRB2_JSON_PASTE35(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35)
#define SRB2_JSON_PASTE37(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36) SRB2_JSON_PASTE2(func, v1) SRB2_JSON_PASTE36(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36)
#define SRB2_JSON_PASTE38(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37) SRB2_JSON_PASTE2(func, v1) SRB2_JSON_PASTE37(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37)
#define SRB2_JSON_PASTE39(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38) SRB2_JSON_PASTE2(func, v1) SRB2_JSON_PASTE38(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38)
#define SRB2_JSON_PASTE40(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39) SRB2_JSON_PASTE2(func, v1) SRB2_JSON_PASTE39(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39)
#define SRB2_JSON_PASTE41(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40) SRB2_JSON_PASTE2(func, v1) SRB2_JSON_PASTE40(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40)
#define SRB2_JSON_PASTE42(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41) SRB2_JSON_PASTE2(func, v1) SRB2_JSON_PASTE41(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41)
#define SRB2_JSON_PASTE43(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42) SRB2_JSON_PASTE2(func, v1) SRB2_JSON_PASTE42(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42)
#define SRB2_JSON_PASTE44(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43) SRB2_JSON_PASTE2(func, v1) SRB2_JSON_PASTE43(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43)
#define SRB2_JSON_PASTE45(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44) SRB2_JSON_PASTE2(func, v1) SRB2_JSON_PASTE44(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44)
#define SRB2_JSON_PASTE46(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45) SRB2_JSON_PASTE2(func, v1) SRB2_JSON_PASTE45(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45)
#define SRB2_JSON_PASTE47(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46) SRB2_JSON_PASTE2(func, v1) SRB2_JSON_PASTE46(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46)
#define SRB2_JSON_PASTE48(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47) SRB2_JSON_PASTE2(func, v1) SRB2_JSON_PASTE47(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47)
#define SRB2_JSON_PASTE49(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48) SRB2_JSON_PASTE2(func, v1) SRB2_JSON_PASTE48(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48)
#define SRB2_JSON_PASTE50(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49) SRB2_JSON_PASTE2(func, v1) SRB2_JSON_PASTE49(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49)
#define SRB2_JSON_PASTE51(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50) SRB2_JSON_PASTE2(func, v1) SRB2_JSON_PASTE50(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50)
#define SRB2_JSON_PASTE52(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51) SRB2_JSON_PASTE2(func, v1) SRB2_JSON_PASTE51(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51)
#define SRB2_JSON_PASTE53(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52) SRB2_JSON_PASTE2(func, v1) SRB2_JSON_PASTE52(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52)
#define SRB2_JSON_PASTE54(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53) SRB2_JSON_PASTE2(func, v1) SRB2_JSON_PASTE53(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53)
#define SRB2_JSON_PASTE55(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54) SRB2_JSON_PASTE2(func, v1) SRB2_JSON_PASTE54(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54)
#define SRB2_JSON_PASTE56(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55) SRB2_JSON_PASTE2(func, v1) SRB2_JSON_PASTE55(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55)
#define SRB2_JSON_PASTE57(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56) SRB2_JSON_PASTE2(func, v1) SRB2_JSON_PASTE56(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56)
#define SRB2_JSON_PASTE58(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57) SRB2_JSON_PASTE2(func, v1) SRB2_JSON_PASTE57(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57)
#define SRB2_JSON_PASTE59(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58) SRB2_JSON_PASTE2(func, v1) SRB2_JSON_PASTE58(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58)
#define SRB2_JSON_PASTE60(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59) SRB2_JSON_PASTE2(func, v1) SRB2_JSON_PASTE59(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59)
#define SRB2_JSON_PASTE61(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60) SRB2_JSON_PASTE2(func, v1) SRB2_JSON_PASTE60(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60)
#define SRB2_JSON_PASTE62(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61) SRB2_JSON_PASTE2(func, v1) SRB2_JSON_PASTE61(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61)
#define SRB2_JSON_PASTE63(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62) SRB2_JSON_PASTE2(func, v1) SRB2_JSON_PASTE62(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62)
#define SRB2_JSON_PASTE64(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62, v63) SRB2_JSON_PASTE2(func, v1) SRB2_JSON_PASTE63(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62, v63)
#define SRB2_JSON_TO(v1) to_json(srb2_json_j.as_object()[#v1], srb2_json_t.v1);
#define SRB2_JSON_FROM(v1) srb2_json_t.v1 = srb2_json_j.as_object().at(#v1);
#define SRB2_JSON_FROM_WITH_DEFAULT(v1) if (srb2_json_j.as_object().find(#v1) != srb2_json_j.as_object().end()) \
{ \
from_json(srb2_json_j.as_object().find(#v1)->second, srb2_json_t.v1); \
} \
else \
{ \
srb2_json_t.v1 = srb2_json_default_obj.v1; \
}
/*!
@brief macro
@def SRB2_JSON_DEFINE_TYPE_INTRUSIVE
@since version 3.9.0
*/
#define SRB2_JSON_DEFINE_TYPE_INTRUSIVE(Type, ...) \
friend void to_json(srb2::JsonValue& srb2_json_j, const Type& srb2_json_t) { srb2_json_j = srb2::JsonObject(); SRB2_JSON_EXPAND(SRB2_JSON_PASTE(SRB2_JSON_TO, __VA_ARGS__)) } \
friend void from_json(const srb2::JsonValue& srb2_json_j, Type& srb2_json_t) { SRB2_JSON_EXPAND(SRB2_JSON_PASTE(SRB2_JSON_FROM, __VA_ARGS__)) }
#define SRB2_JSON_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(Type, ...) \
friend void to_json(srb2::JsonValue& srb2_json_j, const Type& srb2_json_t) { srb2_json_j = srb2::JsonObject(); SRB2_JSON_EXPAND(SRB2_JSON_PASTE(SRB2_JSON_TO, __VA_ARGS__)) } \
friend void from_json(const srb2::JsonValue& srb2_json_j, Type& srb2_json_t) { const Type srb2_json_default_obj{}; SRB2_JSON_EXPAND(SRB2_JSON_PASTE(SRB2_JSON_FROM_WITH_DEFAULT, __VA_ARGS__)) }
/*!
@brief macro
@def SRB2_JSON_DEFINE_TYPE_NON_INTRUSIVE
@since version 3.9.0
*/
#define SRB2_JSON_DEFINE_TYPE_NON_INTRUSIVE(Type, ...) \
inline void to_json(srb2::JsonValue& srb2_json_j, const Type& srb2_json_t) { SRB2_JSON_EXPAND(SRB2_JSON_PASTE(SRB2_JSON_TO, __VA_ARGS__)) } \
inline void from_json(const srb2::JsonValue& srb2_json_j, Type& srb2_json_t) { SRB2_JSON_EXPAND(SRB2_JSON_PASTE(SRB2_JSON_FROM, __VA_ARGS__)) }
/*!
@brief macro
@def SRB2_JSON_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT
@since version 3.11.0
*/
#define SRB2_JSON_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT(Type, ...) \
inline void to_json(srb2::JsonValue& srb2_json_j, const Type& srb2_json_t) { SRB2_JSON_EXPAND(SRB2_JSON_PASTE(SRB2_JSON_TO, __VA_ARGS__)) } \
inline void from_json(const srb2::JsonValue& srb2_json_j, Type& srb2_json_t) { const Type srb2_json_default_obj{}; SRB2_JSON_EXPAND(SRB2_JSON_PASTE(SRB2_JSON_FROM_WITH_DEFAULT, __VA_ARGS__)) }

View file

@ -1,7 +1,7 @@
// DR. ROBOTNIK'S RING RACERS
//-----------------------------------------------------------------------------
// Copyright (C) 2024 by Ronald "Eidolon" Kinard
// Copyright (C) 2024 by Kart Krew
// Copyright (C) 2025 by Ronald "Eidolon" Kinard
// Copyright (C) 2025 by Kart Krew
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
@ -10,11 +10,13 @@
#include "memory.h"
#include <array>
#include <new>
#include <cstdint>
#include "../cxxutil.hpp"
#include "../z_zone.h"
using namespace srb2;
namespace
{
@ -58,6 +60,81 @@ void LinearMemory::reset() noexcept
} // namespace
PoolAllocator::~PoolAllocator()
{
release();
}
constexpr static size_t nearest_multiple(size_t v, size_t divisor)
{
return (v + (divisor - 1)) & ~(divisor - 1);
}
PoolAllocator::ChunkFooter* PoolAllocator::allocate_chunk()
{
uint8_t* chunk = (uint8_t*)Z_Malloc(nearest_multiple(blocks_ * block_size_, alignof(ChunkFooter)) + sizeof(ChunkFooter), tag_, nullptr);
ChunkFooter* footer = (ChunkFooter*)(chunk + (blocks_ * block_size_));
footer->next = nullptr;
footer->start = (void*)chunk;
for (size_t i = 0; i < blocks_; i++)
{
FreeBlock* cur = (FreeBlock*)(chunk + (i * block_size_));
FreeBlock* next = (FreeBlock*)(chunk + ((i + 1) * block_size_));
cur->next = next;
}
((FreeBlock*)(chunk + ((blocks_ - 1) * block_size_)))->next = nullptr;
return footer;
}
void* PoolAllocator::allocate()
{
if (first_chunk_ == nullptr)
{
SRB2_ASSERT(head_ == nullptr);
// No chunks allocated yet
first_chunk_ = allocate_chunk();
head_ = (FreeBlock*)first_chunk_->start;
}
if (head_->next == nullptr)
{
// Current chunk will be full; allocate another at the end of the list
ChunkFooter* last_chunk = first_chunk_;
while (last_chunk->next != nullptr)
{
last_chunk = last_chunk->next;
}
ChunkFooter* new_chunk = allocate_chunk();
last_chunk->next = new_chunk;
head_->next = (FreeBlock*)new_chunk->start;
}
FreeBlock* ret = head_;
head_ = head_->next;
return ret;
}
void PoolAllocator::deallocate(void* p)
{
FreeBlock* block = reinterpret_cast<FreeBlock*>(p);
block->next = head_;
head_ = block;
}
void PoolAllocator::release()
{
ChunkFooter* next = nullptr;
for (ChunkFooter* i = first_chunk_; i != nullptr; i = next)
{
next = i->next;
Z_Free(i->start);
}
first_chunk_ = nullptr;
head_ = nullptr;
}
static LinearMemory g_frame_memory {4 * 1024 * 1024};
void* Z_Frame_Alloc(size_t size)

View file

@ -1,7 +1,7 @@
// DR. ROBOTNIK'S RING RACERS
//-----------------------------------------------------------------------------
// Copyright (C) 2024 by Ronald "Eidolon" Kinard
// Copyright (C) 2024 by Kart Krew
// Copyright (C) 2025 by Ronald "Eidolon" Kinard
// Copyright (C) 2025 by Kart Krew
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
@ -14,6 +14,58 @@
#include <stddef.h>
#ifdef __cplusplus
#include <cstdint>
namespace srb2
{
/// Pool allocator; manages bulk allocations of same-size block. If the pool is full,
/// allocations will fail by returning nullptr.
class PoolAllocator final
{
struct FreeBlock
{
FreeBlock* next;
};
struct ChunkFooter
{
ChunkFooter* next;
void* start;
};
ChunkFooter* first_chunk_;
FreeBlock* head_;
size_t block_size_;
size_t blocks_;
int32_t tag_;
ChunkFooter* allocate_chunk();
public:
constexpr PoolAllocator(size_t block_size, size_t blocks, int32_t tag)
: first_chunk_(nullptr)
, head_(nullptr)
, block_size_(block_size)
, blocks_(blocks)
, tag_(tag)
{}
PoolAllocator(const PoolAllocator&) = delete;
PoolAllocator(PoolAllocator&&) noexcept = default;
~PoolAllocator();
PoolAllocator& operator=(const PoolAllocator&) = delete;
PoolAllocator& operator=(PoolAllocator&&) noexcept = default;
void* allocate();
void deallocate(void* p);
constexpr size_t block_size() const noexcept { return block_size_; };
void release();
};
} // namespace srb2
extern "C" {
#endif // __cpluspplus

View file

@ -1,7 +1,7 @@
// DR. ROBOTNIK'S RING RACERS
//-----------------------------------------------------------------------------
// Copyright (C) 2024 by Ronald "Eidolon" Kinard
// Copyright (C) 2024 by Kart Krew
// Copyright (C) 2025 by Ronald "Eidolon" Kinard
// Copyright (C) 2025 by Kart Krew
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
@ -238,11 +238,12 @@ bool operator!=(const srb2::StaticVec<T, L1>& lhs, const srb2::StaticVec<T, L2>&
template <typename T, size_t Limit>
struct std::hash<srb2::StaticVec<T, Limit>>
{
uint64_t operator()(const srb2::StaticVec<T, Limit>& input) const
size_t operator()(const srb2::StaticVec<T, Limit>& input) const
{
constexpr const uint64_t prime {0x00000100000001B3};
std::size_t ret {0xcbf29ce484222325};
constexpr size_t prime = sizeof(size_t) == 8 ? 0x00000100000001B3 : 0x01000193;
constexpr size_t basis = sizeof(size_t) == 8 ? 0xcbf29ce484222325 : 0x811c9dc5;
size_t ret = basis;
for (auto itr = input.begin(); itr != input.end(); itr++)
{
ret = (ret * prime) ^ std::hash<T>(*itr);

1125
src/core/string.cpp Normal file

File diff suppressed because it is too large Load diff

453
src/core/string.h Normal file
View file

@ -0,0 +1,453 @@
// DR. ROBOTNIK'S RING RACERS
//-----------------------------------------------------------------------------
// Copyright (C) 2025 by Ronald "Eidolon" Kinard
// Copyright (C) 2025 by Kart Krew
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
// See the 'LICENSE' file for more details.
//-----------------------------------------------------------------------------
#ifndef SRB2_CORE_STRING_HPP
#define SRB2_CORE_STRING_HPP
#ifdef __cplusplus
#include <cstdint>
#include <initializer_list>
#include <string>
#include <string_view>
#include <type_traits>
#include "fmt/core.h"
#include "static_vec.hpp"
#include "vector.hpp"
namespace srb2
{
class Utf8Iter
{
public:
using difference_type = size_t;
using value_type = uint32_t;
using pointer = void;
using reference = void;
using iterator_category = std::input_iterator_tag;
private:
size_t i_;
std::string_view s_;
Utf8Iter(std::string_view s, size_t i) : i_(i), s_(s) {}
friend class String;
uint32_t do_codepoint() const;
public:
Utf8Iter() = default;
Utf8Iter(const Utf8Iter&) = default;
Utf8Iter(Utf8Iter&&) noexcept = default;
~Utf8Iter() = default;
Utf8Iter& operator=(const Utf8Iter&) = default;
Utf8Iter& operator=(Utf8Iter&&) noexcept = default;
static Utf8Iter begin(std::string_view s) { return Utf8Iter(s, 0); }
static Utf8Iter end(std::string_view s) { return Utf8Iter(s, s.size()); }
bool operator==(const Utf8Iter& r) const noexcept
{
return s_ == r.s_ && i_ == r.i_;
}
bool operator!=(const Utf8Iter& r) const noexcept { return !(*this == r); }
uint32_t operator*() const { return codepoint(); }
Utf8Iter& operator++()
{
i_ += size();
return *this;
}
Utf8Iter operator++(int)
{
Utf8Iter copy = *this;
++*this;
return copy;
}
uint32_t codepoint() const;
bool valid() const;
uint8_t size() const;
};
class Utf16Iter
{
public:
using difference_type = size_t;
using value_type = uint32_t;
using pointer = void;
using reference = void;
using iterator_category = std::input_iterator_tag;
private:
size_t i_;
std::u16string_view s_;
Utf16Iter(std::u16string_view s, size_t i) : i_(i), s_(s) {}
uint32_t do_codepoint() const;
public:
Utf16Iter() = default;
Utf16Iter(const Utf16Iter&) = default;
Utf16Iter(Utf16Iter&&) noexcept = default;
~Utf16Iter() = default;
Utf16Iter& operator=(const Utf16Iter&) = default;
Utf16Iter& operator=(Utf16Iter&&) = default;
static Utf16Iter begin(std::u16string_view s) { return Utf16Iter(s, 0); }
static Utf16Iter end(std::u16string_view s) { return Utf16Iter(s, s.size()); }
bool operator==(const Utf16Iter& r) const noexcept
{
return s_ == r.s_ && i_ == r.i_;
}
bool operator!=(const Utf16Iter& r) const noexcept { return !(*this == r); }
uint32_t operator*() const { return codepoint(); }
Utf16Iter& operator++()
{
i_ += size();
return *this;
}
Utf16Iter operator++(int)
{
Utf16Iter copy = *this;
++*this;
return copy;
}
uint32_t codepoint() const;
bool valid() const { return true; } // we allow unpaired surrogates in general
uint8_t size() const;
};
class String
{
public:
using size_type = uint32_t;
using difference_type = int64_t;
using value_type = uint8_t;
using reference = uint8_t&;
using const_reference = const uint8_t&;
using pointer = uint8_t*;
using const_pointer = const uint8_t*;
using iterator = uint8_t*;
using const_iterator = const uint8_t*;
private:
srb2::Vector<uint8_t> data_;
public:
friend struct std::hash<String>;
static constexpr const size_type npos = -1;
String() = default;
String(const String&);
String(String&&) noexcept;
~String();
String& operator=(const String&);
String& operator=(String&&) noexcept;
String(const char* s);
String(const char* s, size_t len);
String(const std::string&);
explicit String(std::string_view view);
operator std::string() const;
operator std::string_view() const;
size_type size() const noexcept;
bool empty() const noexcept { return data_.empty(); }
const char* c_str() const;
uint8_t* data() noexcept { return data_.data(); }
const uint8_t* data() const noexcept { return data_.data(); }
void reserve(size_type capacity);
uint8_t* begin() noexcept;
uint8_t* end() noexcept;
const uint8_t* cbegin() const noexcept;
const uint8_t* cend() const noexcept;
const uint8_t* begin() const noexcept { return cbegin(); }
const uint8_t* end() const noexcept { return cend(); }
uint8_t& at(size_type i);
const uint8_t& at(size_type i) const;
uint8_t& operator[](size_type i) { return data_[i]; }
const uint8_t& operator[](size_type i) const { return data_[i]; }
uint8_t& front() { return data_[0]; }
const uint8_t& front() const { return data_[0]; }
uint8_t& back() { return data_[size() - 1]; }
const uint8_t& back() const { return data_[size() - 1]; }
void clear() { data_.clear(); }
String& insert(size_type index, size_type count, uint8_t ch);
String& insert(size_type index, const char* s);
String& insert(size_type index, const char* s, size_type count);
String& insert(size_type index, std::string_view str);
String& insert(size_type index, std::string_view str, size_t s_index, size_t count = npos);
iterator insert(const_iterator pos, uint8_t ch);
iterator insert(const_iterator pos, size_type count, uint8_t ch);
template <
typename InputIt,
typename std::enable_if_t<
std::is_constructible<
uint8_t,
typename std::iterator_traits<InputIt>::reference
>::value,
int
> = 0
>
iterator insert(const_iterator pos, InputIt first, InputIt last)
{
size_type offset = pos - data();
if (!empty())
{
// remove null byte
data_.pop_back();
}
auto ret = data_.insert(pos, first, last);
if (data_.size() > 0)
{
data_.push_back(0);
}
return data() + offset;
}
iterator insert(const_iterator pos, std::initializer_list<uint8_t> list);
String& erase(size_type index = 0, size_type count = npos);
iterator erase(const_iterator position);
iterator erase(const_iterator first, const_iterator last);
void push_back(uint8_t v);
void pop_back();
String& append(size_type count, uint8_t ch);
String& append(const char* s, size_type count);
String& append(const char* s);
String& append(std::string_view str);
String& append(std::string_view str, size_type pos, size_type count = npos);
template <
typename InputIt,
typename std::enable_if_t<
std::is_constructible<
uint8_t,
typename std::iterator_traits<InputIt>::reference
>::value,
int
> = 0
>
String& append(InputIt first, InputIt last)
{
if (!empty())
{
// remove null byte
data_.pop_back();
}
for (; first != last; first++)
{
data_.push_back(*first);
}
if (data_.size() > 0)
{
data_.push_back(0);
}
return *this;
}
String& append(std::initializer_list<uint8_t> ilist);
String& operator+=(std::string_view r);
String& operator+=(const char* r);
String& operator+=(uint8_t r);
String& operator+=(std::initializer_list<uint8_t> r);
String& replace(size_type pos, size_type count, std::string_view str);
String& replace(const_iterator first, const_iterator last, std::string_view str);
String& replace(size_type pos, size_type count, std::string_view str, size_t pos2, size_t count2 = -1);
String& replace(size_type pos, size_type count, const char* cstr, size_type count2);
String& replace(const_iterator first, const_iterator last, const char* cstr, size_type count2);
String& replace(size_type pos, size_type count, const char* cstr);
String& replace(const_iterator first, const_iterator last, const char* cstr);
// String& replace(size_type pos, size_type count, size_type count2, uint8_t ch);
String& replace(const_iterator first, const_iterator last, uint8_t ch);
template <
typename InputIt,
typename std::enable_if_t<
std::is_constructible<
uint8_t,
typename std::iterator_traits<InputIt>::reference
>::value,
int
> = 0
>
String& replace(const_iterator first, const_iterator last, InputIt first2, InputIt last2)
{
for (; first != last && first2 != last2; first++, first2++)
{
*const_cast<iterator>(first) = *first2;
}
return *this;
}
String& replace(const_iterator first, const_iterator last, std::initializer_list<uint8_t> ilist);
size_type copy(uint8_t* dest, size_type count, size_type pos = 0) const;
size_type copy(char* dest, size_type count, size_type pos = 0) const;
void resize(size_type count);
void resize(size_type count, uint8_t ch);
void swap(String& other) noexcept;
size_type find(const String& str, size_type pos = 0) const;
size_type find(std::string_view str, size_type pos = 0) const;
size_type find(const char* s, size_type pos, size_t count) const;
size_type find(const char* s, size_type pos = 0) const;
size_type find(uint8_t ch, size_type pos = 0) const;
size_type rfind(const String& str, size_type pos = npos) const;
size_type rfind(std::string_view str, size_type pos = npos) const;
size_type rfind(const char* s, size_type pos, size_type count) const;
size_type rfind(const char* s, size_type pos = npos) const;
size_type rfind(uint8_t ch, size_type pos = npos) const;
// size_type find_first_of(std::string_view str, size_type pos = 0) const;
// size_type find_first_of(const char* s, size_type pos, size_type count) const;
// size_type find_first_of(const char* s, size_type pos = 0) const;
// size_type find_first_of(uint8_t ch, size_type pos = 0) const;
// size_type find_first_not_of(std::string_view str, size_type pos = 0) const;
// size_type find_first_not_of(const char* s, size_type pos, size_type count) const;
// size_type find_first_not_of(const char* s, size_type pos = 0) const;
// size_type find_first_not_of(uint8_t ch, size_type pos = 0) const;
// size_type find_last_of(std::string_view str, size_type pos = npos) const;
// size_type find_last_of(const char* s, size_type pos, size_type count) const;
// size_type find_last_of(const char* s, size_type pos = npos) const;
// size_type find_last_of(uint8_t ch, size_type pos = npos) const;
// size_type find_last_not_of(std::string_view str, size_type pos = npos) const;
// size_type find_last_not_of(const char* s, size_type pos, size_type count) const;
// size_type find_last_not_of(const char* s, size_type pos = npos) const;
// size_type find_last_not_of(uint8_t ch, size_type pos = npos) const;
int compare(std::string_view str) const noexcept;
// int compare(size_type pos1, size_type count1, std::string_view str) const;
// int compare(size_type pos1, size_type count1, std::string_view str, size_type pos2, size_type count2 = npos) const;
int compare(const char* s) const;
// int compare(size_type pos1, size_type count1, const char* s) const;
// int compare(size_type pos1, size_type count1, const char* s, size_type count2) const;
String substr(size_type pos = 0, size_type count = npos) const;
// Non-STL String functions
bool valid_utf8() const noexcept;
srb2::Vector<uint16_t> to_utf16() const;
srb2::Vector<uint32_t> to_utf32() const;
size_t length_decoded() const;
Utf8Iter decode_begin() const { return Utf8Iter(*this, 0); }
Utf8Iter decode_end() const { return Utf8Iter(*this, size()); };
};
String operator+(const String& lhs, const String& rhs);
String operator+(const String& lhs, const char* rhs);
String operator+(const String& lhs, uint8_t rhs);
String operator+(const String& lhs, std::string_view view);
bool operator==(const String& lhs, const String& rhs);
bool operator==(const String& lhs, const char* rhs);
// bool operator==(const String& lhs, std::string_view rhs);
bool operator!=(const String& lhs, const String& rhs);
bool operator!=(const String& lhs, const char* rhs);
// bool operator!=(const String& lhs, std::string_view rhs);
bool operator<(const String& lhs, const String& rhs);
bool operator<(const String& lhs, const char* rhs);
// bool operator<(const String& lhs, std::string_view rhs);
bool operator<=(const String& lhs, const String& rhs);
bool operator<=(const String& lhs, const char* rhs);
// bool operator<=(const String& lhs, std::string_view rhs);
bool operator>(const String& lhs, const String& rhs);
bool operator>(const String& lhs, const char* rhs);
// bool operator>(const String& lhs, std::string_view rhs);
bool operator>=(const String& lhs, const String& rhs);
bool operator>=(const String& lhs, const char* rhs);
// bool operator>=(const String& lhs, std::string_view rhs);
Vector<uint16_t> to_utf16(std::string_view utf8);
Vector<uint32_t> to_utf32(std::string_view utf8);
srb2::StaticVec<uint8_t, 4> to_utf8(uint32_t codepoint);
template <
typename ItUTF32,
typename std::enable_if_t<
std::is_constructible<
uint32_t,
typename std::iterator_traits<ItUTF32>::reference
>::value,
int
> = 0
>
srb2::String to_utf8(ItUTF32 begin, ItUTF32 end)
{
srb2::String ret;
for (auto itr = begin; itr != end; ++itr)
{
srb2::StaticVec<uint8_t, 4> utf8 = to_utf8(*itr);
ret.append(utf8.begin(), utf8.end());
}
return ret;
}
srb2::String to_utf8(std::u32string_view utf32view);
// fmtlib
inline auto format_as(const String& str) { return fmt::string_view(static_cast<std::string_view>(str)); }
srb2::String vformat(fmt::string_view fmt, fmt::format_args args);
template <typename... T>
inline auto format(fmt::format_string<T...> fmt, T&&... args)
{
return ::srb2::vformat(fmt, fmt::vargs<T...>{{args...}});
}
} // namespace srb2
namespace std
{
template <> struct hash<srb2::String>
{
size_t operator()(const srb2::String& v);
};
} // namespace std
#endif // __cplusplus
#ifndef __cplusplus
#include <stdint.h>
#endif
#ifdef __cplusplus
extern "C"
{
#endif
int Str_IsValidUTF8(const char* str);
// int Str_ToUTF16(uint16_t* dst, size_t dstlen, const char* src);
// int Str_ToUTF32(uint32_t* dst, size_t dstlen, const char* src);
uint32_t Str_NextCodepointFromUTF8(const char** itr);
#ifdef __cplusplus
} // extern "C"
#endif
#endif // SRB2_CORE_STRING_HPP

Some files were not shown because too many files have changed in this diff Show more