diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 29f5ef5ff..14c36213e 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -12,6 +12,7 @@ variables: stages: - build + - osxcross default: interruptible: true diff --git a/.gitlab/ci/jobs/alpine-3-gcc-makefile.yml b/.gitlab/ci/jobs/alpine-3-gcc-makefile.yml index 6b0b6a06f..13bcea070 100644 --- a/.gitlab/ci/jobs/alpine-3-gcc-makefile.yml +++ b/.gitlab/ci/jobs/alpine-3-gcc-makefile.yml @@ -58,26 +58,24 @@ Alpine 3 GCC Makefile: - - | # 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" @@ -103,7 +101,7 @@ Alpine 3 GCC Makefile: - - | # 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 elfutils-dev + - apk add musl-dev sdl2_mixer-dev libpng-dev curl-dev libgme-dev libopenmpt-dev miniupnpc-dev elfutils-dev - | # apk_development echo -e "\e[0Ksection_end:`date +%s`:apk_development\r\e[0K" diff --git a/.gitlab/ci/jobs/alpine-3-gcc.yml b/.gitlab/ci/jobs/alpine-3-gcc.yml index 522b88ae3..5d828ce58 100644 --- a/.gitlab/ci/jobs/alpine-3-gcc.yml +++ b/.gitlab/ci/jobs/alpine-3-gcc.yml @@ -15,8 +15,8 @@ Alpine 3 GCC: artifacts: paths: - - "build.alpine3/bin/" - - "build.alpine3/src/config.h" + - "build.cmake/bin/" + - "build.cmake/src/config.h" expose_as: "Apline-3" name: "$CI_PROJECT_PATH_SLUG-$CI_COMMIT_REF_SLUG-$CI_COMMIT_SHORT_SHA-Apline-3" @@ -58,26 +58,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" @@ -111,7 +109,15 @@ Alpine 3 GCC: - - | # cmake echo -e "\e[0Ksection_start:`date +%s`:cmake[collapsed=false]\r\e[0KBuilding Makefiles" - - cmake -B build.alpine3 -DSRB2_USE_CCACHE=YES -DSRB2_CONFIG_ERRORMODE=ON -DSRB2_CONFIG_EXECINFO=NO -G "Unix Makefiles" + - | + cmake \ + -B build.cmake \ + -G "Unix Makefiles" \ + -DCMAKE_COLOR_DIAGNOSTICS=OFF \ + -DSRB2_CONFIG_ENABLE_WEBM_MOVIES=OFF \ + -DSRB2_CONFIG_ERRORMODE=ON \ + -DSRB2_CONFIG_EXECINFO=NO \ + -DSRB2_CONFIG_USE_GME:BOOL=ON - | # cmake echo -e "\e[0Ksection_end:`date +%s`:cmake\r\e[0K" @@ -119,7 +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" diff --git a/.gitlab/ci/jobs/batocera-arm64-makefile.yml b/.gitlab/ci/jobs/batocera-arm64-makefile.yml index e02497d40..dd8f57759 100644 --- a/.gitlab/ci/jobs/batocera-arm64-makefile.yml +++ b/.gitlab/ci/jobs/batocera-arm64-makefile.yml @@ -1,6 +1,8 @@ batocera:arm64 Makefile: extends: Debian stable:arm64 Makefile + stage: build + when: manual allow_failure: true diff --git a/.gitlab/ci/jobs/batocera-arm64.yml b/.gitlab/ci/jobs/batocera-arm64.yml index c3b586584..5f928ab50 100644 --- a/.gitlab/ci/jobs/batocera-arm64.yml +++ b/.gitlab/ci/jobs/batocera-arm64.yml @@ -1,6 +1,8 @@ batocera:arm64: extends: Debian stable:arm64 + stage: build + when: manual allow_failure: true @@ -32,7 +34,15 @@ batocera:arm64: - - | # cmake echo -e "\e[0Ksection_start:`date +%s`:cmake[collapsed=false]\r\e[0KBuilding Makefiles" - - cmake -B build.cmake -DSRB2_USE_CCACHE=YES -DSRB2_CONFIG_ERRORMODE=ON -DSRB2_CONFIG_FORCE_NO_MS_BITFIELDS=ON -DSRB2_CONFIG_USE_GME=OFF -G "Unix Makefiles" + - | + cmake \ + -B build.cmake \ + -G "Unix Makefiles" \ + -DCMAKE_COLOR_DIAGNOSTICS=OFF \ + -DSRB2_CONFIG_ENABLE_WEBM_MOVIES=OFF \ + -DSRB2_CONFIG_ERRORMODE=ON \ + -DSRB2_CONFIG_FORCE_NO_MS_BITFIELDS=ON \ + -DSRB2_CONFIG_USE_GME:BOOL=OFF - | # cmake echo -e "\e[0Ksection_end:`date +%s`:cmake\r\e[0K" @@ -40,7 +50,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" diff --git a/.gitlab/ci/jobs/debian-oldstable-amd64-makefile.yml b/.gitlab/ci/jobs/debian-oldstable-amd64-makefile.yml index bd4a92741..f365a7927 100644 --- a/.gitlab/ci/jobs/debian-oldstable-amd64-makefile.yml +++ b/.gitlab/ci/jobs/debian-oldstable-amd64-makefile.yml @@ -1,6 +1,8 @@ Debian oldstable:amd64 Makefile: extends: Debian stable:amd64 Makefile + stage: build + when: manual image: git.do.srb2.org:5050/stjr/srb2ci/srb2ci:oldstable diff --git a/.gitlab/ci/jobs/debian-oldstable-amd64.yml b/.gitlab/ci/jobs/debian-oldstable-amd64.yml index ad69dc8dd..3aaf30698 100644 --- a/.gitlab/ci/jobs/debian-oldstable-amd64.yml +++ b/.gitlab/ci/jobs/debian-oldstable-amd64.yml @@ -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 ++-x86-64-linux-gnu || apt-get install g++ + - 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" @@ -34,7 +36,14 @@ Debian oldstable:amd64: - - | # cmake echo -e "\e[0Ksection_start:`date +%s`:cmake[collapsed=false]\r\e[0KBuilding Makefiles" - - cmake -B build.cmake -DSRB2_USE_CCACHE=YES -DSRB2_CONFIG_ERRORMODE=ON -DSRB2_CONFIG_USE_GME=OFF -G "Unix Makefiles" + - | + cmake \ + -B build.cmake \ + -G "Unix Makefiles" \ + -DCMAKE_COLOR_DIAGNOSTICS=OFF \ + -DSRB2_CONFIG_ENABLE_WEBM_MOVIES=OFF \ + -DSRB2_CONFIG_ERRORMODE=ON \ + -DSRB2_CONFIG_USE_GME:BOOL=ON - | # cmake echo -e "\e[0Ksection_end:`date +%s`:cmake\r\e[0K" @@ -42,7 +51,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" diff --git a/.gitlab/ci/jobs/debian-oldstable-arm64-makefile.yml b/.gitlab/ci/jobs/debian-oldstable-arm64-makefile.yml index 426934bf9..25782baf2 100644 --- a/.gitlab/ci/jobs/debian-oldstable-arm64-makefile.yml +++ b/.gitlab/ci/jobs/debian-oldstable-arm64-makefile.yml @@ -1,6 +1,8 @@ Debian oldstable:arm64 Makefile: extends: Debian stable:arm64 Makefile + stage: build + when: manual image: git.do.srb2.org:5050/stjr/srb2ci/srb2ci:oldstable diff --git a/.gitlab/ci/jobs/debian-oldstable-arm64.yml b/.gitlab/ci/jobs/debian-oldstable-arm64.yml index 24db9c807..96db9f486 100644 --- a/.gitlab/ci/jobs/debian-oldstable-arm64.yml +++ b/.gitlab/ci/jobs/debian-oldstable-arm64.yml @@ -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 @@ -34,7 +36,15 @@ Debian oldstable:arm64: - - | # cmake echo -e "\e[0Ksection_start:`date +%s`:cmake[collapsed=false]\r\e[0KBuilding Makefiles" - - cmake -B build.cmake -DSRB2_USE_CCACHE=YES -DSRB2_CONFIG_ERRORMODE=ON -DSRB2_CONFIG_FORCE_NO_MS_BITFIELDS=ON -DSRB2_CONFIG_USE_GME=OFF -G "Unix Makefiles" + - | + cmake \ + -B build.cmake \ + -G "Unix Makefiles" \ + -DCMAKE_COLOR_DIAGNOSTICS=OFF \ + -DSRB2_CONFIG_ENABLE_WEBM_MOVIES=OFF \ + -DSRB2_CONFIG_ERRORMODE=ON \ + -DSRB2_CONFIG_FORCE_NO_MS_BITFIELDS=ON \ + -DSRB2_CONFIG_USE_GME:BOOL=ON - | # cmake echo -e "\e[0Ksection_end:`date +%s`:cmake\r\e[0K" @@ -42,7 +52,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" diff --git a/.gitlab/ci/jobs/debian-stable-amd64-makefile.yml b/.gitlab/ci/jobs/debian-stable-amd64-makefile.yml index a6aebfac3..fee52c5a7 100644 --- a/.gitlab/ci/jobs/debian-stable-amd64-makefile.yml +++ b/.gitlab/ci/jobs/debian-stable-amd64-makefile.yml @@ -13,7 +13,6 @@ Debian stable:amd64 Makefile: variables: CC: x86_64-linux-gnu-gcc CXX: x86_64-linux-gnu-g++ - LDFLAGS: -Wl,-fuse-ld=gold OBJCOPY: x86_64-linux-gnu-objcopy OBJDUMP: x86_64-linux-gnu-objdump PKG_CONFIG_PATH: /usr/lib/x86_64-linux-gnu/pkgconfig diff --git a/.gitlab/ci/jobs/debian-stable-amd64.yml b/.gitlab/ci/jobs/debian-stable-amd64.yml index a39344db8..da3b3a4ad 100644 --- a/.gitlab/ci/jobs/debian-stable-amd64.yml +++ b/.gitlab/ci/jobs/debian-stable-amd64.yml @@ -13,7 +13,6 @@ Debian stable:amd64: variables: CC: x86_64-linux-gnu-gcc CXX: x86_64-linux-gnu-g++ - LDFLAGS: -Wl,-fuse-ld=gold OBJCOPY: x86_64-linux-gnu-objcopy OBJDUMP: x86_64-linux-gnu-objdump PKG_CONFIG_PATH: /usr/lib/x86_64-linux-gnu/pkgconfig @@ -40,7 +39,14 @@ Debian stable:amd64: - - | # cmake echo -e "\e[0Ksection_start:`date +%s`:cmake[collapsed=false]\r\e[0KBuilding Makefiles" - - cmake -B build.cmake -DSRB2_USE_CCACHE=YES -DSRB2_CONFIG_ERRORMODE=ON -G "Unix Makefiles" + - | + cmake \ + -B build.cmake \ + -G "Unix Makefiles" \ + -DCMAKE_COLOR_DIAGNOSTICS=OFF \ + -DSRB2_CONFIG_ENABLE_WEBM_MOVIES=OFF \ + -DSRB2_CONFIG_ERRORMODE=ON \ + -DSRB2_CONFIG_USE_GME:BOOL=ON - | # cmake echo -e "\e[0Ksection_end:`date +%s`:cmake\r\e[0K" @@ -48,7 +54,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" diff --git a/.gitlab/ci/jobs/debian-stable-arm64-makefile.yml b/.gitlab/ci/jobs/debian-stable-arm64-makefile.yml index 53625138a..aa0ea3780 100644 --- a/.gitlab/ci/jobs/debian-stable-arm64-makefile.yml +++ b/.gitlab/ci/jobs/debian-stable-arm64-makefile.yml @@ -15,7 +15,6 @@ Debian stable:arm64 Makefile: variables: CC: aarch64-linux-gnu-gcc CXX: aarch64-linux-gnu-g++ - LDFLAGS: -Wl,-fuse-ld=gold OBJCOPY: aarch64-linux-gnu-objcopy OBJDUMP: aarch64-linux-gnu-objdump LD: aarch64-linux-gnu-ld diff --git a/.gitlab/ci/jobs/debian-stable-arm64.yml b/.gitlab/ci/jobs/debian-stable-arm64.yml index 52e6e8603..1f929a06b 100644 --- a/.gitlab/ci/jobs/debian-stable-arm64.yml +++ b/.gitlab/ci/jobs/debian-stable-arm64.yml @@ -15,7 +15,6 @@ Debian stable:arm64: variables: CC: aarch64-linux-gnu-gcc CXX: aarch64-linux-gnu-g++ - LDFLAGS: -Wl,-fuse-ld=gold OBJCOPY: aarch64-linux-gnu-objcopy OBJDUMP: aarch64-linux-gnu-objdump LD: aarch64-linux-gnu-ld @@ -41,7 +40,15 @@ Debian stable:arm64: - - | # cmake echo -e "\e[0Ksection_start:`date +%s`:cmake[collapsed=false]\r\e[0KBuilding Makefiles" - - cmake -B build.cmake -DSRB2_USE_CCACHE=YES -DSRB2_CONFIG_ERRORMODE=ON -DSRB2_CONFIG_FORCE_NO_MS_BITFIELDS=ON -G "Unix Makefiles" + - | + cmake \ + -B build.cmake \ + -G "Unix Makefiles" \ + -DCMAKE_COLOR_DIAGNOSTICS=OFF \ + -DSRB2_CONFIG_ENABLE_WEBM_MOVIES=OFF \ + -DSRB2_CONFIG_ERRORMODE=ON \ + -DSRB2_CONFIG_FORCE_NO_MS_BITFIELDS=ON \ + -DSRB2_CONFIG_USE_GME:BOOL=ON - | # cmake echo -e "\e[0Ksection_end:`date +%s`:cmake\r\e[0K" @@ -49,7 +56,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" diff --git a/.gitlab/ci/jobs/debian-stable-clang-amd64.yml b/.gitlab/ci/jobs/debian-stable-clang-amd64.yml index 4686c1849..fb363c7ae 100644 --- a/.gitlab/ci/jobs/debian-stable-clang-amd64.yml +++ b/.gitlab/ci/jobs/debian-stable-clang-amd64.yml @@ -9,17 +9,16 @@ Debian stable Clang: artifacts: paths: - - "build.clang/bin/" - - "build.clang/src/config.h" + - "build.cmake/bin/" + - "build.cmake/src/config.h" expose_as: "clang" name: "$CI_PROJECT_PATH_SLUG-$CI_COMMIT_REF_SLUG-$CI_COMMIT_SHORT_SHA-clang" variables: CC: clang - CXX: 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 script: - - | @@ -41,7 +40,17 @@ Debian stable Clang: - - | # cmake echo -e "\e[0Ksection_start:`date +%s`:cmake[collapsed=false]\r\e[0KBuilding Makefiles" - - cmake -B build.clang -DCPM_USE_LOCAL_PACKAGES:BOOL=ON -DSRB2_CONFIG_ENABLE_TESTS:BOOL=OFF -DSRB2_CONFIG_SYSTEM_LIBRARIES:BOOL=ON -DSRB2_USE_LIBGME:BOOL=OFF -G "Unix Makefiles" + - | + cmake \ + -B build.cmake \ + -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 \ + -DSRB2_USE_LIBGME:BOOL=OFF \ + -DSRB2_CONFIG_USE_GME:BOOL=ON - | # cmake echo -e "\e[0Ksection_end:`date +%s`:cmake\r\e[0K" @@ -49,7 +58,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" diff --git a/.gitlab/ci/jobs/debian-stable-i386.yml b/.gitlab/ci/jobs/debian-stable-i386.yml index ad4dcbb4f..f27c91533 100644 --- a/.gitlab/ci/jobs/debian-stable-i386.yml +++ b/.gitlab/ci/jobs/debian-stable-i386.yml @@ -40,7 +40,14 @@ Debian stable:i386: - - | # cmake echo -e "\e[0Ksection_start:`date +%s`:cmake[collapsed=false]\r\e[0KBuilding Makefiles" - - cmake -B build.cmake -DSRB2_USE_CCACHE=YES -DSRB2_CONFIG_ERRORMODE=ON -G "Unix Makefiles" + - | + cmake \ + -B build.cmake \ + -G "Unix Makefiles" \ + -DCMAKE_COLOR_DIAGNOSTICS=OFF \ + -DSRB2_CONFIG_ENABLE_WEBM_MOVIES=OFF \ + -DSRB2_CONFIG_ERRORMODE=ON \ + -DSRB2_CONFIG_USE_GME:BOOL=ON - | # cmake echo -e "\e[0Ksection_end:`date +%s`:cmake\r\e[0K" @@ -48,7 +55,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" diff --git a/.gitlab/ci/jobs/debian-testing-clang-amd64.yml b/.gitlab/ci/jobs/debian-testing-clang-amd64.yml index dc790b397..132e72642 100644 --- a/.gitlab/ci/jobs/debian-testing-clang-amd64.yml +++ b/.gitlab/ci/jobs/debian-testing-clang-amd64.yml @@ -16,7 +16,6 @@ Debian testing Clang: variables: CC: clang - CXX: clang + CXX: clang++ WFLAGS: -Wno-cast-align -Wno-implicit-const-int-float-conversion -Werror -Wno-deprecated-non-prototype -Wno-single-bit-bitfield-constant-conversion CFLAGS: -Wno-cast-align -Wno-implicit-const-int-float-conversion -Werror -Wno-deprecated-non-prototype -Wno-single-bit-bitfield-constant-conversion - LDFLAGS: -Wl,-fuse-ld=gold diff --git a/.gitlab/ci/jobs/debian-testing-gcc-amd64-makefile.yml b/.gitlab/ci/jobs/debian-testing-gcc-amd64-makefile.yml index 70d71b537..1165b1fea 100644 --- a/.gitlab/ci/jobs/debian-testing-gcc-amd64-makefile.yml +++ b/.gitlab/ci/jobs/debian-testing-gcc-amd64-makefile.yml @@ -19,7 +19,6 @@ Debian testing GCC Makefile: variables: CC: gcc CXX: g++ - LDFLAGS: -Wl,-fuse-ld=gold script: - - | diff --git a/.gitlab/ci/jobs/debian-testing-gcc-amd64.yml b/.gitlab/ci/jobs/debian-testing-gcc-amd64.yml index 7efb6c62d..9d7020e4c 100644 --- a/.gitlab/ci/jobs/debian-testing-gcc-amd64.yml +++ b/.gitlab/ci/jobs/debian-testing-gcc-amd64.yml @@ -19,7 +19,6 @@ Debian testing GCC: variables: CC: gcc CXX: g++ - LDFLAGS: -Wl,-fuse-ld=gold script: - - | @@ -41,7 +40,14 @@ Debian testing GCC: - - | # cmake echo -e "\e[0Ksection_start:`date +%s`:cmake[collapsed=false]\r\e[0KBuilding Makefiles" - - cmake -B build.cmake -DSRB2_USE_CCACHE=YES -DSRB2_CONFIG_ERRORMODE=ON -G "Unix Makefiles" + - | + cmake \ + -B build.cmake \ + -G "Unix Makefiles" \ + -DCMAKE_COLOR_DIAGNOSTICS=OFF \ + -DSRB2_CONFIG_ENABLE_WEBM_MOVIES=OFF \ + -DSRB2_CONFIG_ERRORMODE=ON \ + -DSRB2_CONFIG_USE_GME:BOOL=ON - | # cmake echo -e "\e[0Ksection_end:`date +%s`:cmake\r\e[0K" @@ -49,7 +55,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" diff --git a/.gitlab/ci/jobs/macos-arm64.yml b/.gitlab/ci/jobs/macos-arm64.yml index a9e31773e..558f7faff 100644 --- a/.gitlab/ci/jobs/macos-arm64.yml +++ b/.gitlab/ci/jobs/macos-arm64.yml @@ -3,26 +3,30 @@ osxcross arm64: stage: build - when: manual - allow_failure: 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 + OSXCROSS_HOST: oa64 + CMAKE_TOOLCHAIN_FILE: /osxcross/toolchain.cmake + LD: /opt/osxcross.arm64/ld script: - - | # apt_development echo -e "\e[0Ksection_start:`date +%s`:macports_development[collapsed=true]\r\e[0KInstalling development packages" - - osxcross-macports install --arm64 curl libopenmpt libsdl2_mixer + - osxcross-macports install --arm64 libopenmpt || osxcross-macports install --verbose --arm64 libopenmpt || true + - osxcross-macports install --arm64 wavpack || osxcross-macports install --verbose --arm64 wavpack || true + - osxcross-macports install --arm64 libxmp opusfile || osxcross-macports install --verbose --arm64 libxmp opusfile + - osxcross-macports install --static --arm64 libsdl2_mixer || osxcross-macports install --verbose --static --arm64 libsdl2_mixer || true + - osxcross-macports install --static --arm64 curl || osxcross-macports install --verbose --static --arm64 curl || true + - osxcross-macports install --static --arm64 miniupnpc libpng || osxcross-macports install --verbose --static --arm64 miniupnpc libpng - | # apt_development echo -e "\e[0Ksection_end:`date +%s`:macports_development\r\e[0K" @@ -30,7 +34,20 @@ osxcross arm64: - - | # cmake echo -e "\e[0Ksection_start:`date +%s`:cmake[collapsed=false]\r\e[0KBuilding Makefiles" - - cmake -B build.osxcross --toolchain /osxcross/toolchain.cmake -DCPM_USE_LOCAL_PACKAGES:BOOL=ON -DOPENMPT_INCLUDE_DIR:PATH="/osxcross/macports/pkgs/opt/local/include" -DSDL2_INCLUDE_DIR:PATH="/osxcross/macports/pkgs/opt/local/lib" -DSRB2_CONFIG_ENABLE_TESTS:BOOL=OFF -DSRB2_CONFIG_SYSTEM_LIBRARIES:BOOL=ON -DSRB2_CONFIG_FORCE_NO_MS_BITFIELDS:BOOL=ON -DSRB2_CONFIG_USE_GME:BOOL=OFF -G "Unix Makefiles" + - | + cmake \ + -B build.arm64 \ + -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_CONFIG_USE_GME:BOOL=OFF \ + -DSRB2_SDL2_EXE_NAME=srb2_$CI_PIPELINE_ID \ + -DSRB2_CONFIG_FORCE_NO_MS_BITFIELDS:BOOL=ON - | # make echo -e "\e[0Ksection_end:`date +%s`:make\r\e[0K" @@ -38,7 +55,35 @@ 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 --verbose build.arm64/src/config.h build.arm64/dist/arm64.h + - | + # make + echo -e "\e[0Ksection_end:`date +%s`:copy\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" + + - - | + # ccache_stats + echo -e "\e[0Ksection_start:`date +%s`:ccache_stats[collapsed=true]\r\e[0Kccache statistics:" + - ccache --show-stats + - ccache --show-log-stats || true + - | + # ccahe_stats + echo -e "\e[0Ksection_end:`date +%s`:ccache_stats\r\e[0K" diff --git a/.gitlab/ci/jobs/macos-x86_64.yml b/.gitlab/ci/jobs/macos-x86_64.yml index 525a919c8..73b4034b0 100644 --- a/.gitlab/ci/jobs/macos-x86_64.yml +++ b/.gitlab/ci/jobs/macos-x86_64.yml @@ -3,67 +3,30 @@ osxcross x86_64: stage: build - cache: - - key: ccache-$CI_JOB_NAME_SLUG-$CI_COMMIT_REF_SLUG - fallback_keys: - - ccache-$CI_JOB_NAME_SLUG-$CI_DEFAULT_BRANCH - - ccache-$CI_JOB_NAME_SLUG-master - paths: - - build/ccache - - build/ccache_statslog - - - key: apt-$CI_JOB_IMAGE - paths: - - build/apt-cache - unprotect: true - - - key: vcpkg-root - paths: - - build/vcpkg-root - unprotect: true - - - key: vcpkg-binary-cache-x64-osx - paths: - - build/vcpkg-binary-cache - unprotect: true + allow_failure: true 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 + OSXCROSS_HOST: o64 + CMAKE_TOOLCHAIN_FILE: /osxcross/toolchain.cmake + LD: /opt/osxcross.x86_64/ld 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" - - - | # 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 libopenmpt || osxcross-macports install --verbose libopenmpt || true + - osxcross-macports install wavpack || osxcross-macports install --verbose wavpack || true + - osxcross-macports install libxmp opusfile || osxcross-macports install --verbose libxmp opusfile + - osxcross-macports install --static libsdl2_mixer || osxcross-macports install --verbose --static libsdl2_mixer || true + - osxcross-macports install --static curl || osxcross-macports install --verbose --static curl || true + - osxcross-macports install --static miniupnpc libpng || osxcross-macports install --verbose --static miniupnpc libpng - | # apt_development echo -e "\e[0Ksection_end:`date +%s`:macports_development\r\e[0K" @@ -71,7 +34,19 @@ osxcross x86_64: - - | # cmake echo -e "\e[0Ksection_start:`date +%s`:cmake[collapsed=false]\r\e[0KBuilding Makefiles" - - cmake -B build.osxcross --toolchain /osxcross/toolchain.cmake -DCPM_USE_LOCAL_PACKAGES:BOOL=ON -DOPENMPT_INCLUDE_DIR:PATH="/osxcross/macports/pkgs/opt/local/include" -DSDL2_INCLUDE_DIR:PATH="/osxcross/macports/pkgs/opt/local/lib" -DSRB2_CONFIG_ENABLE_TESTS:BOOL=OFF -DSRB2_CONFIG_SYSTEM_LIBRARIES:BOOL=ON -DSRB2_CONFIG_USE_GME:BOOL=OFF -G "Unix Makefiles" + - | + cmake \ + -B build.x86_64 \ + -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_CONFIG_USE_GME:BOOL=OFF \ + -DSRB2_SDL2_EXE_NAME=srb2_$CI_PIPELINE_ID - | # make echo -e "\e[0Ksection_end:`date +%s`:make\r\e[0K" @@ -79,11 +54,21 @@ osxcross x86_64: - - | # make echo -e "\e[0Ksection_start:`date +%s`:make[collapsed=false]\r\e[0KCompiling SRB2" - - make --directory=build.osxcross --keep-going || make --directory=build.osxcross --keep-going + - cmake --build build.x86_64 --parallel 1 -- --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.x86_64/dist + - cp --reflink=auto --sparse=always --verbose build.x86_64/src/config.h build.x86_64/dist/x86_64.h + - | + # make + echo -e "\e[0Ksection_end:`date +%s`:copy\r\e[0K" + + after_script: - - | # apt_clean @@ -93,18 +78,6 @@ osxcross x86_64: # 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:" diff --git a/.gitlab/ci/jobs/osxcross-universal.yml b/.gitlab/ci/jobs/osxcross-universal.yml new file mode 100644 index 000000000..e76f6dda4 --- /dev/null +++ b/.gitlab/ci/jobs/osxcross-universal.yml @@ -0,0 +1,69 @@ +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 + + allow_failure: true + + 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-darwin" + + script: + - - | + # mkdir + echo -e "\e[0Ksection_start:`date +%s`:mkdir[collapsed=true]\r\e[0KMaking dist folder" + mkdir --parents --verbose dist/src dist/bin + - | + # mkdir + echo -e "\e[0Ksection_end:`date +%s`:mkdir\r\e[0K" + + - - | + # copy-config + echo -e "\e[0Ksection_start:`date +%s`:x86_64-config[collapsed=true]\r\e[0KCopying x86_64 config" + - cp --reflink=auto --sparse=always --verbose --target-directory=dist/src/ build.*/dist/*.h + - | + # x86_64-config + echo -e "\e[0Ksection_end:`date +%s`:x86_64-config\r\e[0K" + + - - | + # copy-build + echo -e "\e[0Ksection_start:`date +%s`:copy-build[collapsed=true]\r\e[0KCopying ALL build" + - cp --reflink=auto --sparse=always --recursive --verbose --target-directory=dist/ build.*/bin/ + - | + # copy-build + echo -e "\e[0Ksection_end:`date +%s`:copy-build\r\e[0K" + + - - | + # link-build + echo -e "\e[0Ksection_start:`date +%s`:link-build[collapsed=true]\r\e[0KLinking universal build" + - lipo -create -output dist/bin/srb2_$CI_PIPELINE_ID.app/Contents/MacOS/srb2_$CI_PIPELINE_ID build.*/bin/srb2_$CI_PIPELINE_ID.app/Contents/MacOS/srb2_$CI_PIPELINE_ID + - | + # universal-build + echo -e "\e[0Ksection_end:`date +%s`:link-build\r\e[0K" + + - - | + # arm64-verify + echo -e "\e[0Ksection_start:`date +%s`:arm64-verify[collapsed=true]\r\e[0KVerifying arm64" + - lipo dist/bin/srb2_$CI_PIPELINE_ID.app/Contents/MacOS/srb2_$CI_PIPELINE_ID -verify_arch arm64 + - | + # arm64-verify + echo -e "\e[0Ksection_end:`date +%s`:arm64-verify\r\e[0K" + + - - | + # x86_64-verify + echo -e "\e[0Ksection_start:`date +%s`:x86_64-verify[collapsed=true]\r\e[0KVerifying x86_64" + - lipo dist/bin/srb2_$CI_PIPELINE_ID.app/Contents/MacOS/srb2_$CI_PIPELINE_ID -verify_arch x86_64 + - | + # x86_64-verify + echo -e "\e[0Ksection_end:`date +%s`:x86_64-verify\r\e[0K" diff --git a/.gitlab/ci/jobs/windows-x64-makefile.yml b/.gitlab/ci/jobs/windows-x64-makefile.yml index 8da30d2b9..aea9de4ce 100644 --- a/.gitlab/ci/jobs/windows-x64-makefile.yml +++ b/.gitlab/ci/jobs/windows-x64-makefile.yml @@ -16,6 +16,8 @@ Windows x64 Makefile: variables: PREFIX: x86_64-w64-mingw32 + CC: /usr/bin/x86_64-w64-mingw32-gcc + CXX: /usr/bin/x86_64-w64-mingw32-g++ script: - - | diff --git a/.gitlab/ci/jobs/windows-x64.yml b/.gitlab/ci/jobs/windows-x64.yml index e5accf926..6db0de9a7 100644 --- a/.gitlab/ci/jobs/windows-x64.yml +++ b/.gitlab/ci/jobs/windows-x64.yml @@ -7,6 +7,25 @@ Windows x64: allow_failure: true + cache: + - key: ccache-$CI_JOB_NAME_SLUG-$CI_COMMIT_REF_SLUG + fallback_keys: + - ccache-$CI_JOB_NAME_SLUG-$CI_DEFAULT_BRANCH + - ccache-$CI_JOB_NAME_SLUG-master + paths: + - build/ccache + - build/ccache_statslog + + - key: apt-$CI_JOB_IMAGE + paths: + - build/apt-cache + unprotect: true + + - key: vcpkg-binary-cache-x64-mingw-static + paths: + - build/vcpkg-binary-cache + unprotect: true + artifacts: paths: - "build.cmake/bin/" @@ -15,9 +34,22 @@ 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" @@ -37,7 +69,16 @@ Windows x64: - - | # cmake echo -e "\e[0Ksection_start:`date +%s`:cmake[collapsed=false]\r\e[0KBuilding Makefiles" - - cmake -B build.cmake -DSRB2_USE_CCACHE=YES -DSRB2_CONFIG_ERRORMODE=ON -DCMAKE_TOOLCHAIN_FILE=$VCPKG_ROOT/scripts/buildsystems/vcpkg.cmake -DVCPKG_TARGET_TRIPLET=x64-mingw-static -DVCPKG_CHAINLOAD_TOOLCHAIN_FILE=$VCPKG_ROOT/scripts/toolchains/mingw.cmake + - | + cmake \ + -B build.cmake \ + -G "Unix Makefiles" \ + -DCMAKE_COLOR_DIAGNOSTICS=OFF \ + -DSRB2_CONFIG_ENABLE_WEBM_MOVIES=OFF \ + -DSRB2_CONFIG_ERRORMODE=ON \ + -DCMAKE_TOOLCHAIN_FILE=${VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake \ + -DVCPKG_TARGET_TRIPLET=${VCPKG_TARGET_TRIPLET} \ + -DVCPKG_CHAINLOAD_TOOLCHAIN_FILE=$VCPKG_ROOT/scripts/toolchains/mingw.cmake - | # cmake echo -e "\e[0Ksection_end:`date +%s`:cmake\r\e[0K" @@ -45,7 +86,7 @@ Windows x64: - - | # make echo -e "\e[0Ksection_start:`date +%s`:make[collapsed=false]\r\e[0KCompiling SRB2" - - make --directory=build.cmake --keep-going || make --directory=build.cmake --keep-going + - cmake --build build.cmake --parallel 1 -- --keep-going - | # make echo -e "\e[0Ksection_end:`date +%s`:make\r\e[0K" diff --git a/.gitlab/ci/jobs/windows-x86.yml b/.gitlab/ci/jobs/windows-x86.yml index f983c8287..0a1b24e18 100644 --- a/.gitlab/ci/jobs/windows-x86.yml +++ b/.gitlab/ci/jobs/windows-x86.yml @@ -3,10 +3,6 @@ Windows x86: stage: build - when: manual - - allow_failure: true - cache: - key: ccache-$CI_JOB_NAME_SLUG-$CI_COMMIT_REF_SLUG fallback_keys: @@ -21,11 +17,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 @@ -33,33 +24,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" @@ -84,9 +65,16 @@ Windows x86: - - | # cmake echo -e "\e[0Ksection_start:`date +%s`:cmake[collapsed=false]\r\e[0KBuilding Makefiles" - # cmake - echo -e "\e[0Ksection_start:`date +%s`:cmake[collapsed=false]\r\e[0KBuilding Makefiles" - - cmake --preset ninja-x86_mingw_static_vcpkg-debug -G "Unix Makefiles" -DSRB2_USE_CCACHE=YES -DSRB2_CONFIG_ERRORMODE=ON -DCMAKE_TOOLCHAIN_FILE=$VCPKG_ROOT/scripts/buildsystems/vcpkg.cmake + - | + cmake \ + -B build.cmake \ + -G "Unix Makefiles" \ + -DCMAKE_COLOR_DIAGNOSTICS=OFF \ + -DSRB2_CONFIG_ENABLE_WEBM_MOVIES=OFF \ + -DSRB2_CONFIG_ERRORMODE=ON \ + -DCMAKE_TOOLCHAIN_FILE=${VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake \ + -DVCPKG_TARGET_TRIPLET=${VCPKG_TARGET_TRIPLET} \ + -DVCPKG_CHAINLOAD_TOOLCHAIN_FILE=$VCPKG_ROOT/scripts/toolchains/mingw.cmake - | # cmake echo -e "\e[0Ksection_end:`date +%s`:cmake\r\e[0K" @@ -94,37 +82,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" diff --git a/.gitlab/ci/templates/srb2ci.yml b/.gitlab/ci/templates/srb2ci.yml index bdf8a3ed6..765048614 100644 --- a/.gitlab/ci/templates/srb2ci.yml +++ b/.gitlab/ci/templates/srb2ci.yml @@ -93,26 +93,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" diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 2cfb56f6e..fbc341733 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -464,8 +464,13 @@ else() endif() if(TARGET miniupnpc::miniupnpc) - target_compile_definitions(SRB2SDL2 PRIVATE -DHAVE_MINIUPNPC) - target_link_libraries(SRB2SDL2 PRIVATE miniupnpc::miniupnpc) + if("${VCPKG_TARGET_TRIPLET}" MATCHES "-mingw-static$") + target_compile_definitions(SRB2SDL2 PRIVATE -DHAVE_MINIUPNPC -DMINIUPNP_STATICLIB) + target_link_libraries(SRB2SDL2 PRIVATE miniupnpc::miniupnpc -liphlpapi) + else() + target_compile_definitions(SRB2SDL2 PRIVATE -DHAVE_MINIUPNPC) + target_link_libraries(SRB2SDL2 PRIVATE miniupnpc::miniupnpc) + endif() message(STATUS "miniupnpc Found") else() message(STATUS "No miniupnpc Found") diff --git a/src/blua/CMakeLists.txt b/src/blua/CMakeLists.txt index 892bf534a..21278f2bb 100644 --- a/src/blua/CMakeLists.txt +++ b/src/blua/CMakeLists.txt @@ -1,6 +1,7 @@ target_sources(SRB2SDL2 PRIVATE lapi.c lbaselib.c + ldblib.c ldo.c lfunc.c linit.c diff --git a/src/blua/Sourcefile b/src/blua/Sourcefile index dae943109..2b6b96366 100644 --- a/src/blua/Sourcefile +++ b/src/blua/Sourcefile @@ -1,6 +1,7 @@ lapi.c lbaselib.c ldo.c +ldblib.c lfunc.c linit.c liolib.c diff --git a/src/blua/ldblib.c b/src/blua/ldblib.c new file mode 100644 index 000000000..2eacef929 --- /dev/null +++ b/src/blua/ldblib.c @@ -0,0 +1,310 @@ +/* +** $Id: ldblib.c,v 1.104.1.4 2009/08/04 18:50:18 roberto Exp $ +** Interface from Lua to its debug API +** See Copyright Notice in lua.h +*/ + + +#include +#include +#include + +#define ldblib_c +#define LUA_LIB + +#include "lua.h" + +#include "lauxlib.h" +#include "lualib.h" + + + +static void settabss (lua_State *L, const char *i, const char *v) { + lua_pushstring(L, v); + lua_setfield(L, -2, i); +} + + +static void settabsi (lua_State *L, const char *i, int v) { + lua_pushinteger(L, v); + lua_setfield(L, -2, i); +} + + +static lua_State *getthread (lua_State *L, int *arg) { + if (lua_isthread(L, 1)) { + *arg = 1; + return lua_tothread(L, 1); + } + else { + *arg = 0; + return L; + } +} + + +static void treatstackoption (lua_State *L, lua_State *L1, const char *fname) { + if (L == L1) { + lua_pushvalue(L, -2); + lua_remove(L, -3); + } + else + lua_xmove(L1, L, 1); + lua_setfield(L, -2, fname); +} + + +static int db_getinfo (lua_State *L) { + lua_Debug ar; + int arg; + lua_State *L1 = getthread(L, &arg); + const char *options = luaL_optstring(L, arg+2, "flnSu"); + if (lua_isnumber(L, arg+1)) { + if (!lua_getstack(L1, (int)lua_tointeger(L, arg+1), &ar)) { + lua_pushnil(L); /* level out of range */ + return 1; + } + } + else if (lua_isfunction(L, arg+1)) { + lua_pushfstring(L, ">%s", options); + options = lua_tostring(L, -1); + lua_pushvalue(L, arg+1); + lua_xmove(L, L1, 1); + } + else + return luaL_argerror(L, arg+1, "function or level expected"); + if (!lua_getinfo(L1, options, &ar)) + return luaL_argerror(L, arg+2, "invalid option"); + lua_createtable(L, 0, 2); + if (strchr(options, 'S')) { + settabss(L, "source", ar.source); + settabss(L, "short_src", ar.short_src); + settabsi(L, "linedefined", ar.linedefined); + settabsi(L, "lastlinedefined", ar.lastlinedefined); + settabss(L, "what", ar.what); + } + if (strchr(options, 'l')) + settabsi(L, "currentline", ar.currentline); + if (strchr(options, 'u')) + settabsi(L, "nups", ar.nups); + if (strchr(options, 'n')) { + settabss(L, "name", ar.name); + settabss(L, "namewhat", ar.namewhat); + } + if (strchr(options, 'L')) + treatstackoption(L, L1, "activelines"); + if (strchr(options, 'f')) + treatstackoption(L, L1, "func"); + return 1; /* return table */ +} + + +static int db_getlocal (lua_State *L) { + int arg; + lua_State *L1 = getthread(L, &arg); + lua_Debug ar; + const char *name; + if (!lua_getstack(L1, luaL_checkint(L, arg+1), &ar)) /* out of range? */ + return luaL_argerror(L, arg+1, "level out of range"); + name = lua_getlocal(L1, &ar, luaL_checkint(L, arg+2)); + if (name) { + lua_xmove(L1, L, 1); + lua_pushstring(L, name); + lua_pushvalue(L, -2); + return 2; + } + else { + lua_pushnil(L); + return 1; + } +} + + +static int auxupvalue (lua_State *L, int get) { + const char *name; + int n = luaL_checkint(L, 2); + luaL_checktype(L, 1, LUA_TFUNCTION); + if (lua_iscfunction(L, 1)) return 0; /* cannot touch C upvalues from Lua */ + name = get ? lua_getupvalue(L, 1, n) : lua_setupvalue(L, 1, n); + if (name == NULL) return 0; + lua_pushstring(L, name); + lua_insert(L, -(get+1)); + return get + 1; +} + + +static int db_getupvalue (lua_State *L) { + return auxupvalue(L, 1); +} + + + +static char KEY_HOOK = 'h'; + + +static void hookf (lua_State *L, lua_Debug *ar) { + static const char *const hooknames[] = + {"call", "return", "line", "count", "tail return"}; + lua_pushlightuserdata(L, (void *)&KEY_HOOK); + lua_rawget(L, LUA_REGISTRYINDEX); + lua_pushlightuserdata(L, L); + lua_rawget(L, -2); + if (lua_isfunction(L, -1)) { + lua_pushstring(L, hooknames[(int)ar->event]); + if (ar->currentline >= 0) + lua_pushinteger(L, ar->currentline); + else lua_pushnil(L); + lua_assert(lua_getinfo(L, "lS", ar)); + lua_call(L, 2, 0); + } +} + + +static int makemask (const char *smask, int count) { + int mask = 0; + if (strchr(smask, 'c')) mask |= LUA_MASKCALL; + if (strchr(smask, 'r')) mask |= LUA_MASKRET; + if (strchr(smask, 'l')) mask |= LUA_MASKLINE; + if (count > 0) mask |= LUA_MASKCOUNT; + return mask; +} + + +static char *unmakemask (int mask, char *smask) { + int i = 0; + if (mask & LUA_MASKCALL) smask[i++] = 'c'; + if (mask & LUA_MASKRET) smask[i++] = 'r'; + if (mask & LUA_MASKLINE) smask[i++] = 'l'; + smask[i] = '\0'; + return smask; +} + + +static void gethooktable (lua_State *L) { + lua_pushlightuserdata(L, (void *)&KEY_HOOK); + lua_rawget(L, LUA_REGISTRYINDEX); + if (!lua_istable(L, -1)) { + lua_pop(L, 1); + lua_createtable(L, 0, 1); + lua_pushlightuserdata(L, (void *)&KEY_HOOK); + lua_pushvalue(L, -2); + lua_rawset(L, LUA_REGISTRYINDEX); + } +} + + +static int db_sethook (lua_State *L) { + int arg, mask, count; + lua_Hook func; + lua_State *L1 = getthread(L, &arg); + if (lua_isnoneornil(L, arg+1)) { + lua_settop(L, arg+1); + func = NULL; mask = 0; count = 0; /* turn off hooks */ + } + else { + const char *smask = luaL_checkstring(L, arg+2); + luaL_checktype(L, arg+1, LUA_TFUNCTION); + count = luaL_optint(L, arg+3, 0); + func = hookf; mask = makemask(smask, count); + } + gethooktable(L); + lua_pushlightuserdata(L, L1); + lua_pushvalue(L, arg+1); + lua_rawset(L, -3); /* set new hook */ + lua_pop(L, 1); /* remove hook table */ + lua_sethook(L1, func, mask, count); /* set hooks */ + return 0; +} + + +static int db_gethook (lua_State *L) { + int arg; + lua_State *L1 = getthread(L, &arg); + char buff[5]; + int mask = lua_gethookmask(L1); + lua_Hook hook = lua_gethook(L1); + if (hook != NULL && hook != hookf) /* external hook? */ + lua_pushliteral(L, "external hook"); + else { + gethooktable(L); + lua_pushlightuserdata(L, L1); + lua_rawget(L, -2); /* get hook */ + lua_remove(L, -2); /* remove hook table */ + } + lua_pushstring(L, unmakemask(mask, buff)); + lua_pushinteger(L, lua_gethookcount(L1)); + return 3; +} + + +#define LEVELS1 12 /* size of the first part of the stack */ +#define LEVELS2 10 /* size of the second part of the stack */ + +static int db_errorfb (lua_State *L) { + int level; + int firstpart = 1; /* still before eventual `...' */ + int arg; + lua_State *L1 = getthread(L, &arg); + lua_Debug ar; + if (lua_isnumber(L, arg+2)) { + level = (int)lua_tointeger(L, arg+2); + lua_pop(L, 1); + } + else + level = (L == L1) ? 1 : 0; /* level 0 may be this own function */ + if (lua_gettop(L) == arg) + lua_pushliteral(L, ""); + else if (!lua_isstring(L, arg+1)) return 1; /* message is not a string */ + else lua_pushliteral(L, "\n"); + lua_pushliteral(L, "stack traceback:"); + while (lua_getstack(L1, level++, &ar)) { + if (level > LEVELS1 && firstpart) { + /* no more than `LEVELS2' more levels? */ + if (!lua_getstack(L1, level+LEVELS2, &ar)) + level--; /* keep going */ + else { + lua_pushliteral(L, "\n\t..."); /* too many levels */ + while (lua_getstack(L1, level+LEVELS2, &ar)) /* find last levels */ + level++; + } + firstpart = 0; + continue; + } + lua_pushliteral(L, "\n\t"); + lua_getinfo(L1, "Snl", &ar); + lua_pushfstring(L, "%s:", ar.short_src); + if (ar.currentline > 0) + lua_pushfstring(L, "%d:", ar.currentline); + if (*ar.namewhat != '\0') /* is there a name? */ + lua_pushfstring(L, " in function " LUA_QS, ar.name); + else { + if (*ar.what == 'm') /* main? */ + lua_pushfstring(L, " in main chunk"); + else if (*ar.what == 'C' || *ar.what == 't') + lua_pushliteral(L, " ?"); /* C function or tail call */ + else + lua_pushfstring(L, " in function <%s:%d>", + ar.short_src, ar.linedefined); + } + lua_concat(L, lua_gettop(L) - arg); + } + lua_concat(L, lua_gettop(L) - arg); + return 1; +} + + +static const luaL_Reg dblib[] = { + {"gethook", db_gethook}, + {"getinfo", db_getinfo}, + {"getlocal", db_getlocal}, + {"getupvalue", db_getupvalue}, + {"sethook", db_sethook}, + {"traceback", db_errorfb}, + {NULL, NULL} +}; + + +LUALIB_API int luaopen_debug (lua_State *L) { + luaL_register(L, LUA_DBLIBNAME, dblib); + return 1; +} diff --git a/src/blua/linit.c b/src/blua/linit.c index dcf05d9f2..392d45dce 100644 --- a/src/blua/linit.c +++ b/src/blua/linit.c @@ -20,6 +20,7 @@ static const luaL_Reg lualibs[] = { {LUA_IOLIBNAME, luaopen_io}, {LUA_OSLIBNAME, luaopen_os}, {LUA_STRLIBNAME, luaopen_string}, + {LUA_DBLIBNAME, luaopen_debug}, {NULL, NULL} }; diff --git a/src/blua/lualib.h b/src/blua/lualib.h index 7127e4d77..70facb70c 100644 --- a/src/blua/lualib.h +++ b/src/blua/lualib.h @@ -30,6 +30,9 @@ LUALIB_API int (luaopen_os) (lua_State *L); #define LUA_STRLIBNAME "string" LUALIB_API int (luaopen_string) (lua_State *L); +#define LUA_DBLIBNAME "debug" +LUALIB_API int (luaopen_debug) (lua_State *L); + /* open all previous libraries */ LUALIB_API void (luaL_openlibs) (lua_State *L); diff --git a/src/command.c b/src/command.c index ab6cfc08a..bc24d5e05 100644 --- a/src/command.c +++ b/src/command.c @@ -2482,6 +2482,22 @@ static boolean CV_FilterVarByVersion(consvar_t *v, const char *valstr) if (!CV_FilterJoyAxisVars(v, valstr)) return false; } + + if (GETMAJOREXECVERSION(cv_execversion.value) < 57) // 57 = 2.2.16 + { + if ( + (!stricmp(v->name, "movebob") && atoi(valstr) == FRACUNIT) || + (!stricmp(v->name, "playersforexit") && atoi(valstr) == 4) || // 4 = all + (!stricmp(v->name, "advancemap") && atoi(valstr) == 1) || // 1 = next + (!stricmp(v->name, "cam_speed") && !stricmp(valstr, "0.3")) || + (!stricmp(v->name, "cam2_speed") && !stricmp(valstr, "0.3")) || + (!stricmp(v->name, "timerres") && atoi(valstr) == 0) || // 0 = classic + (!stricmp(v->name, "gr_modelinterpolation")) || // Force reset + (!stricmp(v->name, "fov") && atoi(valstr) == 90) + ) + return false; + } + return true; } diff --git a/src/d_player.h b/src/d_player.h index cdb547d3b..1dc3fb529 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -2,7 +2,7 @@ //----------------------------------------------------------------------------- // Copyright (C) 1993-1996 by id Software, Inc. // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2024 by Sonic Team Junior. +// Copyright (C) 1999-2025 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. @@ -47,13 +47,14 @@ typedef enum SF_DASHMODE = 1<<11, // Sonic Advance 2 style top speed increase? SF_FASTWAIT = 1<<12, // Faster wait animation? SF_FASTEDGE = 1<<13, // Faster edge teeter? - SF_MULTIABILITY = 1<<14, // Revenge of Final Demo. - SF_NONIGHTSROTATION = 1<<15, // Disable sprite rotation for NiGHTS - SF_NONIGHTSSUPER = 1<<16, // Disable super colors for NiGHTS (if you have SF_SUPER) - SF_NOSUPERSPRITES = 1<<17, // Don't use super sprites while super - SF_NOSUPERJUMPBOOST = 1<<18, // Disable the jump boost given while super (i.e. Knuckles) - SF_CANBUSTWALLS = 1<<19, // Can naturally bust walls on contact? (i.e. Knuckles) - SF_NOSHIELDABILITY = 1<<20, // Disable shield abilities + SF_JETFUME = 1<<14, // Follow item uses Metal Sonic's jet fume behavior + SF_MULTIABILITY = 1<<15, // Revenge of Final Demo. + SF_NONIGHTSROTATION = 1<<16, // Disable sprite rotation for NiGHTS + SF_NONIGHTSSUPER = 1<<17, // Disable super sprites and colors for NiGHTS + SF_NOSUPERSPRITES = 1<<18, // Don't use super sprites while super + SF_NOSUPERJUMPBOOST = 1<<19, // Disable the jump boost given while super (i.e. Knuckles) + SF_CANBUSTWALLS = 1<<20, // Can naturally bust walls on contact? (i.e. Knuckles) + SF_NOSHIELDABILITY = 1<<21, // Disable shield abilities // free up to and including 1<<31 } skinflags_t; diff --git a/src/deh_tables.c b/src/deh_tables.c index d71463253..a96adf8ae 100644 --- a/src/deh_tables.c +++ b/src/deh_tables.c @@ -1,7 +1,7 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2024 by Sonic Team Junior. +// Copyright (C) 1999-2025 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. @@ -5260,6 +5260,7 @@ struct int_const_s const INT_CONST[] = { {"SF_DASHMODE",SF_DASHMODE}, {"SF_FASTWAIT",SF_FASTWAIT}, {"SF_FASTEDGE",SF_FASTEDGE}, + {"SF_JETFUME",SF_JETFUME}, {"SF_MULTIABILITY",SF_MULTIABILITY}, {"SF_NONIGHTSROTATION",SF_NONIGHTSROTATION}, {"SF_NONIGHTSSUPER",SF_NONIGHTSSUPER}, diff --git a/src/hardware/hw_draw.c b/src/hardware/hw_draw.c index 369f59ac2..ab253d5c8 100644 --- a/src/hardware/hw_draw.c +++ b/src/hardware/hw_draw.c @@ -256,8 +256,8 @@ void HWR_DrawStretchyFixedPatch(patch_t *gpatch, fixed_t x, fixed_t y, fixed_t p } // positions of the cx, cy, are between 0 and vid.width/vid.height now, we need them to be between -1 and 1 - cx = -1 + (cx / (vid.width/2)); - cy = 1 - (cy / (vid.height/2)); + cx = -1.0f + (cx / (vid.width / 2.0f)); + cy = 1.0f - (cy / (vid.height / 2.0f)); // fwidth and fheight are similar fwidth /= vid.width / 2; diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index a5befe112..d84322dfd 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -2671,45 +2671,31 @@ fixed_t *hwbbox; static void HWR_RenderBSPNode(INT32 bspnum) { - node_t *bsp = &nodes[bspnum]; - - // Decide which side the view point is on + node_t *bsp; INT32 side; ps_numbspcalls.value.i++; - // Found a subsector? - if (bspnum & NF_SUBSECTOR) + while (!(bspnum & NF_SUBSECTOR)) // Found a subsector? { - if (bspnum == -1) - { - //*(gl_drawsubsector_p++) = 0; - HWR_Subsector(0); - } - else - { - //*(gl_drawsubsector_p++) = bspnum&(~NF_SUBSECTOR); - HWR_Subsector(bspnum&(~NF_SUBSECTOR)); - } - return; - } + bsp = &nodes[bspnum]; - // Decide which side the view point is on. - side = R_PointOnSide(viewx, viewy, bsp); - - // BP: big hack for a test in lighning ref : 1249753487AB - hwbbox = bsp->bbox[side]; - - // Recursively divide front space. - HWR_RenderBSPNode(bsp->children[side]); - - // Possibly divide back space. - if (HWR_CheckBBox(bsp->bbox[side^1])) - { + // Decide which side the view point is on. + side = R_PointOnSide(viewx, viewy, bsp); // BP: big hack for a test in lighning ref : 1249753487AB - hwbbox = bsp->bbox[side^1]; - HWR_RenderBSPNode(bsp->children[side^1]); + hwbbox = bsp->bbox[side]; + // Recursively divide front space. + HWR_RenderBSPNode(bsp->children[side]); + + // Possibly divide back space. + + if (!HWR_CheckBBox(bsp->bbox[side^1])) + return; + + bspnum = bsp->children[side^1]; } + + HWR_Subsector(bspnum == -1 ? 0 : bspnum & ~NF_SUBSECTOR); } // ========================================================================== @@ -5675,7 +5661,6 @@ void HWR_LoadLevel(void) // ========================================================================== static CV_PossibleValue_t glshaders_cons_t[] = {{0, "Off"}, {1, "On"}, {2, "Ignore custom shaders"}, {0, NULL}}; -static CV_PossibleValue_t glmodelinterpolation_cons_t[] = {{0, "Off"}, {1, "Sometimes"}, {2, "Always"}, {0, NULL}}; static CV_PossibleValue_t glfakecontrast_cons_t[] = {{0, "Off"}, {1, "On"}, {2, "Smooth"}, {0, NULL}}; static CV_PossibleValue_t glshearing_cons_t[] = {{0, "Off"}, {1, "On"}, {2, "Third-person"}, {0, NULL}}; @@ -5704,7 +5689,7 @@ consvar_t cv_glcoronasize = CVAR_INIT ("gr_coronasize", "1", CV_SAVE|CV_FLOAT, 0 #endif consvar_t cv_glmodels = CVAR_INIT ("gr_models", "Off", CV_SAVE, CV_OnOff, NULL); -consvar_t cv_glmodelinterpolation = CVAR_INIT ("gr_modelinterpolation", "Sometimes", CV_SAVE, glmodelinterpolation_cons_t, NULL); +consvar_t cv_glmodelinterpolation = CVAR_INIT ("gr_modelinterpolation", "On", CV_SAVE, CV_OnOff, NULL); consvar_t cv_glmodellighting = CVAR_INIT ("gr_modellighting", "Off", CV_SAVE|CV_CALL, CV_OnOff, CV_glmodellighting_OnChange); consvar_t cv_glshearing = CVAR_INIT ("gr_shearing", "Off", CV_SAVE, glshearing_cons_t, NULL); diff --git a/src/hardware/hw_md2.c b/src/hardware/hw_md2.c index 931867142..ce2c2c346 100644 --- a/src/hardware/hw_md2.c +++ b/src/hardware/hw_md2.c @@ -1062,15 +1062,11 @@ static boolean HWR_AllowModel(mobj_t *mobj) static boolean HWR_CanInterpolateModel(mobj_t *mobj, model_t *model) { - if (cv_glmodelinterpolation.value == 2) // Always interpolate - return true; return model->interpolate[(mobj->frame & FF_FRAMEMASK)]; } static boolean HWR_CanInterpolateSprite2(modelspr2frames_t *spr2frame) { - if (cv_glmodelinterpolation.value == 2) // Always interpolate - return true; return spr2frame->interpolate; } diff --git a/src/info.c b/src/info.c index 4d3468e10..3998eb88d 100644 --- a/src/info.c +++ b/src/info.c @@ -2,7 +2,7 @@ //----------------------------------------------------------------------------- // Copyright (C) 1993-1996 by id Software, Inc. // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2024 by Sonic Team Junior. +// Copyright (C) 1999-2025 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. @@ -4187,7 +4187,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // painstate 0, // painchance sfx_None, // painsound - S_NULL, // meleestate + S_JETFUMEFLASH, // meleestate S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate diff --git a/src/lua_baselib.c b/src/lua_baselib.c index ecd1ee55e..1ffa3968b 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -3166,7 +3166,10 @@ static int lib_rCheckTextureNumForName(lua_State *L) { const char *name = luaL_checkstring(L, 1); //HUDSAFE - lua_pushinteger(L, R_CheckTextureNumForName(name)); + INT32 num = R_CheckTextureNumForName(name, TEXTURETYPE_TEXTURE); + if (num == -1) + num = R_CheckTextureNumForName(name, TEXTURETYPE_FLAT); + lua_pushinteger(L, num); return 1; } diff --git a/src/m_menu.c b/src/m_menu.c index 37d191a0d..be1b421f7 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -3892,6 +3892,9 @@ void M_Ticker(void) M_SetupScreenshotMenu(); #if defined (MASTERSERVER) && defined (HAVE_THREADS) + if (!netgame) + return; + I_lock_mutex(&ms_ServerList_mutex); { if (ms_ServerList) diff --git a/src/netcode/d_clisrv.c b/src/netcode/d_clisrv.c index 6702e2591..7a5fb06a6 100644 --- a/src/netcode/d_clisrv.c +++ b/src/netcode/d_clisrv.c @@ -673,6 +673,7 @@ void D_QuitNetGame(void) HSendPacket(servernode, true, 0, 0); } + seenplayer = NULL; D_CloseConnection(); ClearAdminPlayers(); diff --git a/src/netcode/d_net.c b/src/netcode/d_net.c index 4860d8688..a3a47b950 100644 --- a/src/netcode/d_net.c +++ b/src/netcode/d_net.c @@ -163,12 +163,6 @@ typedef struct // ack return to send (like sliding window protocol) UINT8 firstacktosend; - // when no consecutive packets are received we keep in mind what packets - // we already received in a queue - UINT8 acktosend_head; - UINT8 acktosend_tail; - UINT8 acktosend[MAXACKTOSEND]; - // automatically send keep alive packet when not enough trafic tic_t lasttimeacktosend_sent; // detect connection lost @@ -200,10 +194,9 @@ FUNCMATH static INT32 cmpack(UINT8 a, UINT8 b) /** Sets freeack to a free acknum and copies the netbuffer in the ackpak table * * \param freeack The address to store the free acknum at - * \param lowtimer ??? * \return True if a free acknum was found */ -static boolean GetFreeAcknum(UINT8 *freeack, boolean lowtimer) +static boolean GetFreeAcknum(UINT8 *freeack) { node_t *node = &nodes[doomcom->remotenode]; INT32 numfreeslot = 0; @@ -232,17 +225,8 @@ static boolean GetFreeAcknum(UINT8 *freeack, boolean lowtimer) node->nextacknum++; ackpak[i].destinationnode = (UINT8)(node - nodes); ackpak[i].length = doomcom->datalength; - if (lowtimer) - { - // Lowtime means can't be sent now so try it as soon as possible - ackpak[i].senttime = 0; - ackpak[i].resentnum = 1; - } - else - { - ackpak[i].senttime = I_GetTime(); - ackpak[i].resentnum = 0; - } + ackpak[i].senttime = I_GetTime(); + ackpak[i].resentnum = 0; M_Memcpy(ackpak[i].pak.raw, netbuffer, ackpak[i].length); *freeack = ackpak[i].acknum; @@ -259,38 +243,6 @@ static boolean GetFreeAcknum(UINT8 *freeack, boolean lowtimer) return false; } -/** Counts how many acks are free - * - * \param urgent True if the type of the packet meant to - * use an ack is lower than PT_CANFAIL - * If for some reason you don't want use it - * for any packet type in particular, - * just set to false - * \return The number of free acks - * - */ -INT32 Net_GetFreeAcks(boolean urgent) -{ - INT32 numfreeslot = 0; - INT32 n = 0; // Number of free acks found - - for (INT32 i = 0; i < MAXACKPACKETS; i++) - if (!ackpak[i].acknum) - { - // For low priority packets, make sure to let freeslots so urgent packets can be sent - if (!urgent) - { - numfreeslot++; - if (numfreeslot <= URGENTFREESLOTNUM) - continue; - } - - n++; - } - - return n; -} - // Get a ack to send in the queue of this node static UINT8 GetAcktosend(INT32 node) { @@ -308,9 +260,9 @@ static void RemoveAck(INT32 i) } // We have got a packet, proceed the ack request and ack return -static int Processackpak(void) +static boolean Processackpak(void) { - int goodpacket = 0; + boolean goodpacket = true; node_t *node = &nodes[doomcom->remotenode]; // Received an ack return, so remove the ack in the list @@ -319,7 +271,7 @@ static int Processackpak(void) node->remotefirstack = netbuffer->ackreturn; // Search the ackbuffer and free it for (INT32 i = 0; i < MAXACKPACKETS; i++) - if (ackpak[i].acknum && ackpak[i].destinationnode == node - nodes + if (ackpak[i].acknum && ackpak[i].destinationnode == doomcom->remotenode && cmpack(ackpak[i].acknum, netbuffer->ackreturn) <= 0) { RemoveAck(i); @@ -335,119 +287,32 @@ static int Processackpak(void) { DEBFILE(va("Discard(1) ack %d (duplicated)\n", ack)); duppacket++; - goodpacket = 1; // Discard packet (duplicate) + goodpacket = false; // Discard packet (duplicate) } else { - // Check if it is not already in the queue - for (INT32 i = node->acktosend_tail; i != node->acktosend_head; i = (i+1) % MAXACKTOSEND) - if (node->acktosend[i] == ack) - { - DEBFILE(va("Discard(2) ack %d (duplicated)\n", ack)); - duppacket++; - goodpacket = 1; // Discard packet (duplicate) - break; - } - if (goodpacket == 0) + // Is a good packet so increment the acknowledge number, + // Then search for a "hole" in the queue + UINT8 nextfirstack = (UINT8)(node->firstacktosend + 1); + if (!nextfirstack) + nextfirstack = 1; + + if (ack == nextfirstack) { - // Is a good packet so increment the acknowledge number, - // Then search for a "hole" in the queue - UINT8 nextfirstack = (UINT8)(node->firstacktosend + 1); - if (!nextfirstack) - nextfirstack = 1; - - if (ack == nextfirstack) - { - UINT8 hm1; // head - 1 - boolean change = true; - - node->firstacktosend = nextfirstack++; - if (!nextfirstack) - nextfirstack = 1; - hm1 = (UINT8)((node->acktosend_head-1+MAXACKTOSEND) % MAXACKTOSEND); - while (change) - { - change = false; - for (INT32 i = node->acktosend_tail; i != node->acktosend_head; - i = (i+1) % MAXACKTOSEND) - { - if (cmpack(node->acktosend[i], nextfirstack) <= 0) - { - if (node->acktosend[i] == nextfirstack) - { - node->firstacktosend = nextfirstack++; - if (!nextfirstack) - nextfirstack = 1; - change = true; - } - if (i == node->acktosend_tail) - { - node->acktosend[node->acktosend_tail] = 0; - node->acktosend_tail = (UINT8)((i+1) % MAXACKTOSEND); - } - else if (i == hm1) - { - node->acktosend[hm1] = 0; - node->acktosend_head = hm1; - hm1 = (UINT8)((hm1-1+MAXACKTOSEND) % MAXACKTOSEND); - } - } - } - } - } - else // Out of order packet - { - // Don't increment firsacktosend, put it in asktosend queue - // Will be incremented when the nextfirstack comes (code above) - UINT8 newhead = (UINT8)((node->acktosend_head+1) % MAXACKTOSEND); - DEBFILE(va("out of order packet (%d expected)\n", nextfirstack)); - if (newhead != node->acktosend_tail) - { - node->acktosend[node->acktosend_head] = ack; - node->acktosend_head = newhead; - } - else // Buffer full discard packet, sender will resend it - { // We can admit the packet but we will not detect the duplication after :( - DEBFILE("no more freeackret\n"); - goodpacket = 2; - } - } + node->firstacktosend = nextfirstack; + } + else // Out of order packet + { + // Don't increment firsacktosend, put it in asktosend queue + // Will be incremented when the nextfirstack comes (code above) + DEBFILE(va("out of order packet (%d expected)\n", nextfirstack)); + goodpacket = false; } } } - // return values: 0 = ok, 1 = duplicate, 2 = out of order return goodpacket; } -// send special packet with only ack on it -void Net_SendAcks(INT32 node) -{ - netbuffer->packettype = PT_NOTHING; - M_Memcpy(netbuffer->u.textcmd, nodes[node].acktosend, MAXACKTOSEND); - HSendPacket(node, false, 0, MAXACKTOSEND); -} - -static void GotAcks(void) -{ - for (INT32 j = 0; j < MAXACKTOSEND; j++) - if (netbuffer->u.textcmd[j]) - for (INT32 i = 0; i < MAXACKPACKETS; i++) - if (ackpak[i].acknum && ackpak[i].destinationnode == doomcom->remotenode) - { - if (ackpak[i].acknum == netbuffer->u.textcmd[j]) - RemoveAck(i); - // nextacknum is first equal to acknum, then when receiving bigger ack - // there is big chance the packet is lost - // When resent, nextacknum = nodes[node].nextacknum - // will redo the same but with different value - else if (cmpack(ackpak[i].nextacknum, netbuffer->u.textcmd[j]) <= 0 - && ackpak[i].senttime > 0) - { - ackpak[i].senttime--; // hurry up - } - } -} - void Net_ConnectionTimeout(INT32 node) { // Don't timeout several times @@ -501,11 +366,6 @@ void Net_AckTicker(void) // This is something like node open flag if (nodes[i].firstacktosend) { - // We haven't sent a packet for a long time - // Acknowledge packet if needed - if (nodes[i].lasttimeacktosend_sent + ACKTOSENDTIMEOUT < I_GetTime()) - Net_SendAcks(i); - if (!(nodes[i].flags & NF_CLOSE) && nodes[i].lasttimepacketreceived + connectiontimeout < I_GetTime()) { @@ -519,37 +379,12 @@ void Net_AckTicker(void) // (the higher layer doesn't have room, or something else ....) void Net_UnAcknowledgePacket(INT32 node) { - INT32 hm1 = (nodes[node].acktosend_head-1+MAXACKTOSEND) % MAXACKTOSEND; DEBFILE(va("UnAcknowledge node %d\n", node)); if (!node) return; - if (nodes[node].acktosend[hm1] == netbuffer->ack) - { - nodes[node].acktosend[hm1] = 0; - nodes[node].acktosend_head = (UINT8)hm1; - } - else if (nodes[node].firstacktosend == netbuffer->ack) - { - nodes[node].firstacktosend--; - if (!nodes[node].firstacktosend) - nodes[node].firstacktosend = UINT8_MAX; - } - else - { - while (nodes[node].firstacktosend != netbuffer->ack) - { - nodes[node].acktosend_tail = (UINT8) - ((nodes[node].acktosend_tail-1+MAXACKTOSEND) % MAXACKTOSEND); - nodes[node].acktosend[nodes[node].acktosend_tail] = nodes[node].firstacktosend; - - nodes[node].firstacktosend--; - if (!nodes[node].firstacktosend) - nodes[node].firstacktosend = UINT8_MAX; - } - nodes[node].firstacktosend++; - if (!nodes[node].firstacktosend) - nodes[node].firstacktosend = 1; - } + nodes[node].firstacktosend--; + if (!nodes[node].firstacktosend) + nodes[node].firstacktosend = UINT8_MAX; } /** Checks if all acks have been received @@ -592,7 +427,6 @@ void Net_WaitAllAckReceived(UINT32 timeout) static void InitNode(node_t *node) { - node->acktosend_head = node->acktosend_tail = 0; node->firstacktosend = 0; node->nextacknum = 1; node->remotefirstack = 0; @@ -651,11 +485,11 @@ void Net_CloseConnection(INT32 node) nodes[node].flags |= NF_CLOSE; - // try to Send ack back (two army problem) - if (GetAcktosend(node)) + if (nodes[node].firstacktosend) { - Net_SendAcks(node); - Net_SendAcks(node); + // send a PT_NOTHING back to acknowledge the packet + netbuffer->packettype = PT_NOTHING; + HSendPacket(node, false, 0, 0); } // check if we are waiting for an ack from this node @@ -991,7 +825,7 @@ boolean HSendPacket(INT32 node, boolean reliable, UINT8 acknum, size_t packetlen netbuffer->ackreturn = 0; if (reliable) { - if (!GetFreeAcknum(&netbuffer->ack, false)) + if (!GetFreeAcknum(&netbuffer->ack)) return false; } else @@ -1057,7 +891,6 @@ boolean HGetPacket(void) while(true) { //nodejustjoined = I_NetGet(); - int goodpacket; I_NetGet(); if (doomcom->remotenode == -1) // No packet received @@ -1103,22 +936,12 @@ boolean HGetPacket(void) }*/ // Proceed the ack and ackreturn field - goodpacket = Processackpak(); - if (goodpacket != 0) - { - // resend the ACK in case the previous ACK didn't reach the client. - // prevents the client's netbuffer from locking up. - if (goodpacket == 1) - Net_SendAcks(doomcom->remotenode); + if (!Processackpak()) continue; // discarded (duplicated) - } // A packet with just ackreturn if (netbuffer->packettype == PT_NOTHING) - { - GotAcks(); continue; - } break; } diff --git a/src/netcode/d_net.h b/src/netcode/d_net.h index 2f83939f8..6b3ee5e67 100644 --- a/src/netcode/d_net.h +++ b/src/netcode/d_net.h @@ -60,7 +60,6 @@ extern netnode_t netnodes[MAXNETNODES]; extern boolean serverrunning; -INT32 Net_GetFreeAcks(boolean urgent); void Net_AckTicker(void); // If reliable return true if packet sent, 0 else diff --git a/src/netcode/d_netcmd.c b/src/netcode/d_netcmd.c index 94170fa0d..35e28db36 100644 --- a/src/netcode/d_netcmd.c +++ b/src/netcode/d_netcmd.c @@ -320,7 +320,7 @@ consvar_t cv_overtime = CVAR_INIT ("overtime", "Yes", CV_SAVE|CV_NETVAR|CV_ALLOW consvar_t cv_rollingdemos = CVAR_INIT ("rollingdemos", "On", CV_SAVE, CV_OnOff, NULL); static CV_PossibleValue_t timetic_cons_t[] = {{0, "Classic"}, {1, "Centiseconds"}, {2, "Mania"}, {3, "Tics"}, {0, NULL}}; -consvar_t cv_timetic = CVAR_INIT ("timerres", "Classic", CV_SAVE, timetic_cons_t, NULL); +consvar_t cv_timetic = CVAR_INIT ("timerres", "Mania", CV_SAVE, timetic_cons_t, NULL); static CV_PossibleValue_t powerupdisplay_cons_t[] = {{0, "Never"}, {1, "First-person only"}, {2, "Always"}, {0, NULL}}; consvar_t cv_powerupdisplay = CVAR_INIT ("powerupdisplay", "First-person only", CV_SAVE, powerupdisplay_cons_t, NULL); @@ -372,10 +372,10 @@ static CV_PossibleValue_t cooplives_cons_t[] = {{0, "Infinite"}, {1, "Per-player consvar_t cv_cooplives = CVAR_INIT ("cooplives", "Avoid Game Over", CV_SAVE|CV_NETVAR|CV_CALL|CV_CHEAT|CV_ALLOWLUA, cooplives_cons_t, CoopLives_OnChange); static CV_PossibleValue_t advancemap_cons_t[] = {{0, "Off"}, {1, "Next"}, {2, "Random"}, {0, NULL}}; -consvar_t cv_advancemap = CVAR_INIT ("advancemap", "Next", CV_SAVE|CV_NETVAR|CV_ALLOWLUA, advancemap_cons_t, NULL); +consvar_t cv_advancemap = CVAR_INIT ("advancemap", "Random", CV_SAVE|CV_NETVAR|CV_ALLOWLUA, advancemap_cons_t, NULL); static CV_PossibleValue_t playersforexit_cons_t[] = {{0, "One"}, {1, "1/4"}, {2, "Half"}, {3, "3/4"}, {4, "All"}, {0, NULL}}; -consvar_t cv_playersforexit = CVAR_INIT ("playersforexit", "All", CV_SAVE|CV_NETVAR|CV_ALLOWLUA, playersforexit_cons_t, NULL); +consvar_t cv_playersforexit = CVAR_INIT ("playersforexit", "3/4", CV_SAVE|CV_NETVAR|CV_ALLOWLUA, playersforexit_cons_t, NULL); consvar_t cv_exitmove = CVAR_INIT ("exitmove", "On", CV_SAVE|CV_NETVAR|CV_CALL|CV_ALLOWLUA, CV_OnOff, ExitMove_OnChange); @@ -4253,9 +4253,9 @@ void D_GameTypeChanged(INT32 lastgametype) case GT_TEAMMATCH: if (!cv_timelimit.changed && !cv_pointlimit.changed) // user hasn't changed limits { - // default settings for match: timelimit 10 mins, no pointlimit + // default settings for match: timelimit 7 mins, no pointlimit CV_SetValue(&cv_pointlimit, 0); - CV_SetValue(&cv_timelimit, 10); + CV_SetValue(&cv_timelimit, 7); } if (!cv_itemrespawntime.changed) CV_Set(&cv_itemrespawntime, cv_itemrespawntime.defaultvalue); // respawn normally @@ -4264,9 +4264,9 @@ void D_GameTypeChanged(INT32 lastgametype) case GT_HIDEANDSEEK: if (!cv_timelimit.changed && !cv_pointlimit.changed) // user hasn't changed limits { - // default settings for tag: 5 mins, no pointlimit + // default settings for tag: 7 mins, no pointlimit // Note that tag mode also uses an alternate timing mechanism in tandem with timelimit. - CV_SetValue(&cv_timelimit, 5); + CV_SetValue(&cv_timelimit, 7); CV_SetValue(&cv_pointlimit, 0); } if (!cv_itemrespawntime.changed) @@ -4275,8 +4275,8 @@ void D_GameTypeChanged(INT32 lastgametype) case GT_CTF: if (!cv_timelimit.changed && !cv_pointlimit.changed) // user hasn't changed limits { - // default settings for CTF: no timelimit, pointlimit 5 - CV_SetValue(&cv_timelimit, 0); + // default settings for CTF: 15 mins, pointlimit 5 + CV_SetValue(&cv_timelimit, 15); CV_SetValue(&cv_pointlimit, 5); } if (!cv_itemrespawntime.changed) diff --git a/src/netcode/d_netfil.c b/src/netcode/d_netfil.c index bfb67838f..252909907 100644 --- a/src/netcode/d_netfil.c +++ b/src/netcode/d_netfil.c @@ -208,8 +208,8 @@ UINT8 *PutFileNeeded(UINT16 firstfile) filestatus += (WILLSEND_NO << 4); // Won't send else if (wadfiles[i]->filesize <= (UINT32)cv_maxsend.value * 1024) filestatus += (WILLSEND_YES << 4); // Will send if requested - // else - // filestatus += (0 << 4); -- Won't send, too big + else + filestatus += (WILLSEND_TOOLARGE << 4); // Won't send, too big } WRITEUINT8(p, filestatus); diff --git a/src/netcode/http-mserv.c b/src/netcode/http-mserv.c index 8ce20af95..0fe1e9934 100644 --- a/src/netcode/http-mserv.c +++ b/src/netcode/http-mserv.c @@ -63,7 +63,11 @@ consvar_t cv_masterserver_token = CVAR_INIT static int hms_started; +static boolean hms_args_checked; +#ifndef NO_IPV6 static boolean hms_allow_ipv6; +#endif +static boolean hms_allow_ipv4; static char *hms_api; #ifdef HAVE_THREADS @@ -134,6 +138,18 @@ HMS_on_read (char *s, size_t _1, size_t n, void *userdata) return n; } +static void HMS_check_args_once(void) +{ + if (hms_args_checked) + return; + +#ifndef NO_IPV6 + hms_allow_ipv6 = !M_CheckParm("-noipv6"); +#endif + hms_allow_ipv4 = !M_CheckParm("-noipv4"); + hms_args_checked = true; +} + FUNCDEBUG static struct HMS_buffer * HMS_connect (int proto, const char *format, ...) { @@ -152,7 +168,6 @@ HMS_connect (int proto, const char *format, ...) if (! hms_started) { - hms_allow_ipv6 = !M_CheckParm("-noipv6"); if (curl_global_init(CURL_GLOBAL_ALL) != 0) { Contact_error(); @@ -225,20 +240,27 @@ HMS_connect (int proto, const char *format, ...) curl_easy_setopt(curl, CURLOPT_STDERR, logstream); } - if (M_CheckParm("-bindaddr") && M_IsNextParm()) - { - curl_easy_setopt(curl, CURLOPT_INTERFACE, M_GetNextParm()); - } - curl_easy_setopt(curl, CURLOPT_URL, url); curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); #ifndef NO_IPV6 - if (proto == PROTO_V6) + if (proto == PROTO_V6 || (proto == PROTO_ANY && !hms_allow_ipv4)) + { curl_easy_setopt(curl, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V6); - if (proto == PROTO_V4) + if (M_CheckParm("-bindaddr6") && M_IsNextParm()) + { + curl_easy_setopt(curl, CURLOPT_INTERFACE, M_GetNextParm()); + } + } + if (proto == PROTO_V4 || (proto == PROTO_ANY && !hms_allow_ipv6)) #endif + { curl_easy_setopt(curl, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4); + if (M_CheckParm("-bindaddr") && M_IsNextParm()) + { + curl_easy_setopt(curl, CURLOPT_INTERFACE, M_GetNextParm()); + } + } curl_easy_setopt(curl, CURLOPT_TIMEOUT, cv_masterserver_timeout.value); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, HMS_on_read); @@ -326,6 +348,8 @@ HMS_fetch_rooms (int joining, int query_id) (void)query_id; + HMS_check_args_once(); + hms = HMS_connect(PROTO_ANY, "rooms"); if (! hms) @@ -420,18 +444,15 @@ int HMS_register (void) { struct HMS_buffer *hms; - int ok; + int ok = 0; char post[256]; char *title; - hms = HMS_connect(PROTO_V4, "rooms/%d/register", cv_masterserver_room_id.value); + HMS_check_args_once(); - if (! hms) - return 0; - - title = curl_easy_escape(hms->curl, cv_servername.string, 0); + title = curl_easy_escape(NULL, cv_servername.string, 0); snprintf(post, sizeof post, "port=%d&" @@ -447,16 +468,24 @@ HMS_register (void) curl_free(title); - curl_easy_setopt(hms->curl, CURLOPT_POSTFIELDS, post); - - ok = HMS_do(hms); - - if (ok) + if (hms_allow_ipv4) { - hms_server_token = strdup(strtok(hms->buffer, "\n")); - } + hms = HMS_connect(PROTO_V4, "rooms/%d/register", cv_masterserver_room_id.value); - HMS_end(hms); + if (! hms) + return 0; + + curl_easy_setopt(hms->curl, CURLOPT_POSTFIELDS, post); + + ok = HMS_do(hms); + + if (ok) + { + hms_server_token = strdup(strtok(hms->buffer, "\n")); + } + + HMS_end(hms); + } #ifndef NO_IPV6 if (!hms_allow_ipv6) @@ -488,7 +517,9 @@ HMS_unlist (void) struct HMS_buffer *hms; int ok = 0; - if (hms_server_token) + HMS_check_args_once(); + + if (hms_server_token && hms_allow_ipv4) { hms = HMS_connect(PROTO_V4, "servers/%s/unlist", hms_server_token); @@ -535,6 +566,7 @@ HMS_update (void) char *title; + HMS_check_args_once(); title = curl_easy_escape(NULL, cv_servername.string, 0); snprintf(post, sizeof post, @@ -544,7 +576,7 @@ HMS_update (void) curl_free(title); - if (hms_server_token) + if (hms_server_token && hms_allow_ipv4) { hms = HMS_connect(PROTO_V4, "servers/%s/update", hms_server_token); @@ -583,6 +615,8 @@ HMS_list_servers (void) char *list; char *p; + HMS_check_args_once(); + hms = HMS_connect(PROTO_ANY, "servers"); if (! hms) @@ -628,6 +662,8 @@ HMS_fetch_servers (msg_server_t *list, int room_number, int query_id) int i; + HMS_check_args_once(); + (void)query_id; if (room_number > 0) @@ -739,6 +775,8 @@ HMS_compare_mod_version (char *buffer, size_t buffer_size) char *version; char *version_name; + HMS_check_args_once(); + hms = HMS_connect(PROTO_ANY, "versions/%d", MODID); if (! hms) diff --git a/src/netcode/i_tcp.c b/src/netcode/i_tcp.c index 256d9992e..38d4bbbaa 100644 --- a/src/netcode/i_tcp.c +++ b/src/netcode/i_tcp.c @@ -1,7 +1,7 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2024 by Sonic Team Junior. +// Copyright (C) 1999-2025 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. @@ -386,6 +386,7 @@ static const char *SOCK_AddrToStr(mysockaddr_t *sk) int v6 = 0; #endif void *addr; + int e = 0; // save error code so it can't be modified later code and avoid calling WSAGetLastError() more then once if(sk->any.sa_family == AF_INET) addr = &sk->ip4.sin_addr; @@ -399,7 +400,10 @@ static const char *SOCK_AddrToStr(mysockaddr_t *sk) if(addr == NULL) sprintf(s, "No address"); else if(inet_ntop(sk->any.sa_family, addr, &s[v6], sizeof (s) - v6) == NULL) - sprintf(s, "Unknown family type, error #%u", errno); + { + e = errno; + sprintf(s, "Unknown family type, error #%u: %s", e, strerror(e)); + } #ifdef HAVE_IPV6 else if(sk->any.sa_family == AF_INET6) { @@ -456,6 +460,8 @@ static boolean SOCK_cmpipv6(mysockaddr_t *a, mysockaddr_t *b, UINT8 mask) { UINT8 bitmask; I_Assert(mask <= 128); + if (mask == 0) + mask = 128; if (memcmp(&a->ip6.sin6_addr.s6_addr, &b->ip6.sin6_addr.s6_addr, mask / 8) != 0) return false; if (mask % 8 == 0) @@ -650,11 +656,12 @@ static inline ssize_t SOCK_SendToAddr(SOCKET_TYPE socket, mysockaddr_t *sockaddr return sendto(socket, (char *)&doomcom->data, doomcom->datalength, 0, &sockaddr->any, d); } -#define ALLOWEDERROR(x) ((x) == ECONNREFUSED || (x) == EWOULDBLOCK || (x) == EHOSTUNREACH || (x) == ENETUNREACH) +#define ALLOWEDERROR(x) ((x) == ECONNREFUSED || (x) == EWOULDBLOCK || (x) == EHOSTUNREACH || (x) == ENETUNREACH || (x) == EADDRNOTAVAIL) static void SOCK_Send(void) { ssize_t c = ERRSOCKET; + int e = 0; // save error code so it can't be modified later code and avoid calling WSAGetLastError() more then once if (!nodeconnected[doomcom->remotenode]) return; @@ -668,8 +675,12 @@ static void SOCK_Send(void) if (myfamily[i] == broadcastaddress[j].any.sa_family) { c = SOCK_SendToAddr(mysockets[i], &broadcastaddress[j]); - if (c == ERRSOCKET && !ALLOWEDERROR(errno)) - break; + if (c == ERRSOCKET) + { + e = errno; + if (!ALLOWEDERROR(e)) + break; + } } } } @@ -681,21 +692,28 @@ static void SOCK_Send(void) if (myfamily[i] == clientaddress[doomcom->remotenode].any.sa_family) { c = SOCK_SendToAddr(mysockets[i], &clientaddress[doomcom->remotenode]); - if (c == ERRSOCKET && !ALLOWEDERROR(errno)) - break; + if (c == ERRSOCKET) + { + e = errno; + if (!ALLOWEDERROR(e)) + break; + } } } } else { c = SOCK_SendToAddr(nodesocket[doomcom->remotenode], &clientaddress[doomcom->remotenode]); + if (c == ERRSOCKET) + { + e = errno; + } } - if (c == ERRSOCKET) + if (c == ERRSOCKET && e != 0) // 0 means no socket for the address family was found { - int e = errno; // save error code so it can't be modified later if (!ALLOWEDERROR(e)) - I_Error("SOCK_Send, error sending to node %d (%s) #%u: %s", doomcom->remotenode, + I_Error("SOCK_Send, error sending to node %d (%s) #%u, %s", doomcom->remotenode, SOCK_GetNodeAddress(doomcom->remotenode), e, strerror(e)); } } @@ -726,6 +744,8 @@ static SOCKET_TYPE UDP_Bind(int family, struct sockaddr *addr, socklen_t addrlen { SOCKET_TYPE s = socket(family, SOCK_DGRAM, IPPROTO_UDP); int opt; + int rc; + int e = 0; // save error code so it can't be modified later code and avoid calling WSAGetLastError() more then once socklen_t opts; #ifdef FIONBIO unsigned long trueval = true; @@ -740,12 +760,17 @@ static SOCKET_TYPE UDP_Bind(int family, struct sockaddr *addr, socklen_t addrlen #ifdef USE_WINSOCK2 DWORD dwBytesReturned = 0; BOOL bfalse = FALSE; - WSAIoctl(s, SIO_UDP_CONNRESET, &bfalse, sizeof(bfalse), + rc = WSAIoctl(s, SIO_UDP_CONNRESET, &bfalse, sizeof(bfalse), NULL, 0, &dwBytesReturned, NULL, NULL); #else unsigned long falseval = false; - ioctl(s, SIO_UDP_CONNRESET, &falseval); + rc = ioctl(s, SIO_UDP_CONNRESET, &falseval); #endif + if (rc == -1) + { + e = errno; + I_OutputMsg("SIO_UDP_CONNRESET failed: #%u, %s\n", e, strerror(e)); + } } #endif @@ -758,14 +783,22 @@ static SOCKET_TYPE UDP_Bind(int family, struct sockaddr *addr, socklen_t addrlen { opt = true; opts = (socklen_t)sizeof(opt); - setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *)&opt, opts); + rc = setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *)&opt, opts); + if (rc <= -1) + { + e = errno; + I_OutputMsg("setting SO_REUSEADDR failed: #%u, %s\n", e, strerror(e)); + } } // make it broadcastable opt = true; opts = (socklen_t)sizeof(opt); - if (setsockopt(s, SOL_SOCKET, SO_BROADCAST, (char *)&opt, opts)) + rc = setsockopt(s, SOL_SOCKET, SO_BROADCAST, (char *)&opt, opts); + if (rc <= -1) { + e = errno; CONS_Alert(CONS_WARNING, M_GetText("Could not get broadcast rights\n")); // I do not care anymore + I_OutputMsg("setting SO_BROADCAST failed: #%u, %s\n", e, strerror(e)); } } #ifdef HAVE_IPV6 @@ -775,24 +808,34 @@ static SOCKET_TYPE UDP_Bind(int family, struct sockaddr *addr, socklen_t addrlen { opt = true; opts = (socklen_t)sizeof(opt); - setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *)&opt, opts); + rc = setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *)&opt, opts); + if (rc <= -1) + { + e = errno; + I_OutputMsg("setting SO_REUSEADDR failed: #%u, %s\n", e, strerror(e)); + } } #ifdef IPV6_V6ONLY // make it IPv6 ony opt = true; opts = (socklen_t)sizeof(opt); - if (setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, (char *)&opt, opts)) + rc = setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, (char *)&opt, opts); + if (rc <= -1) { + e = errno; CONS_Alert(CONS_WARNING, M_GetText("Could not limit IPv6 bind\n")); // I do not care anymore + I_OutputMsg("setting IPV6_V6ONLY failed: #%u, %s\n", e, strerror(e)); } #endif } #endif - if (bind(s, addr, addrlen) == ERRSOCKET) + rc = bind(s, addr, addrlen); + if (rc == ERRSOCKET) { + e = errno; close(s); - I_OutputMsg("Binding failed\n"); + I_OutputMsg("Binding failed: #%u, %s\n", e, strerror(e)); return (SOCKET_TYPE)ERRSOCKET; } @@ -806,9 +849,18 @@ static SOCKET_TYPE UDP_Bind(int family, struct sockaddr *addr, socklen_t addrlen inet_pton(AF_INET6, IPV6_MULTICAST_ADDRESS, &maddr.ipv6mr_multiaddr); maddr.ipv6mr_interface = 0; - if (setsockopt(s, IPPROTO_IPV6, IPV6_JOIN_GROUP, (const char *)&maddr, sizeof(maddr)) != 0) + rc = setsockopt(s, IPPROTO_IPV6, IPV6_JOIN_GROUP, (const char *)&maddr, sizeof(maddr)); + if (rc <= -1) { + e = errno; CONS_Alert(CONS_WARNING, M_GetText("Could not register multicast address\n")); + if (e == ENODEV) + { + close(s); + I_OutputMsg("Binding failed: no IPv6 device\n"); + return (SOCKET_TYPE)ERRSOCKET; + } + I_OutputMsg("setting IPV6_JOIN_GROUP failed: #%u, %s \n", e, strerror(e)); } } } @@ -816,33 +868,56 @@ static SOCKET_TYPE UDP_Bind(int family, struct sockaddr *addr, socklen_t addrlen #ifdef FIONBIO // make it non blocking - opt = true; - if (ioctl(s, FIONBIO, &trueval) != 0) + rc = ioctl(s, FIONBIO, &trueval); + if (rc == -1) { + e = errno; close(s); - I_OutputMsg("Seting FIOBIO on failed\n"); + I_OutputMsg("FIOBIO failed: #%u, %s\n", e, strerror(e)); return (SOCKET_TYPE)ERRSOCKET; } #endif + opt = 0; opts = (socklen_t)sizeof(opt); - getsockopt(s, SOL_SOCKET, SO_RCVBUF, (char *)&opt, &opts); + rc = getsockopt(s, SOL_SOCKET, SO_RCVBUF, (char *)&opt, &opts); + if (rc <= -1) + { + e = errno; + I_OutputMsg("getting SO_RCVBUF failed: #%u, %s\n", e, strerror(e)); + } CONS_Printf(M_GetText("Network system buffer: %dKb\n"), opt>>10); if (opt < 64<<10) // 64k { opt = 64<<10; opts = (socklen_t)sizeof(opt); - setsockopt(s, SOL_SOCKET, SO_RCVBUF, (char *)&opt, opts); - getsockopt(s, SOL_SOCKET, SO_RCVBUF, (char *)&opt, &opts); - if (opt < 64<<10) + rc = setsockopt(s, SOL_SOCKET, SO_RCVBUF, (char *)&opt, opts); + if (rc <= -1) + { + e = errno; + I_OutputMsg("setting SO_RCVBUF failed: #%u, %s\n", e, strerror(e)); + } + opt = 0; + rc = getsockopt(s, SOL_SOCKET, SO_RCVBUF, (char *)&opt, &opts); + if (rc <= -1) + { + e = errno; + I_OutputMsg("getting SO_RCVBUF failed: #%u, %s\n", e, strerror(e)); + } + if (opt <= 64<<10) CONS_Alert(CONS_WARNING, M_GetText("Can't set buffer length to 64k, file transfer will be bad\n")); else CONS_Printf(M_GetText("Network system buffer set to: %dKb\n"), opt>>10); } - if (getsockname(s, &straddr.any, &len) == -1) + rc = getsockname(s, &straddr.any, &len); + if (rc != 0) + { + e = errno; CONS_Alert(CONS_WARNING, M_GetText("Failed to get port number\n")); + I_OutputMsg("getsockname failed: #%u, %s\n", e, strerror(e)); + } else { if (family == AF_INET) @@ -864,6 +939,7 @@ static boolean UDP_Socket(void) #ifdef HAVE_IPV6 const INT32 b_ipv6 = !M_CheckParm("-noipv6"); #endif + const INT32 b_ipv4 = !M_CheckParm("-noipv4"); const char *serv; @@ -879,16 +955,45 @@ static boolean UDP_Socket(void) hints.ai_socktype = SOCK_DGRAM; hints.ai_protocol = IPPROTO_UDP; +#ifdef HAVE_IPV6 + if (!b_ipv6) + I_OutputMsg("Disabling IPv6 support at runtime\n"); +#else + I_OutputMsg("Compiled without IPv6 support\n"); +#endif + if (serverrunning) serv = serverport_name; else serv = clientport_name; - if (M_CheckParm("-bindaddr")) + if (b_ipv4) { - while (M_IsNextParm()) + if (M_CheckParm("-bindaddr")) { - gaie = I_getaddrinfo(M_GetNextParm(), serv, &hints, &ai); + while (M_IsNextParm()) + { + gaie = I_getaddrinfo(M_GetNextParm(), serv, &hints, &ai); + if (gaie == 0) + { + runp = ai; + while (runp != NULL && s < MAXNETNODES+1) + { + mysockets[s] = UDP_Bind(runp->ai_family, runp->ai_addr, (socklen_t)runp->ai_addrlen); + if (mysockets[s] != (SOCKET_TYPE)ERRSOCKET) + { + myfamily[s] = hints.ai_family; + s++; + } + runp = runp->ai_next; + } + I_freeaddrinfo(ai); + } + } + } + else + { + gaie = I_getaddrinfo("0.0.0.0", serv, &hints, &ai); if (gaie == 0) { runp = ai; @@ -899,6 +1004,13 @@ static boolean UDP_Socket(void) { myfamily[s] = hints.ai_family; s++; +#ifdef HAVE_MINIUPNPC + if (UPNP_support) + { + I_UPnP_rem(serverport_name, "UDP"); + I_UPnP_add(NULL, serverport_name, "UDP"); + } +#endif } runp = runp->ai_next; } @@ -906,32 +1018,6 @@ static boolean UDP_Socket(void) } } } - else - { - gaie = I_getaddrinfo("0.0.0.0", serv, &hints, &ai); - if (gaie == 0) - { - runp = ai; - while (runp != NULL && s < MAXNETNODES+1) - { - mysockets[s] = UDP_Bind(runp->ai_family, runp->ai_addr, (socklen_t)runp->ai_addrlen); - if (mysockets[s] != (SOCKET_TYPE)ERRSOCKET) - { - myfamily[s] = hints.ai_family; - s++; -#ifdef HAVE_MINIUPNPC - if (UPNP_support) - { - I_UPnP_rem(serverport_name, "UDP"); - I_UPnP_add(NULL, serverport_name, "UDP"); - } -#endif - } - runp = runp->ai_next; - } - I_freeaddrinfo(ai); - } - } #ifdef HAVE_IPV6 if (b_ipv6) { @@ -996,11 +1082,14 @@ static boolean UDP_Socket(void) s = 0; - // setup broadcast adress to BROADCASTADDR entry - broadcastaddress[s].any.sa_family = AF_INET; - broadcastaddress[s].ip4.sin_port = htons(atoi(DEFAULTPORT)); - broadcastaddress[s].ip4.sin_addr.s_addr = htonl(INADDR_BROADCAST); - s++; + if (b_ipv4) + { + // setup broadcast adress to BROADCASTADDR entry + broadcastaddress[s].any.sa_family = AF_INET; + broadcastaddress[s].ip4.sin_port = htons(atoi(DEFAULTPORT)); + broadcastaddress[s].ip4.sin_addr.s_addr = htonl(INADDR_BROADCAST); + s++; + } #ifdef HAVE_IPV6 if (b_ipv6) @@ -1129,7 +1218,7 @@ static SINT8 SOCK_NetMakeNodewPort(const char *address, const char *port) DEBFILE(va("Creating new node: %s@%s\n", address, port)); memset (&hints, 0x00, sizeof (hints)); - hints.ai_flags = 0; + hints.ai_flags = AI_ADDRCONFIG; hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_DGRAM; hints.ai_protocol = IPPROTO_UDP; @@ -1159,7 +1248,7 @@ static SINT8 SOCK_NetMakeNodewPort(const char *address, const char *port) } } - if (i < mysocketses) + if (i >= mysocketses) runp = runp->ai_next; else break; diff --git a/src/p_enemy.c b/src/p_enemy.c index 29fcf50c2..7091af542 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -5582,7 +5582,7 @@ void A_MinusDigging(mobj_t *actor) minus = actor; - P_DoBlockThingsIterate(xl, yl, xh, yh, PIT_MinusCarry); + P_DoBlockThingsIterate(xl, yl, xh, yh, PIT_MinusCarry, minus); } else { @@ -13726,7 +13726,7 @@ void A_DustDevilThink(mobj_t *actor) dustdevil = actor; - P_DoBlockThingsIterate(xl, yl, xh, yh, PIT_DustDevilLaunch); + P_DoBlockThingsIterate(xl, yl, xh, yh, PIT_DustDevilLaunch, dustdevil); //Whirlwind sound effect. if (leveltime % 70 == 0) @@ -13842,7 +13842,7 @@ void A_TNTExplode(mobj_t *actor) barrel = actor; - P_DoBlockThingsIterate(xl, yl, xh, yh, PIT_TNTExplode); + P_DoBlockThingsIterate(xl, yl, xh, yh, PIT_TNTExplode, barrel); // cause a quake -- P_StartQuake does not exist yet epicenter.x = actor->x; diff --git a/src/p_map.c b/src/p_map.c index fce17f8c4..337344b2f 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -2262,7 +2262,7 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y) for (bx = xl; bx <= xh; bx++) for (by = yl; by <= yh; by++) { - if (!P_BlockThingsIterator(bx, by, PIT_CheckThing)) + if (!P_BlockThingsIterator(bx, by, PIT_CheckThing, tmthing)) blockval = false; else tmhitthing = tmfloorthing; @@ -2876,7 +2876,7 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff) standx = x; standy = y; - P_DoBlockThingsIterate(xl, yl, xh, yh, PIT_PushableMoved); + P_DoBlockThingsIterate(xl, yl, xh, yh, PIT_PushableMoved, stand); } // Link the thing into its new position @@ -4223,7 +4223,7 @@ void P_RadiusAttack(mobj_t *spot, mobj_t *source, fixed_t damagedist, UINT8 dama bombdamagetype = damagetype; bombsightcheck = sightcheck; - P_DoBlockThingsIterate(xl, yl, xh, yh, PIT_RadiusAttack); + P_DoBlockThingsIterate(xl, yl, xh, yh, PIT_RadiusAttack, bombspot); } // diff --git a/src/p_maputl.c b/src/p_maputl.c index 5398fd7a4..4c7b95927 100644 --- a/src/p_maputl.c +++ b/src/p_maputl.c @@ -1050,10 +1050,14 @@ boolean P_BlockLinesIterator(INT32 x, INT32 y, boolean (*func)(line_t *)) // // P_BlockThingsIterator // -boolean P_BlockThingsIterator(INT32 x, INT32 y, boolean (*func)(mobj_t *)) +boolean P_BlockThingsIterator(INT32 x, INT32 y, boolean (*func)(mobj_t *), mobj_t *thing) { blocknode_t *block, *next = NULL; + boolean checkthing = false; + if (thing) + checkthing = true; + if (x < 0 || y < 0 || x >= bmapwidth || y >= bmapheight) return true; @@ -1065,20 +1069,20 @@ boolean P_BlockThingsIterator(INT32 x, INT32 y, boolean (*func)(mobj_t *)) if (!func(block->mobj)) return false; - if (P_MobjWasRemoved(tmthing)) // func just popped our tmthing, cannot continue. + if (checkthing && P_MobjWasRemoved(thing)) // func just popped our tmthing, cannot continue. return true; } return true; } -boolean P_DoBlockThingsIterate(int x1, int y1, int x2, int y2, boolean (*func)(mobj_t *)) +boolean P_DoBlockThingsIterate(int x1, int y1, int x2, int y2, boolean (*func)(mobj_t *), mobj_t *thing) { boolean status = true; for (INT32 bx = x1; bx <= x2; bx++) for (INT32 by = y1; by <= y2; by++) - if (!P_BlockThingsIterator(bx, by, func)) + if (!P_BlockThingsIterator(bx, by, func, thing)) status = false; return status; @@ -1451,7 +1455,7 @@ boolean P_PathTraverse(fixed_t px1, fixed_t py1, fixed_t px2, fixed_t py2, INT32 flags, traverser_t trav) { fixed_t xt1, yt1, xt2, yt2; - fixed_t xstep, ystep, partial, xintercept, yintercept; + fixed_t xstep, ystep, partialx, partialy, xintercept, yintercept; INT32 mapx, mapy, mapxstep, mapystep, count; earlyout = flags & PT_EARLYOUT; @@ -1470,56 +1474,82 @@ boolean P_PathTraverse(fixed_t px1, fixed_t py1, fixed_t px2, fixed_t py2, trace.dx = px2 - px1; trace.dy = py2 - py1; - px1 -= bmaporgx; - py1 -= bmaporgy; - xt1 = (unsigned)px1>>MAPBLOCKSHIFT; - yt1 = (unsigned)py1>>MAPBLOCKSHIFT; + xt1 = px1>>MAPBLOCKSHIFT; + yt1 = py2>>MAPBLOCKSHIFT; + px1 = (unsigned)(px1 - bmaporgx); + py1 = (unsigned)(py1 - bmaporgy); - px2 -= bmaporgx; - py2 -= bmaporgy; - xt2 = (unsigned)px2>>MAPBLOCKSHIFT; - yt2 = (unsigned)py2>>MAPBLOCKSHIFT; + xt2 = px2>>MAPBLOCKSHIFT; + yt2 = py2>>MAPBLOCKSHIFT; + px2 = (unsigned)(px2 - bmaporgx); + py2 = (unsigned)(py2 - bmaporgy); if (xt2 > xt1) { mapxstep = 1; - partial = FRACUNIT - ((px1>>MAPBTOFRAC) & FRACMASK); + partialx = FRACUNIT - (((unsigned)px1>>MAPBTOFRAC) & FRACMASK); ystep = FixedDiv(py2 - py1, abs(px2 - px1)); } else if (xt2 < xt1) { mapxstep = -1; - partial = (px1>>MAPBTOFRAC) & FRACMASK; + partialx = ((unsigned)px1>>MAPBTOFRAC) & FRACMASK; ystep = FixedDiv(py2 - py1, abs(px2 - px1)); } else { mapxstep = 0; - partial = FRACUNIT; + partialx = FRACUNIT; ystep = 256*FRACUNIT; } - yintercept = (py1>>MAPBTOFRAC) + FixedMul(partial, ystep); + yintercept = ((unsigned)py1>>MAPBTOFRAC) + FixedMul(partialx, ystep); if (yt2 > yt1) { mapystep = 1; - partial = FRACUNIT - ((py1>>MAPBTOFRAC) & FRACMASK); + partialy = FRACUNIT - (((unsigned)py1>>MAPBTOFRAC) & FRACMASK); xstep = FixedDiv(px2 - px1, abs(py2 - py1)); } else if (yt2 < yt1) { mapystep = -1; - partial = (py1>>MAPBTOFRAC) & FRACMASK; + partialy = ((unsigned)py1>>MAPBTOFRAC) & FRACMASK; xstep = FixedDiv(px2 - px1, abs(py2 - py1)); } else { mapystep = 0; - partial = FRACUNIT; + partialy = FRACUNIT; xstep = 256*FRACUNIT; } - xintercept = (px1>>MAPBTOFRAC) + FixedMul(partial, xstep); + xintercept = ((unsigned)px1>>MAPBTOFRAC) + FixedMul(partialy, xstep); + + // [RH] Fix for traces that pass only through blockmap corners. In that case, + // xintercept and yintercept can both be set ahead of mapx and mapy, so the + // for loop would never advance anywhere. + + if (abs(xstep) == 1 && abs(ystep) == 1) + { + if (ystep < 0) + { + partialx = FRACUNIT - partialx; + } + if (xstep < 0) + { + partialy = FRACUNIT - partialy; + } + if (partialx == partialy) + { + xintercept = xt1; + yintercept = yt1; + } + } + + xt1 = (unsigned)px1>>MAPBLOCKSHIFT; + yt1 = (unsigned)py1>>MAPBLOCKSHIFT; + xt2 = (unsigned)px2>>MAPBLOCKSHIFT; + yt2 = (unsigned)py2>>MAPBLOCKSHIFT; // Step through map blocks. // Count is present to prevent a round off error @@ -1534,21 +1564,64 @@ boolean P_PathTraverse(fixed_t px1, fixed_t py1, fixed_t px2, fixed_t py2, return false; // early out if (flags & PT_ADDTHINGS) - if (!P_BlockThingsIterator(mapx, mapy, PIT_AddThingIntercepts)) + if (!P_BlockThingsIterator(mapx, mapy, PIT_AddThingIntercepts, NULL)) return false; // early out - if (mapx == xt2 && mapy == yt2) + // both coordinates reached the end, so end the traversing. + if ((mapxstep | mapystep) == 0) break; - if ((yintercept >> FRACBITS) == mapy) + // [RH] Handle corner cases properly instead of pretending they don't exist. + switch ((((yintercept >> FRACBITS) == mapy) << 1) | ((xintercept >> FRACBITS) == mapx)) { - yintercept += ystep; - mapx += mapxstep; - } - else if ((xintercept >> FRACBITS) == mapx) - { - xintercept += xstep; - mapy += mapystep; + case 0: // neither xintercept nor yintercept match! + count = 64; // Stop traversing, because somebody screwed up. + break; + + case 1: // xintercept matches + xintercept += xstep; + mapy += mapystep; + if (mapy == yt2) + mapystep = 0; + break; + + case 2: // yintercept matches + yintercept += ystep; + mapx += mapxstep; + if (mapx == xt2) + mapxstep = 0; + break; + + case 3: // xintercept and yintercept both match + // The trace is exiting a block through its corner. Not only does the block + // being entered need to be checked (which will happen when this loop + // continues), but the other two blocks adjacent to the corner also need to + // be checked. + if (flags & PT_ADDLINES) + { + if (!P_BlockLinesIterator(mapx + mapxstep, mapy, PIT_AddLineIntercepts)) + return false; // early out + if (!P_BlockLinesIterator(mapx, mapy + mapystep, PIT_AddLineIntercepts)) + return false; // early out + } + + if (flags & PT_ADDTHINGS) + { + if (!P_BlockThingsIterator(mapx + mapxstep, mapy, PIT_AddThingIntercepts, NULL)) + return false; // early out + if (!P_BlockThingsIterator(mapx, mapy + mapystep, PIT_AddThingIntercepts, NULL)) + return false; // early out + } + + xintercept += xstep; + yintercept += ystep; + mapx += mapxstep; + mapy += mapystep; + if (mapx == xt2) + mapxstep = 0; + if (mapy == yt2) + mapystep = 0; + break; } } // Go through the sorted list diff --git a/src/p_maputl.h b/src/p_maputl.h index 67f7fd086..11cc90c59 100644 --- a/src/p_maputl.h +++ b/src/p_maputl.h @@ -61,7 +61,7 @@ extern ffloor_t *openfloorrover, *openceilingrover; void P_LineOpening(line_t *plinedef, mobj_t *mobj); boolean P_BlockLinesIterator(INT32 x, INT32 y, boolean(*func)(line_t *)); -boolean P_BlockThingsIterator(INT32 x, INT32 y, boolean(*func)(mobj_t *)); +boolean P_BlockThingsIterator(INT32 x, INT32 y, boolean(*func)(mobj_t *), mobj_t *thing); void P_ClearBlockNodes(void); @@ -94,7 +94,7 @@ typedef struct bthingit_s bthingit_t *P_NewBlockThingsIterator(int x1, int y1, int x2, int y2); mobj_t *P_BlockThingsIteratorNext(bthingit_t *it, boolean centeronly); void P_FreeBlockThingsIterator(bthingit_t *it); -boolean P_DoBlockThingsIterate(int x1, int y1, int x2, int y2, boolean (*func)(mobj_t *)); +boolean P_DoBlockThingsIterate(int x1, int y1, int x2, int y2, boolean (*func)(mobj_t *), mobj_t *thing); #define PT_ADDLINES 1 #define PT_ADDTHINGS 2 diff --git a/src/p_mobj.c b/src/p_mobj.c index ec107ff71..259bf19d4 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -39,7 +39,7 @@ #include "netcode/net_command.h" static CV_PossibleValue_t CV_BobSpeed[] = {{0, "MIN"}, {4*FRACUNIT, "MAX"}, {0, NULL}}; -consvar_t cv_movebob = CVAR_INIT ("movebob", "1.0", CV_FLOAT|CV_SAVE, CV_BobSpeed, NULL); +consvar_t cv_movebob = CVAR_INIT ("movebob", "0.25", CV_FLOAT|CV_SAVE, CV_BobSpeed, NULL); actioncache_t actioncachehead; @@ -324,7 +324,7 @@ static boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state) mobj->tics = st->tics; // Adjust the player's animation speed - if (mobj->state-states == S_PLAY_WAIT && (player->charflags & SF_FASTWAIT)) + if (state == S_PLAY_WAIT && (player->charflags & SF_FASTWAIT)) mobj->tics = 5; else if (player->panim == PA_EDGE && (player->charflags & SF_FASTEDGE)) mobj->tics = 2; @@ -9334,7 +9334,7 @@ static void P_PointPushThink(mobj_t *mobj) yl = (unsigned)(mobj->y - radius - bmaporgy)>>MAPBLOCKSHIFT; yh = (unsigned)(mobj->y + radius - bmaporgy)>>MAPBLOCKSHIFT; - P_DoBlockThingsIterate(xl, yl, xh, yh, PIT_PushThing); + P_DoBlockThingsIterate(xl, yl, xh, yh, PIT_PushThing, pushmobj); } static boolean P_MobjRegularThink(mobj_t *mobj) diff --git a/src/p_setup.c b/src/p_setup.c index c2b8f2db2..247587e11 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -609,15 +609,15 @@ Ploadflat (levelflat_t *levelflat, const char *flatname, boolean resize) levelflat->type = LEVELFLAT_TEXTURE; // Look for a flat - int texturenum = R_CheckFlatNumForName(levelflat->name); + int texturenum = R_CheckTextureNumForName(levelflat->name, TEXTURETYPE_FLAT); if (texturenum < 0) { // If we can't find a flat, try looking for a texture! - texturenum = R_CheckTextureNumForName(levelflat->name); + texturenum = R_CheckTextureNumForName(levelflat->name, TEXTURETYPE_TEXTURE); if (texturenum < 0) { // Use "not found" texture - texturenum = R_CheckTextureNumForName("REDWALL"); + texturenum = R_CheckTextureNumForName("REDWALL", TEXTURETYPE_TEXTURE); // Give up? if (texturenum < 0) diff --git a/src/p_slopes.c b/src/p_slopes.c index 739032936..12d5afd02 100644 --- a/src/p_slopes.c +++ b/src/p_slopes.c @@ -1046,15 +1046,37 @@ fixed_t P_GetWallTransferMomZ(mobj_t *mo, pslope_t *slope) { vector3_t slopemom, axis; angle_t ang; + angle_t advanceAng = ANG15; + const boolean upwards = (slope->zangle < ANGLE_180); if (slope->flags & SL_NOPHYSICS) return 0; // If there's physics, time for launching. // Doesn't kill the vertical momentum as much as P_SlopeLaunch does. - ang = slope->zangle + ANG15*((slope->zangle > 0) ? 1 : -1); - if (ang > ANGLE_90 && ang < ANGLE_180) - ang = ((slope->zangle > 0) ? ANGLE_90 : InvAngle(ANGLE_90)); // hard cap of directly upwards + ang = slope->zangle; + + // for the time being, let's pretend the slope inclines upwards only + if (!upwards) + { + ang += ANGLE_180; + } + + // angles past 90 degrees need to shrink to get closer to 90 degrees + if (ang > ANGLE_90) + { + advanceAng = InvAngle(advanceAng); + } + + // now we set the actual final angle + if ((ang > ANGLE_90) != (ang + advanceAng > ANGLE_90)) // does advancing the angle push it past directly upwards? + { + ang = (upwards ? ANGLE_90 : InvAngle(ANGLE_90)); // hard cap of directly upwards + } + else + { + ang = slope->zangle + advanceAng; + } slopemom.x = mo->momx; slopemom.y = mo->momy; diff --git a/src/p_spec.c b/src/p_spec.c index 93809cbb4..649f63518 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -135,22 +135,24 @@ void P_ParseAnimationDefintion(SINT8 istexture); static boolean P_FindTextureForAnimation(anim_t *anim, animdef_t *animdef) { - if (R_CheckTextureNumForName(animdef->startname) == -1) + INT32 start = R_CheckTextureNumForName(animdef->startname, TEXTURETYPE_TEXTURE); + if (start == -1) return false; - anim->picnum = R_TextureNumForName(animdef->endname); - anim->basepic = R_TextureNumForName(animdef->startname); + anim->basepic = start; + anim->picnum = R_CheckTextureNumForName(animdef->endname, TEXTURETYPE_TEXTURE); return true; } static boolean P_FindFlatForAnimation(anim_t *anim, animdef_t *animdef) { - if (R_CheckFlatNumForName(animdef->startname) == -1) + INT32 start = R_CheckTextureNumForName(animdef->startname, TEXTURETYPE_FLAT); + if (start == -1) return false; - anim->picnum = R_CheckFlatNumForName(animdef->endname); - anim->basepic = R_CheckFlatNumForName(animdef->startname); + anim->basepic = start; + anim->picnum = R_CheckTextureNumForName(animdef->endname, TEXTURETYPE_FLAT); return true; } diff --git a/src/p_user.c b/src/p_user.c index 7cc9c02ae..ba22808ea 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -2,7 +2,7 @@ //----------------------------------------------------------------------------- // Copyright (C) 1993-1996 by id Software, Inc. // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2024 by Sonic Team Junior. +// Copyright (C) 1999-2025 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. @@ -3310,6 +3310,7 @@ static void P_DoPlayerHeadSigns(player_t *player) sign->frame = 2|FF_FULLBRIGHT; } } + } if (!P_MobjWasRemoved(sign) && splitscreen) // Hide the sign from yourself in splitscreen - In single-screen, it wouldn't get spawned if it shouldn't be visible { @@ -3347,7 +3348,6 @@ static void P_DoPlayerHeadSigns(player_t *player) } #endif } - } } // @@ -4125,7 +4125,7 @@ static void P_DoTeeter(player_t *player) teeteryl = teeteryh = player->mo->y; couldteeter = false; solidteeter = teeter; - if (!P_DoBlockThingsIterate(xl, yl, xh, yh, PIT_CheckSolidsTeeter)) + if (!P_DoBlockThingsIterate(xl, yl, xh, yh, PIT_CheckSolidsTeeter, tmthing)) goto teeterdone; // we've found something that stops us teetering at all teeterdone: teeter = solidteeter; @@ -9833,7 +9833,7 @@ static CV_PossibleValue_t campos_cons_t[] = { {INT32_MIN, "MIN"}, {INT32_MAX, "M consvar_t cv_cam_dist = CVAR_INIT ("cam_curdist", "160", CV_FLOAT|CV_ALLOWLUA, campos_cons_t, NULL); consvar_t cv_cam_height = CVAR_INIT ("cam_curheight", "25", CV_FLOAT|CV_ALLOWLUA, campos_cons_t, NULL); consvar_t cv_cam_still = CVAR_INIT ("cam_still", "Off", CV_ALLOWLUA, CV_OnOff, NULL); -consvar_t cv_cam_speed = CVAR_INIT ("cam_speed", "0.3", CV_FLOAT|CV_SAVE|CV_ALLOWLUA, CV_CamSpeed, NULL); +consvar_t cv_cam_speed = CVAR_INIT ("cam_speed", "0.4", CV_FLOAT|CV_SAVE|CV_ALLOWLUA, CV_CamSpeed, NULL); consvar_t cv_cam_rotate = CVAR_INIT ("cam_rotate", "0", CV_CALL|CV_NOINIT|CV_ALLOWLUA, CV_CamRotate, CV_CamRotate_OnChange); consvar_t cv_cam_rotspeed = CVAR_INIT ("cam_rotspeed", "10", CV_SAVE|CV_ALLOWLUA, rotation_cons_t, NULL); consvar_t cv_cam_turnmultiplier = CVAR_INIT ("cam_turnmultiplier", "0.75", CV_FLOAT|CV_SAVE|CV_ALLOWLUA, multiplier_cons_t, NULL); @@ -9842,7 +9842,7 @@ consvar_t cv_cam_adjust = CVAR_INIT ("cam_adjust", "On", CV_SAVE|CV_ALLOWLUA, CV consvar_t cv_cam2_dist = CVAR_INIT ("cam2_curdist", "160", CV_FLOAT|CV_ALLOWLUA, campos_cons_t, NULL); consvar_t cv_cam2_height = CVAR_INIT ("cam2_curheight", "25", CV_FLOAT|CV_ALLOWLUA, campos_cons_t, NULL); consvar_t cv_cam2_still = CVAR_INIT ("cam2_still", "Off", CV_ALLOWLUA, CV_OnOff, NULL); -consvar_t cv_cam2_speed = CVAR_INIT ("cam2_speed", "0.3", CV_FLOAT|CV_SAVE|CV_ALLOWLUA, CV_CamSpeed, NULL); +consvar_t cv_cam2_speed = CVAR_INIT ("cam2_speed", "0.4", CV_FLOAT|CV_SAVE|CV_ALLOWLUA, CV_CamSpeed, NULL); consvar_t cv_cam2_rotate = CVAR_INIT ("cam2_rotate", "0", CV_CALL|CV_NOINIT|CV_ALLOWLUA, CV_CamRotate, CV_CamRotate2_OnChange); consvar_t cv_cam2_rotspeed = CVAR_INIT ("cam2_rotspeed", "10", CV_SAVE|CV_ALLOWLUA, rotation_cons_t, NULL); consvar_t cv_cam2_turnmultiplier = CVAR_INIT ("cam2_turnmultiplier", "0.75", CV_FLOAT|CV_SAVE|CV_ALLOWLUA, multiplier_cons_t, NULL); @@ -11515,6 +11515,18 @@ void P_DoTailsOverlay(player_t *player, mobj_t *tails) } // Metal Sonic's jet fume +// +// The follow object's state is set to its spawn state when deactivated. +// When the player is on a moving animation, the follow object goes to its see state. +// When dash mode is entered, the follow object switches to its melee state. +// +// If MF2_FRET is set, the jet fume will flash during dash mode. +// MF2_AMBUSH can be used to enable Metal Sonic's skidding animation. +// MF2_JUSTATTACKED will enable the color cycling. +// If the follow item is MT_METALJETFUME, the above two effects are automatically applied. +// +// MF2_STRONGBOX is internally used to track if the jet fume is in its deactivated state or not. +// MF2_BOSSNOTRAP is internally used to instantly reset the jet fume's scale to its intended scale. void P_DoMetalJetFume(player_t *player, mobj_t *fume) { static const UINT8 FUME_SKINCOLORS[] = @@ -11541,19 +11553,29 @@ void P_DoMetalJetFume(player_t *player, mobj_t *fume) fixed_t heightoffset = ((mo->eflags & MFE_VERTICALFLIP) ? mo->height - (P_GetPlayerHeight(player) >> 1) : (P_GetPlayerHeight(player) >> 1)); panim_t panim = player->panim; tic_t dashmode = min(player->dashmode, DASHMODE_MAX); + boolean ismetaljetfume = fume->type == MT_METALJETFUME; + boolean notmoving = panim != PA_WALK && panim != PA_RUN && panim != PA_DASH; boolean underwater = mo->eflags & MFE_UNDERWATER; statenum_t stat = fume->state-states; boolean resetinterp = false; - if (panim != PA_WALK && panim != PA_RUN && panim != PA_DASH) // turn invisible when not in a coherent movement state + if (notmoving) // deactivate when not in a coherent movement state { - if (stat != fume->info->spawnstate) + if ((fume->flags2 & MF2_STRONGBOX) == 0) + { P_SetMobjState(fume, fume->info->spawnstate); - return; + fume->flags2 |= MF2_STRONGBOX; + } + if (P_MobjWasRemoved(fume) || ismetaljetfume) + return; } - if (player->skidtime) // Rotate during metal sonic's new skid animation - angle += ANGLE_90; + // Rotate on skid animation if follow item is MT_METALJETFUME, or if MF2_AMBUSH is set + if (player->mo->sprite2 == SPR2_SKID) + { + if ((ismetaljetfume && (player->charflags & SF_JETFUME)) || (fume->flags2 & MF2_AMBUSH)) + angle += ANGLE_90; + } if (underwater) // No fume underwater; spawn bubbles instead! { @@ -11590,54 +11612,82 @@ void P_DoMetalJetFume(player_t *player, mobj_t *fume) if (panim == PA_WALK) { - if (stat != fume->info->spawnstate) + if ((fume->flags2 & MF2_STRONGBOX) == 0) { - fume->threshold = 0; P_SetMobjState(fume, fume->info->spawnstate); + fume->threshold = 0; + fume->flags2 &= ~MF2_STRONGBOX; } - return; + if (P_MobjWasRemoved(fume) || ismetaljetfume) + return; } } - if (stat == fume->info->spawnstate) // If currently inivisble, activate! + // If currently deactivated, activate! + if (!notmoving && !underwater && (fume->flags2 & MF2_STRONGBOX)) { P_SetMobjState(fume, (stat = fume->info->seestate)); + if (P_MobjWasRemoved(fume)) + return; P_SetScale(fume, mo->scale, false); + fume->flags2 &= ~MF2_STRONGBOX; resetinterp = true; } - if (dashmode > DASHMODE_THRESHOLD && stat != fume->info->seestate) // If in dashmode, grow really big and flash + // If in dash mode, grow really big + if (dashmode > DASHMODE_THRESHOLD && stat != fume->info->meleestate) { fume->destscale = mo->scale; - fume->flags2 ^= MF2_DONTDRAW; fume->flags2 |= mo->flags2 & MF2_DONTDRAW; + + // Flash if follow item is MT_METALJETFUME, or if MF2_FRET is set + if (ismetaljetfume || (fume->flags2 & MF2_FRET)) + fume->flags2 ^= MF2_DONTDRAW; } else // Otherwise, pick a size and color depending on speed and proximity to dashmode { - if (dashmode == DASHMODE_THRESHOLD && dashmode > (tic_t)fume->movecount) // If just about to enter dashmode, play the startup animation again + // If just about to enter dash mode, play the startup animation again + if (dashmode == DASHMODE_THRESHOLD && dashmode > (tic_t)fume->movecount) { - P_SetMobjState(fume, (stat = fume->info->seestate)); + P_SetMobjState(fume, fume->info->meleestate); + if (P_MobjWasRemoved(fume)) + return; P_SetScale(fume, 2*mo->scale, true); } + fume->flags2 = (fume->flags2 & ~MF2_DONTDRAW) | (mo->flags2 & MF2_DONTDRAW); fume->destscale = (mo->scale + FixedDiv(player->speed, player->normalspeed)) / (underwater ? 6 : 3); - fume->color = FUME_SKINCOLORS[(dashmode * sizeof(FUME_SKINCOLORS)) / (DASHMODE_MAX + 1)]; + + // Do color cycling if follow item is MT_METALJETFUME, or if MF2_JUSTATTACKED is set + if (ismetaljetfume || (fume->flags2 & MF2_JUSTATTACKED)) + fume->color = FUME_SKINCOLORS[(dashmode * sizeof(FUME_SKINCOLORS)) / (DASHMODE_MAX + 1)]; if (underwater) { - fume->frame = (fume->frame & FF_FRAMEMASK) | FF_ANIMATE | (P_RandomRange(0, 9) * FF_TRANS10); + fume->frame = (fume->frame & ~FF_TRANSMASK) | (P_RandomRange(0, 9) << FF_TRANSSHIFT); fume->threshold = 1; } else if (fume->threshold) { - fume->frame = (fume->frame & FF_FRAMEMASK) | fume->state->frame; + fume->frame = (fume->frame & FF_FRAMEMASK) | (fume->state->frame & ~FF_FRAMEMASK); fume->threshold = 0; } } - fume->movecount = dashmode; // keeps track of previous dashmode value so we know whether Metal is entering or leaving it - fume->flags2 = (fume->flags2 & ~MF2_OBJECTFLIP) | (mo->flags2 & MF2_OBJECTFLIP); // Make sure to flip in reverse gravity! - fume->eflags = (fume->eflags & ~MFE_VERTICALFLIP) | (mo->eflags & MFE_VERTICALFLIP); // Make sure to flip in reverse gravity! + // keeps track of previous dash mode value so we know whether Metal is entering or leaving it + fume->movecount = dashmode; + + // Make sure to flip in reverse gravity! + fume->flags2 = (fume->flags2 & ~MF2_OBJECTFLIP) | (mo->flags2 & MF2_OBJECTFLIP); + fume->eflags = (fume->eflags & ~MFE_VERTICALFLIP) | (mo->eflags & MFE_VERTICALFLIP); + + // Set the appropriate scale at spawn + // This is... strange, but I had to choose a flag that a follow object would not ordinarily use. + if ((fume->flags2 & MF2_BOSSNOTRAP) == 0) + { + P_SetScale(fume, fume->destscale, true); + fume->flags2 |= MF2_BOSSNOTRAP; + } // Finally, set its position dist = -mo->radius - FixedMul(fume->info->radius, fume->destscale - mo->scale/3); @@ -11647,9 +11697,10 @@ void P_DoMetalJetFume(player_t *player, mobj_t *fume) fume->y = mo->y + P_ReturnThrustY(fume, angle, dist); fume->z = mo->z + heightoffset - (fume->height >> 1); P_SetThingPosition(fume); - if (resetinterp) R_ResetMobjInterpolationState(fume); + if (resetinterp) + R_ResetMobjInterpolationState(fume); - // If dashmode is high enough, spawn a trail + // If dash mode is high enough, spawn a trail if (player->normalspeed >= skins[player->skin]->normalspeed*2) { mobj_t *ghost = P_SpawnGhostMobj(fume); @@ -11663,6 +11714,8 @@ void P_DoFollowMobj(player_t *player, mobj_t *followmobj) { if (LUA_HookFollowMobj(player, followmobj) || P_MobjWasRemoved(followmobj)) {;} + else if (player->charflags & SF_JETFUME) + P_DoMetalJetFume(player, followmobj); else { switch (followmobj->type) @@ -13164,7 +13217,8 @@ void P_PlayerAfterThink(player_t *player) player->followmobj->colorized = true; break; default: - player->followmobj->flags2 |= MF2_LINKDRAW; + if ((player->charflags & SF_JETFUME) == 0) + player->followmobj->flags2 |= MF2_LINKDRAW; break; } } diff --git a/src/r_main.c b/src/r_main.c index 46bac9dc7..3de5cb151 100644 --- a/src/r_main.c +++ b/src/r_main.c @@ -161,7 +161,7 @@ consvar_t cv_translucency = CVAR_INIT ("translucency", "On", CV_SAVE, CV_OnOff, consvar_t cv_drawdist = CVAR_INIT ("drawdist", "Infinite", CV_SAVE, drawdist_cons_t, NULL); consvar_t cv_drawdist_nights = CVAR_INIT ("drawdist_nights", "2048", CV_SAVE, drawdist_cons_t, NULL); consvar_t cv_drawdist_precip = CVAR_INIT ("drawdist_precip", "1024", CV_SAVE, drawdist_precip_cons_t, NULL); -consvar_t cv_fov = CVAR_INIT ("fov", "90", CV_SAVE|CV_FLOAT|CV_CALL, fov_cons_t, Fov_OnChange); +consvar_t cv_fov = CVAR_INIT ("fov", "100", CV_SAVE|CV_FLOAT|CV_CALL, fov_cons_t, Fov_OnChange); consvar_t cv_fovchange = CVAR_INIT ("fovchange", "Off", CV_SAVE, CV_OnOff, NULL); consvar_t cv_maxportals = CVAR_INIT ("maxportals", "2", CV_SAVE, maxportals_cons_t, NULL); diff --git a/src/r_plane.c b/src/r_plane.c index a0de048ea..053cfe921 100644 --- a/src/r_plane.c +++ b/src/r_plane.c @@ -2,7 +2,7 @@ //----------------------------------------------------------------------------- // Copyright (C) 1993-1996 by id Software, Inc. // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2024 by Sonic Team Junior. +// Copyright (C) 1999-2025 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. @@ -182,8 +182,8 @@ static void R_MapPlane(INT32 y, INT32 x1, INT32 x2) R_CalculatePlaneRipple(currentplane->viewangle + currentplane->plangle); - ds_xfrac += planeripple.xfrac; - ds_yfrac += planeripple.yfrac; + ds_xfrac += FixedMul(planeripple.xfrac, currentplane->xscale); + ds_yfrac += FixedMul(planeripple.yfrac, currentplane->yscale); ds_bgofs >>= FRACBITS; if ((y + ds_bgofs) >= viewheight) diff --git a/src/r_skins.c b/src/r_skins.c index f364273e8..7b5e54714 100644 --- a/src/r_skins.c +++ b/src/r_skins.c @@ -2,7 +2,7 @@ //----------------------------------------------------------------------------- // Copyright (C) 1993-1996 by id Software, Inc. // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2024 by Sonic Team Junior. +// Copyright (C) 1999-2025 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. @@ -80,10 +80,19 @@ UINT16 P_ApplySuperFlagToSprite2(UINT16 spr2, mobj_t *mobj) { if (mobj->player) { - if (mobj->player->charflags & SF_NOSUPERSPRITES || (mobj->player->powers[pw_carry] == CR_NIGHTSMODE && (mobj->player->charflags & SF_NONIGHTSSUPER))) + boolean is_nights = mobj->player->powers[pw_carry] == CR_NIGHTSMODE; + + if (mobj->player->charflags & SF_NOSUPERSPRITES || (is_nights && (mobj->player->charflags & SF_NONIGHTSSUPER))) spr2 &= ~SPR2F_SUPER; - else if (mobj->player->powers[pw_super] || (mobj->player->powers[pw_carry] == CR_NIGHTSMODE && (mobj->player->charflags & SF_SUPER))) + else if (mobj->player->powers[pw_super] || (is_nights && (mobj->player->charflags & SF_SUPER))) spr2 |= SPR2F_SUPER; + + // Special case for transforming when you are NiGHTS. + // Do NOT apply the super sprites in this situation, even if they exist. + if (is_nights && mobj->state >= &states[S_PLAY_NIGHTS_TRANS1] && mobj->state <= &states[S_PLAY_NIGHTS_TRANS6]) + { + spr2 &= ~SPR2F_SUPER; + } } if (spr2 & SPR2F_SUPER) @@ -730,6 +739,8 @@ static boolean R_ProcessPatchableFields(skin_t *skin, char *stoken, char *value) GETFLAG(MACHINE) GETFLAG(DASHMODE) GETFLAG(FASTEDGE) + GETFLAG(FASTWAIT) + GETFLAG(JETFUME) GETFLAG(MULTIABILITY) GETFLAG(NONIGHTSROTATION) GETFLAG(NONIGHTSSUPER) diff --git a/src/r_splats.c b/src/r_splats.c index ce35a35b4..4b4de8275 100644 --- a/src/r_splats.c +++ b/src/r_splats.c @@ -53,7 +53,7 @@ static void rasterize_segment_tex(INT32 x1, INT32 y1, INT32 x2, INT32 y2, INT32 if (dir == 0) { - for (;;) + for (; count > 0; count--) { rastertab[y1].maxx = xs; rastertab[y1].tx2 = xe; @@ -62,13 +62,11 @@ static void rasterize_segment_tex(INT32 x1, INT32 y1, INT32 x2, INT32 y2, INT32 xs += dx0; xe += dx1; y1++; - - if (count-- < 1) break; } } else { - for (;;) + for (; count > 0; count--) { rastertab[y1].maxx = xs; rastertab[y1].tx2 = tc; @@ -77,8 +75,6 @@ static void rasterize_segment_tex(INT32 x1, INT32 y1, INT32 x2, INT32 y2, INT32 xs += dx0; xe += dx1; y1++; - - if (count-- < 1) break; } } } @@ -95,7 +91,7 @@ static void rasterize_segment_tex(INT32 x1, INT32 y1, INT32 x2, INT32 y2, INT32 if (dir == 0) { - for (;;) + for (; count > 0; count--) { rastertab[y2].minx = xs; rastertab[y2].tx1 = xe; @@ -104,13 +100,11 @@ static void rasterize_segment_tex(INT32 x1, INT32 y1, INT32 x2, INT32 y2, INT32 xs += dx0; xe += dx1; y2++; - - if (count-- < 1) break; } } else { - for (;;) + for (; count > 0; count--) { rastertab[y2].minx = xs; rastertab[y2].tx1 = tc; @@ -119,8 +113,6 @@ static void rasterize_segment_tex(INT32 x1, INT32 y1, INT32 x2, INT32 y2, INT32 xs += dx0; xe += dx1; y2++; - - if (count-- < 1) break; } } } diff --git a/src/r_textures.c b/src/r_textures.c index 4c52f75eb..4dc6bbae4 100644 --- a/src/r_textures.c +++ b/src/r_textures.c @@ -925,7 +925,7 @@ Rloadtextures (INT32 i, INT32 w) // printf("\"%s\" (wad: %u, lump: %u) is a single patch, dimensions %d x %d\n",W_CheckNameForNumPwad(wadnum,lumpnum),wadnum,lumpnum,width,height); - R_AddSinglePatchTexture(i, wadnum, lumpnum, width, height, TEXTURETYPE_SINGLEPATCH); + R_AddSinglePatchTexture(i, wadnum, lumpnum, width, height, TEXTURETYPE_TEXTURE); i++; } @@ -1494,7 +1494,7 @@ static texture_t *R_ParseTexture(boolean actuallyLoadTexture) resultTexture->hash = quickncasehash(newTextureName, 8); resultTexture->width = newTextureWidth; resultTexture->height = newTextureHeight; - resultTexture->type = TEXTURETYPE_COMPOSITE; + resultTexture->type = TEXTURETYPE_TEXTURE; } Z_Free(texturesToken); texturesToken = M_GetToken(NULL); @@ -1680,7 +1680,7 @@ static void AddTextureToCache(const char *name, UINT32 hash, INT32 id, UINT8 typ // // Check whether texture is available. Filter out NoTexture indicator. // -INT32 R_CheckTextureNumForName(const char *name) +INT32 R_CheckTextureNumForName(const char *name, UINT8 type) { INT32 i; UINT32 hash; @@ -1692,14 +1692,14 @@ INT32 R_CheckTextureNumForName(const char *name) hash = quickncasehash(name, 8); for (i = 0; i < tidcachelen; i++) - if (tidcache[i].hash == hash && !strncasecmp(tidcache[i].name, name, 8)) + if (tidcache[i].type == type && tidcache[i].hash == hash && !strncasecmp(tidcache[i].name, name, 8)) return tidcache[i].id; // Need to parse the list backwards, so textures loaded more recently are used in lieu of ones loaded earlier for (i = numtextures - 1; i >= 0; i--) - if (textures[i]->hash == hash && !strncasecmp(textures[i]->name, name, 8)) + if (textures[i]->type == type && textures[i]->hash == hash && !strncasecmp(textures[i]->name, name, 8)) { - AddTextureToCache(name, hash, i, textures[i]->type); + AddTextureToCache(name, hash, i, type); return i; } @@ -1738,47 +1738,29 @@ const char *R_TextureNameForNum(INT32 num) // // R_TextureNumForName // -// Calls R_CheckTextureNumForName, aborts with error message. +// Calls R_CheckTextureNumForName. Returns REDWALL if not found. // INT32 R_TextureNumForName(const char *name) { - const INT32 i = R_CheckTextureNumForName(name); + INT32 i = R_CheckTextureNumForName(name, TEXTURETYPE_TEXTURE); + // Didn't find it, so look for a flat + if (i == -1) + { + i = R_CheckTextureNumForName(name, TEXTURETYPE_FLAT); + } + + // Still didn't find it, so return REDWALL if (i == -1) { static INT32 redwall = -2; CONS_Debug(DBG_SETUP, "WARNING: R_TextureNumForName: %.8s not found\n", name); if (redwall == -2) - redwall = R_CheckTextureNumForName("REDWALL"); + redwall = R_CheckTextureNumForName("REDWALL", TEXTURETYPE_TEXTURE); if (redwall != -1) return redwall; return 1; } + return i; } - -// Like R_CheckTextureNumForName, but only looks in the flat namespace specifically. -INT32 R_CheckFlatNumForName(const char *name) -{ - INT32 i; - UINT32 hash; - - // "NoTexture" marker. - if (name[0] == '-') - return 0; - - hash = quickncasehash(name, 8); - - for (i = 0; i < tidcachelen; i++) - if (tidcache[i].type == TEXTURETYPE_FLAT && tidcache[i].hash == hash && !strncasecmp(tidcache[i].name, name, 8)) - return tidcache[i].id; - - for (i = numtextures - 1; i >= 0; i--) - if (textures[i]->hash == hash && !strncasecmp(textures[i]->name, name, 8) && textures[i]->type == TEXTURETYPE_FLAT) - { - AddTextureToCache(name, hash, i, TEXTURETYPE_FLAT); - return i; - } - - return -1; -} diff --git a/src/r_textures.h b/src/r_textures.h index 35db40d42..e6985556b 100644 --- a/src/r_textures.h +++ b/src/r_textures.h @@ -40,8 +40,7 @@ typedef struct enum { TEXTURETYPE_UNKNOWN, - TEXTURETYPE_SINGLEPATCH, - TEXTURETYPE_COMPOSITE, + TEXTURETYPE_TEXTURE, TEXTURETYPE_FLAT }; @@ -100,8 +99,7 @@ void R_SetFlatVars(size_t length); // Returns the texture number for the texture name. INT32 R_TextureNumForName(const char *name); -INT32 R_CheckTextureNumForName(const char *name); -INT32 R_CheckFlatNumForName(const char *name); +INT32 R_CheckTextureNumForName(const char *name, UINT8 type); // Returns the texture name for the texture number (in case you ever needed it) const char *R_CheckTextureNameForNum(INT32 num); diff --git a/src/sdl/Srb2SDL-vc10.vcxproj b/src/sdl/Srb2SDL-vc10.vcxproj index 86ffa7082..8026cd3ac 100644 --- a/src/sdl/Srb2SDL-vc10.vcxproj +++ b/src/sdl/Srb2SDL-vc10.vcxproj @@ -447,6 +447,7 @@ + @@ -641,4 +642,4 @@ - \ No newline at end of file + diff --git a/src/sdl/Srb2SDL-vc10.vcxproj.filters b/src/sdl/Srb2SDL-vc10.vcxproj.filters index d2f9d018f..bbfca04d4 100644 --- a/src/sdl/Srb2SDL-vc10.vcxproj.filters +++ b/src/sdl/Srb2SDL-vc10.vcxproj.filters @@ -604,6 +604,9 @@ BLUA + + BLUA + BLUA @@ -1125,4 +1128,4 @@ SDLApp - \ No newline at end of file + diff --git a/src/sdl/mixer_sound.c b/src/sdl/mixer_sound.c index 8f2ca3408..0f9983ee1 100644 --- a/src/sdl/mixer_sound.c +++ b/src/sdl/mixer_sound.c @@ -135,7 +135,7 @@ static void Midiplayer_Onchange(void) if (Mix_GetMidiPlayer() != cv_midiplayer.value) { if (Mix_SetMidiPlayer(cv_midiplayer.value)) // <> 0 means error - CONS_Alert(CONS_ERROR, "Midi player error: %s", Mix_GetError()); + CONS_Alert(CONS_ERROR, "Midi player error: %s\n", Mix_GetError()); else restart = true; } @@ -143,7 +143,7 @@ static void Midiplayer_Onchange(void) if (!Mix_GetSoundFonts() || stricmp(Mix_GetSoundFonts(), cv_midisoundfontpath.string)) { if (!Mix_SetSoundFonts(cv_midisoundfontpath.string)) // == 0 means error - CONS_Alert(CONS_ERROR, "Sound font error: %s", Mix_GetError()); + CONS_Alert(CONS_ERROR, "Sound font error: %s\n", Mix_GetError()); else restart = true; } @@ -190,7 +190,7 @@ static void MidiSoundfontPath_Onchange(void) if (proceed) { if (!Mix_SetSoundFonts(cv_midisoundfontpath.string)) - CONS_Alert(CONS_ERROR, "Sound font error: %s", Mix_GetError()); + CONS_Alert(CONS_ERROR, "Sound font error: %s\n", Mix_GetError()); else S_StartEx(true); } @@ -199,7 +199,18 @@ static void MidiSoundfontPath_Onchange(void) // make sure that s_sound.c does not already verify these // which happens when: defined(HAVE_MIXERX) && !defined(HAVE_MIXER) -static CV_PossibleValue_t midiplayer_cons_t[] = {{MIDI_OPNMIDI, "OPNMIDI"}, {MIDI_Fluidsynth, "Fluidsynth"}, {MIDI_Timidity, "Timidity"}, {MIDI_Native, "Native"}, {0, NULL}}; +static CV_PossibleValue_t midiplayer_cons_t[] = { + {MIDI_ADLMIDI, "ADLMIDI"}, + {MIDI_OPNMIDI, "OPNMIDI"}, + {MIDI_Timidity, "Timidity"}, + {MIDI_Fluidsynth, "Fluidsynth"}, +#if SDL_MIXER_VERSION_ATLEAST(2,6,0) + {MIDI_EDMIDI, "EDMIDI"}, +#endif + {MIDI_Native, "Native"}, + {MIDI_ANY, "Any"}, + {0, NULL} +}; consvar_t cv_midiplayer = CVAR_INIT ("midiplayer", "OPNMIDI" /*MIDI_OPNMIDI*/, CV_CALL|CV_NOINIT|CV_SAVE, midiplayer_cons_t, Midiplayer_Onchange); consvar_t cv_midisoundfontpath = CVAR_INIT ("midisoundfont", "sf2/8bitsf.SF2", CV_CALL|CV_NOINIT|CV_SAVE, NULL, MidiSoundfontPath_Onchange); consvar_t cv_miditimiditypath = CVAR_INIT ("midisoundbank", "./timidity", CV_SAVE, NULL, NULL); diff --git a/vcpkg.json b/vcpkg.json index 07c4244ad..3b79ec83f 100644 --- a/vcpkg.json +++ b/vcpkg.json @@ -2,84 +2,67 @@ "$schema": "https://raw.githubusercontent.com/microsoft/vcpkg-tool/main/docs/vcpkg.schema.json", "name": "srb2", "version": "1.0.0", - "builtin-baseline": "c823fd3e57035b10d970a96da2796a2db55e5df5", + "builtin-baseline": "d5ec528843d29e3a52d745a64b469f810b2cedbf", "dependencies": [ - "curl", { - "name": "libgme", - "platform": "!(windows & mingw) & !native" + "name": "curl", + "platform": "!wasm32" }, + "libgme", { - "name": "libopenmpt", - "platform": "!(windows & mingw)" + "name":"libopenmpt", + "platform": "!wasm32" }, "libpng", "miniupnpc", - "sdl2", + { + "name": "sdl2", + "default-features": false, + "features": [ + { + "name": "wayland", + "platform": "linux" + }, + { + "name": "x11", + "platform": "!windows" + } + ], + "platform": "!wasm32", + "version>=": "2.30.6#2" + }, { "name": "sdl2-mixer-ext", "features": [ { - "name": "cmd", - "platform": "linux" + "name":"fluidsynth", + "platform": "!static" }, { - "name": "libflac", - "platform": "!(windows & mingw & !static)" + "name":"libflac", + "platform": "!wasm32" + }, + "libgme", + "libmodplug", + { + "name":"libvorbis", + "platform": "!wasm32" + }, + "libxmp", + { + "name":"mpg123", + "platform": "!wasm32" }, { - "name": "libgme", - "platform": "!(windows & mingw) & !native" + "name":"opusfile", + "platform": "!wasm32" }, - { - "name": "libmodplug", - "platform": "!(windows & mingw)" - }, - { - "name": "libopnmidi", - "platform": "!(windows & mingw)" - }, - { - "name": "libvorbis", - "platform": "!(windows & mingw & !static)" - }, - { - "name": "libxmp", - "platform": "!(windows & mingw)" - }, - { - "name": "mpg123", - "platform": "!(windows & mingw)" - }, - { - "name": "nativemidi", - "platform": "!(windows & mingw)" - }, - { - "name": "opusfile", - "platform": "!(windows & mingw)" - }, - { - "name": "pxtone", - "platform": "!(windows & mingw)" - }, - { - "name": "timidity", - "platform": "!(windows & mingw)" - }, - { - "name": "wavpack", - "platform": "!(windows & mingw)" - } - ] + "pxtone", + "timidity" + ], + "platform": "!wasm32", + "version>=": "2.6.0#0" }, "zlib" - ], - "overrides": [ - { - "name": "sdl2", - "version": "2.28.5", - "port-version": 1 - } ] }