Merge branch 'next' into cleanupmusic

This commit is contained in:
spherallic 2024-06-25 12:09:13 +02:00
commit 8c6701239d
189 changed files with 12319 additions and 8759 deletions

1
.gitignore vendored
View file

@ -26,3 +26,4 @@ Win32_LIB_ASM_Release
/CMakeUserPresets.json /CMakeUserPresets.json
/out /out
/objs/VC10 /objs/VC10
/thirdparty/vcpkg-overlays

View file

@ -1,848 +1,19 @@
include:
- '.gitlab/ci/templates/*.yml'
- '.gitlab/ci/jobs/*.yml'
workflow:
auto_cancel:
on_new_commit: interruptible
variables: variables:
GIT_STRATEGY: clone
GIT_CLONE_PATH: $CI_BUILDS_DIR/$CI_CONCURRENT_ID/$CI_PROJECT_PATH GIT_CLONE_PATH: $CI_BUILDS_DIR/$CI_CONCURRENT_ID/$CI_PROJECT_PATH
GIT_DEPTH: 20
default:
image: git.do.srb2.org:5050/stjr/srb2ci/srb2ci:stable
cache:
- key: ccache-$CI_PROJECT_PATH_SLUG-$CI_JOB_NAME_SLUG
fallback_keys:
- cache-$CI_PROJECT_PATH_SLUG-$CI_DEFAULT_BRANCH
- cache-$CI_PROJECT_PATH_SLUG-default
paths:
- ccache
- ccache_statslog
- key: apt-$CI_JOB_IMAGE
paths:
- apt-cache
unprotect: true
- key: apk-$CI_JOB_IMAGE
paths:
- apk-cache
unprotect: true
before_script:
- - |
# debconf
echo -e "\e[0Ksection_start:`date +%s`:debconf[collapsed=true]\r\e[0KSetup debconf's environment"
- export DEBIAN_FRONTEND="noninteractive"
- export DEBIAN_PRIORITY="low"
- export DEBCONF_NONINTERACTIVE_SEEN="true"
- |
# debconf
echo -e "\e[0Ksection_end:`date +%s`:debconf\r\e[0K"
- - |
# dpkg_aa
echo -e "\e[0Ksection_start:`date +%s`:dpkg_aa[collapsed=true]\r\e[0KAdding architectures to dpkg"
- dpkg --add-architecture i386
- dpkg --add-architecture amd64
- dpkg --add-architecture arm64
- |
# dpkg_aa
echo -e "\e[0Ksection_end:`date +%s`:dpkg_aa\r\e[0K"
- - |
# apt_conf
echo -e "\e[0Ksection_start:`date +%s`:apt_conf[collapsed=true]\r\e[0KSetting up APT conf"
- export APT_CACHE_DIR=`pwd`/apt-cache
- mkdir --parents --verbose $APT_CACHE_DIR/partial/
- touch /etc/apt/apt.conf.d/99build
- |
# apt.conf
echo Adding options to apt.conf':'
- |
# APT::Install-Recommends
echo APT::Install-Recommends "false"\; | tee --append /etc/apt/apt.conf.d/99build
- |
# quit
echo quiet "1"\; | tee --append /etc/apt/apt.conf.d/99build
- |
# APT::Get::Assume-Yes
echo APT::Get::Assume-Yes "true"\; | tee --append /etc/apt/apt.conf.d/99build
- |
# Dir::Cache::Archives
echo Dir::Cache::Archives "$APT_CACHE_DIR"\; | tee --append /etc/apt/apt.conf.d/99build
- |
# apt_conf
echo -e "\e[0Ksection_end:`date +%s`:apt_conf\r\e[0K"
- - |
# apt_update
echo -e "\e[0Ksection_start:`date +%s`:apt_update[collapsed=true]\r\e[0KUpdating APT listing"
- apt-get update
- |
# apt_update
echo -e "\e[0Ksection_end:`date +%s`:apt_update\r\e[0K"
- - |
# apt_pre
echo -e "\e[0Ksection_start:`date +%s`:apt_pre[collapsed=true]\r\e[0KInstalling pre packages"
- apt-get install apt-utils
- |
# apt_pre
echo -e "\e[0Ksection_end:`date +%s`:apt_pre\r\e[0K"
- - |
# apt_upgrade
echo -e "\e[0Ksection_start:`date +%s`:apt_upgrade[collapsed=true]\r\e[0KUpdating existing packages"
- apt-get upgrade
- |
# apt_update
echo -e "\e[0Ksection_end:`date +%s`:apt_upgrade\r\e[0K"
- - |
# apt_common
echo -e "\e[0Ksection_start:`date +%s`:apt_common[collapsed=true]\r\e[0KInstalling common packages"
- apt-get install make git ccache nasm cmake ca-certificates
- |
# apt_common
echo -e "\e[0Ksection_end:`date +%s`:apt_common\r\e[0K"
- - |
# 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 --append ~/.ccache/ccache.conf
- |
# cache_dir
echo cache_dir = $PWD/ccache | tee --append ~/.ccache/ccache.conf
- |
# compiler_check
echo compiler_check = content | tee --append ~/.ccache/ccache.conf
- |
# stats_log
echo stats_log = $PWD/ccache_statslog | tee --append ~/.ccache/ccache.conf
- |
# max_size
echo max_size = 50M | tee --append ~/.ccache/ccache.conf
- |
# ccache_config
echo -e "\e[0Ksection_end:`date +%s`:ccache_config\r\e[0K"
- - |
# cache_reset
echo -e "\e[0Ksection_start:`date +%s`:ccache_reset[collapsed=true]\r\e[0KResetting ccache statistics"
- ccache --zero-stats
- ccache --show-stats
- |
# ccache_reset
echo -e "\e[0Ksection_end:`date +%s`:ccache_reset\r\e[0K"
artifacts:
paths:
- "bin/"
- "src/comptime.h"
name: "$CI_PROJECT_PATH_SLUG-$CI_COMMIT_REF_SLUG-$CI_COMMIT_SHORT_SHA-$CI_JOB_NAME_SLUG"
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"
stages: stages:
- build - build
Debian testing GCC: default:
stage: build interruptible: true
when: manual
image: debian:testing-slim
allow_failure: true
artifacts: artifacts:
paths: expire_in: 1 day
- "bin/"
- "src/comptime.h"
expose_as: "testing-gcc"
name: "$CI_PROJECT_PATH_SLUG-$CI_COMMIT_REF_SLUG-$CI_COMMIT_SHORT_SHA-testing-gcc"
variables:
CC: gcc
LDFLAGS: -Wl,-fuse-ld=gold
script:
- - |
# apt_toolchain
echo -e "\e[0Ksection_start:`date +%s`:apt_toolchain[collapsed=true]\r\e[0KInstalling toolchain packages"
- apt-get install gcc
- |
# apt_toolchain
echo -e "\e[0Ksection_end:`date +%s`:apt_toolchain\r\e[0K"
- - |
# apt_development
echo -e "\e[0Ksection_start:`date +%s`:apt_development[collapsed=true]\r\e[0KInstalling development packages"
- apt-get install libsdl2-mixer-dev libpng-dev libcurl4-openssl-dev libgme-dev libopenmpt-dev libminiupnpc-dev
- |
# apt_development
echo -e "\e[0Ksection_end:`date +%s`:apt_development\r\e[0K"
- - |
# make
echo -e "\e[0Ksection_start:`date +%s`:make[collapsed=false]\r\e[0KCompiling SRB2"
- make --directory=src --keep-going CCACHE=1 ERRORMODE=1 NONX86=1 || make --directory=src --keep-going CCACHE=1 ERRORMODE=1 NONX86=1
- |
# make
echo -e "\e[0Ksection_end:`date +%s`:make\r\e[0K"
Windows x86:
stage: build
when: on_success
artifacts:
paths:
- "bin/"
- "src/comptime.h"
expose_as: "Win32"
name: "$CI_PROJECT_PATH_SLUG-$CI_COMMIT_REF_SLUG-$CI_COMMIT_SHORT_SHA-Win32"
variables:
PREFIX: i686-w64-mingw32
script:
- - |
# apt_toolchain
echo -e "\e[0Ksection_start:`date +%s`:apt_toolchain[collapsed=true]\r\e[0KInstalling toolchain packages"
- apt-get install gcc-mingw-w64-i686-win32
- |
# apt_toolchain
echo -e "\e[0Ksection_end:`date +%s`:apt_toolchain\r\e[0K"
- - |
# make
echo -e "\e[0Ksection_start:`date +%s`:make[collapsed=false]\r\e[0KCompiling SRB2"
- make --directory=src --keep-going CCACHE=1 ERRORMODE=1 MINGW=1 SDL=1 || make --directory=src --keep-going CCACHE=1 ERRORMODE=1 MINGW=1 SDL=1
- |
# make
echo -e "\e[0Ksection_end:`date +%s`:make\r\e[0K"
Debian stable:amd64:
stage: build
when: on_success
artifacts:
paths:
- "bin/"
- "src/comptime.h"
expose_as: "Debian amd64"
name: "$CI_PROJECT_PATH_SLUG-$CI_COMMIT_REF_SLUG-$CI_COMMIT_SHORT_SHA-x86-64"
variables:
CC: x86_64-linux-gnu-gcc
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
script:
- - |
# apt_toolchain
echo -e "\e[0Ksection_start:`date +%s`:apt_toolchain[collapsed=true]\r\e[0KInstalling toolchain packages"
- apt-get install gcc-x86-64-linux-gnu || apt-get install gcc
- |
# apt_toolchain
echo -e "\e[0Ksection_end:`date +%s`:apt_toolchain\r\e[0K"
- - |
# apt_development
echo -e "\e[0Ksection_start:`date +%s`:apt_development[collapsed=true]\r\e[0KInstalling development packages"
- apt-get install libsdl2-mixer-dev:amd64 libpng-dev:amd64 libcurl4-openssl-dev:amd64 libgme-dev:amd64 libopenmpt-dev:amd64 libminiupnpc-dev:amd64
- |
# apt_development
echo -e "\e[0Ksection_end:`date +%s`:apt_development\r\e[0K"
- - |
# make
echo -e "\e[0Ksection_start:`date +%s`:make[collapsed=false]\r\e[0KCompiling SRB2"
- make --directory=src --keep-going CCACHE=1 ERRORMODE=1 LINUX64=1 || make --directory=src --keep-going CCACHE=1 ERRORMODE=1 LINUX64=1
- |
# make
echo -e "\e[0Ksection_end:`date +%s`:make\r\e[0K"
Debian oldstable:amd64:
extends: Debian stable:amd64
when: manual
image: git.do.srb2.org:5050/stjr/srb2ci/srb2ci:oldstable
allow_failure: true
artifacts:
paths:
- "bin/"
- "src/comptime.h"
expose_as: "Debian old amd64"
name: "$CI_PROJECT_PATH_SLUG-$CI_COMMIT_REF_SLUG-$CI_COMMIT_SHORT_SHA-old-x86-64"
script:
- - |
# apt_toolchain
echo -e "\e[0Ksection_start:`date +%s`:apt_toolchain[collapsed=true]\r\e[0KInstalling toolchain packages"
- apt-get install gcc-x86-64-linux-gnu || apt-get install gcc
- |
# apt_toolchain
echo -e "\e[0Ksection_end:`date +%s`:apt_toolchain\r\e[0K"
- - |
# apt_development
echo -e "\e[0Ksection_start:`date +%s`:apt_development[collapsed=true]\r\e[0KInstalling development packages"
- apt-get install libsdl2-mixer-dev:amd64 libpng-dev:amd64 libcurl4-openssl-dev:amd64 libopenmpt-dev:amd64 libminiupnpc-dev:amd64
- |
# apt_development
echo -e "\e[0Ksection_end:`date +%s`:apt_development\r\e[0K"
- - |
# make
echo -e "\e[0Ksection_start:`date +%s`:make[collapsed=false]\r\e[0KCompiling SRB2"
- make --directory=src --keep-going CCACHE=1 ERRORMODE=1 LINUX64=1 NOGME=1 || make --directory=src --keep-going CCACHE=1 ERRORMODE=1 LINUX64=1 NOGME=1
- |
# make
echo -e "\e[0Ksection_end:`date +%s`:make\r\e[0K"
Debian stable:i386:
stage: build
when: manual
artifacts:
paths:
- "bin/"
- "src/comptime.h"
expose_as: "Debian i386"
name: "$CI_PROJECT_PATH_SLUG-$CI_COMMIT_REF_SLUG-$CI_COMMIT_SHORT_SHA-i686"
variables:
CC: i686-linux-gnu-gcc
OBJCOPY: i686-linux-gnu-objcopy
OBJDUMP: i686-linux-gnu-objdump
PKG_CONFIG_PATH: /usr/lib/i386-linux-gnu/pkgconfig
script:
- - |
# apt_toolchain
echo -e "\e[0Ksection_start:`date +%s`:apt_toolchain[collapsed=true]\r\e[0KInstalling toolchain packages"
- apt-get install gcc-i686-linux-gnu || apt-get install gcc
- |
# apt_toolchain
echo -e "\e[0Ksection_end:`date +%s`:apt_toolchain\r\e[0K"
- - |
# apt_development
echo -e "\e[0Ksection_start:`date +%s`:apt_development[collapsed=true]\r\e[0KInstalling development packages"
- apt-get install libsdl2-mixer-dev:i386 libpng-dev:i386 libcurl4-openssl-dev:i386 libgme-dev:i386 libopenmpt-dev:i386 libminiupnpc-dev:i386
- |
# apt_development
echo -e "\e[0Ksection_end:`date +%s`:apt_development\r\e[0K"
- - |
# make
echo -e "\e[0Ksection_start:`date +%s`:make[collapsed=false]\r\e[0KCompiling SRB2"
- make --directory=src --keep-going CCACHE=1 ERRORMODE=1 LINUX=1 || make --directory=src --keep-going CCACHE=1 ERRORMODE=1 LINUX=1
- |
# make
echo -e "\e[0Ksection_end:`date +%s`:make\r\e[0K"
Debian stable:arm64:
stage: build
when: manual
artifacts:
paths:
- "bin/"
- "src/comptime.h"
expose_as: "Debian arm64"
name: "$CI_PROJECT_PATH_SLUG-$CI_COMMIT_REF_SLUG-$CI_COMMIT_SHORT_SHA-aarch64"
variables:
CC: aarch64-linux-gnu-gcc
LDFLAGS: -Wl,-fuse-ld=gold
OBJCOPY: aarch64-linux-gnu-objcopy
OBJDUMP: aarch64-linux-gnu-objdump
PKG_CONFIG_PATH: /usr/lib/aarch64-linux-gnu/pkgconfig
script:
- - |
# apt_toolchain
echo -e "\e[0Ksection_start:`date +%s`:apt_toolchain[collapsed=true]\r\e[0KInstalling toolchain packages"
- apt-get install gcc-aarch64-linux-gnu || apt-get install gcc
- |
# apt_toolchain
echo -e "\e[0Ksection_end:`date +%s`:apt_toolchain\r\e[0K"
- - |
# apt_development
echo -e "\e[0Ksection_start:`date +%s`:apt_development[collapsed=true]\r\e[0KInstalling development packages"
- apt-get install libsdl2-mixer-dev:arm64 libpng-dev:arm64 libcurl4-openssl-dev:arm64 libgme-dev:arm64 libopenmpt-dev:arm64 libminiupnpc-dev:arm64
- |
# apt_development
echo -e "\e[0Ksection_end:`date +%s`:apt_development\r\e[0K"
- - |
# make
echo -e "\e[0Ksection_start:`date +%s`:make[collapsed=false]\r\e[0KCompiling SRB2"
- make --directory=src --keep-going CCACHE=1 ERRORMODE=1 LINUX64=1 ERRORMODE=1 NONX86=1 ARM64=1 || make --directory=src --keep-going CCACHE=1 ERRORMODE=1 LINUX64=1 NONX86=1 ARM64=1
- |
# make
echo -e "\e[0Ksection_end:`date +%s`:make\r\e[0K"
Debian oldstable:arm64:
extends: Debian stable:arm64
when: manual
image: git.do.srb2.org:5050/stjr/srb2ci/srb2ci:oldstable
allow_failure: true
artifacts:
paths:
- "bin/"
- "src/comptime.h"
expose_as: "Debian old arm64"
name: "$CI_PROJECT_PATH_SLUG-$CI_COMMIT_REF_SLUG-$CI_COMMIT_SHORT_SHA-old-aarch64"
script:
- - |
# apt_toolchain
echo -e "\e[0Ksection_start:`date +%s`:apt_toolchain[collapsed=true]\r\e[0KInstalling toolchain packages"
- apt-get install gcc-aarch64-linux-gnu || apt-get install gcc
- |
# apt_toolchain
echo -e "\e[0Ksection_end:`date +%s`:apt_toolchain\r\e[0K"
- - |
# apt_development
echo -e "\e[0Ksection_start:`date +%s`:apt_development[collapsed=true]\r\e[0KInstalling development packages"
- apt-get install libsdl2-mixer-dev:arm64 libpng-dev:arm64 libcurl4-openssl-dev:arm64 libopenmpt-dev:arm64 libminiupnpc-dev:arm64
- |
# apt_development
echo -e "\e[0Ksection_end:`date +%s`:apt_development\r\e[0K"
- - |
# make
echo -e "\e[0Ksection_start:`date +%s`:make[collapsed=false]\r\e[0KCompiling SRB2"
- make --directory=src --keep-going CCACHE=1 ERRORMODE=1 LINUX64=1 ERRORMODE=1 NONX86=1 ARM64=1 NOGME=1 || make --directory=src --keep-going CCACHE=1 ERRORMODE=1 LINUX64=1 NONX86=1 ARM64=1 NOGME=1
- |
# make
echo -e "\e[0Ksection_end:`date +%s`:make\r\e[0K"
batocera:arm64:
extends: Debian stable:arm64
when: manual
allow_failure: true
artifacts:
paths:
- "bin/"
- "src/comptime.h"
expose_as: "Debian old arm64"
name: "$CI_PROJECT_PATH_SLUG-$CI_COMMIT_REF_SLUG-$CI_COMMIT_SHORT_SHA-batocera-aarch64"
script:
- - |
# apt_toolchain
echo -e "\e[0Ksection_start:`date +%s`:apt_toolchain[collapsed=true]\r\e[0KInstalling toolchain packages"
- apt-get install gcc-aarch64-linux-gnu || apt-get install gcc
- |
# apt_toolchain
echo -e "\e[0Ksection_end:`date +%s`:apt_toolchain\r\e[0K"
- - |
# apt_development
echo -e "\e[0Ksection_start:`date +%s`:apt_development[collapsed=true]\r\e[0KInstalling development packages"
- apt-get install libsdl2-mixer-dev:arm64 libpng-dev:arm64 libcurl4-openssl-dev:arm64 libopenmpt-dev:arm64 libminiupnpc-dev:arm64
- |
# apt_development
echo -e "\e[0Ksection_end:`date +%s`:apt_development\r\e[0K"
- - |
# make
echo -e "\e[0Ksection_start:`date +%s`:make[collapsed=false]\r\e[0KCompiling SRB2"
- make --directory=src --keep-going CCACHE=1 ERRORMODE=1 LINUX64=1 ERRORMODE=1 NONX86=1 ARM64=1 NOGME=1 || make --directory=src --keep-going CCACHE=1 ERRORMODE=1 LINUX64=1 NONX86=1 ARM64=1 NOGME=1
- |
# make
echo -e "\e[0Ksection_end:`date +%s`:make\r\e[0K"
Windows x64:
stage: build
when: manual
artifacts:
paths:
- "bin/"
- "src/comptime.h"
expose_as: "Win64"
name: "$CI_PROJECT_PATH_SLUG-$CI_COMMIT_REF_SLUG-$CI_COMMIT_SHORT_SHA-Win64"
variables:
PREFIX: x86_64-w64-mingw32
script:
- - |
# apt_toolchain
echo -e "\e[0Ksection_start:`date +%s`:apt_toolchain[collapsed=true]\r\e[0KInstalling toolchain packages"
- apt-get install gcc-mingw-w64-x86-64-win32
- |
# apt_toolchain
echo -e "\e[0Ksection_end:`date +%s`:apt_toolchain\r\e[0K"
- - |
# make
echo -e "\e[0Ksection_start:`date +%s`:make[collapsed=false]\r\e[0KCompiling SRB2"
- make --directory=src --keep-going CCACHE=1 ERRORMODE=1 MINGW64=1 SDL=1 || make --directory=src --keep-going CCACHE=1 ERRORMODE=1 MINGW64=1 SDL=1
- |
# make
echo -e "\e[0Ksection_end:`date +%s`:make\r\e[0K"
Debian stable Clang:
stage: build
when: on_success
allow_failure: false
artifacts:
paths:
- "build.clang/bin/"
- "build.clang/src/config.h"
expose_as: "clang"
name: "$CI_PROJECT_PATH_SLUG-$CI_COMMIT_REF_SLUG-$CI_COMMIT_SHORT_SHA-clang"
variables:
CC: clang
CXX: clang
WFLAGS: -Wno-cast-align -Wno-implicit-const-int-float-conversion -Werror
CFLAGS: -Wno-cast-align -Wno-implicit-const-int-float-conversion -Werror
LDFLAGS: -Wl,-fuse-ld=gold
script:
- - |
# apt_toolchain
echo -e "\e[0Ksection_start:`date +%s`:apt_toolchain[collapsed=true]\r\e[0KInstalling toolchain packages"
- apt-get install clang
- |
# apt_toolchain
echo -e "\e[0Ksection_end:`date +%s`:apt_toolchain\r\e[0K"
- - |
# apt_development
echo -e "\e[0Ksection_start:`date +%s`:apt_development[collapsed=true]\r\e[0KInstalling development packages"
- apt-get install libsdl2-mixer-dev libpng-dev libcurl4-openssl-dev libgme-dev libopenmpt-dev libminiupnpc-dev
- |
# apt_development
echo -e "\e[0Ksection_end:`date +%s`:apt_development\r\e[0K"
- - |
# 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
echo -e "\e[0Ksection_end:`date +%s`:cmake\r\e[0K"
- - |
# 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
- |
# make
echo -e "\e[0Ksection_end:`date +%s`:make\r\e[0K"
Debian testing Clang:
extends: Debian stable Clang
when: manual
allow_failure: true
image: debian:testing-slim
artifacts:
paths:
- "build.clang/bin/"
- "build.clang/src/config.h"
expose_as: "testing-clang"
name: "$CI_PROJECT_PATH_SLUG-$CI_COMMIT_REF_SLUG-$CI_COMMIT_SHORT_SHA-testing-clang"
variables:
CC: clang
CXX: clang
WFLAGS: -Wno-cast-align -Wno-implicit-const-int-float-conversion -Werror -Wno-deprecated-non-prototype -Wno-single-bit-bitfield-constant-conversion
CFLAGS: -Wno-cast-align -Wno-implicit-const-int-float-conversion -Werror -Wno-deprecated-non-prototype -Wno-single-bit-bitfield-constant-conversion
LDFLAGS: -Wl,-fuse-ld=gold
Alpine 3 GCC:
stage: build
when: on_success
image: alpine:3
allow_failure: true
artifacts:
paths:
- "bin/"
- "src/comptime.h"
expose_as: "Apline-3"
name: "$CI_PROJECT_PATH_SLUG-$CI_COMMIT_REF_SLUG-$CI_COMMIT_SHORT_SHA-Apline-3"
before_script:
- - |
# apk_cache
echo -e "\e[0Ksection_start:`date +%s`:apk_cache[collapsed=true]\r\e[0KUpdating APK listing"
- export APK_CACHE_DIR=`pwd`/apk-cache
- mkdir --parents --verbose $APK_CACHE_DIR/
- ln -sf /etc/apk/cache $APK_CACHE_DIR
- |
# apk_cache
echo -e "\e[0Ksection_end:`date +%s`:apk_cache\r\e[0K"
- - |
# apk_update
echo -e "\e[0Ksection_start:`date +%s`:apk_update[collapsed=true]\r\e[0KUpdating APK listing"
- apk update
- |
# apk_update
echo -e "\e[0Ksection_end:`date +%s`:apk_update\r\e[0K"
- - |
# apk_upgrade
echo -e "\e[0Ksection_start:`date +%s`:apk_upgrade[collapsed=true]\r\e[0KUpdating existing packages"
- apk upgrade
- |
# apk_update
echo -e "\e[0Ksection_end:`date +%s`:apk_upgrade\r\e[0K"
- - |
# apk_common
echo -e "\e[0Ksection_start:`date +%s`:apk_common[collapsed=true]\r\e[0KInstalling common packages"
- apk add make git ccache nasm
- |
# apk_common
echo -e "\e[0Ksection_end:`date +%s`:apk_common\r\e[0K"
- - |
# 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
- |
# cache_dir
echo cache_dir = $PWD/ccache | tee -a ~/.ccache/ccache.conf
- |
# compiler_check
echo compiler_check = content | tee -a ~/.ccache/ccache.conf
- |
# stats_log
echo stats_log = $PWD/ccache_statslog | tee -a ~/.ccache/ccache.conf
- |
# max_size
echo max_size = 50M | tee -a ~/.ccache/ccache.conf
- |
# ccache_config
echo -e "\e[0Ksection_end:`date +%s`:ccache_config\r\e[0K"
- - |
# cache_reset
echo -e "\e[0Ksection_start:`date +%s`:ccache_reset[collapsed=true]\r\e[0KResetting ccache statistics"
- ccache --zero-stats
- ccache --show-stats
- |
# ccache_reset
echo -e "\e[0Ksection_end:`date +%s`:ccache_reset\r\e[0K"
script:
- - |
# apk_toolchain
echo -e "\e[0Ksection_start:`date +%s`:apk_toolchain[collapsed=true]\r\e[0KInstalling toolchain packages"
- apk add gcc
- |
# apk_toolchain
echo -e "\e[0Ksection_end:`date +%s`:apk_toolchain\r\e[0K"
- - |
# apk_development
echo -e "\e[0Ksection_start:`date +%s`:apk_development[collapsed=true]\r\e[0KInstalling development packages"
- apk add musl-dev sdl2_mixer-dev libpng-dev curl-dev libgme-dev libopenmpt-dev miniupnpc-dev
- |
# apk_development
echo -e "\e[0Ksection_end:`date +%s`:apk_development\r\e[0K"
- - |
# make
echo -e "\e[0Ksection_start:`date +%s`:make[collapsed=false]\r\e[0KCompiling SRB2"
- make --directory=src --keep-going CCACHE=1 ERRORMODE=1 NONX86=1 NOEXECINFO=1 || make --directory=src --keep-going CCACHE=1 ERRORMODE=1 NONX86=1 NOEXECINFO=1
- |
# make
echo -e "\e[0Ksection_end:`date +%s`:make\r\e[0K"
after_script:
- - |
# apk_clean
echo -e "\e[0Ksection_start:`date +%s`:apk_clean[collapsed=true]\r\e[0KCleaning of unneeded APK packages"
- apk cache clean
- |
# apk_clean
echo -e "\e[0Ksection_end:`date +%s`:apk_clean\r\e[0K"
- - |
# ccache_stats
echo -e "\e[0Ksection_start:`date +%s`:ccache_stats[collapsed=true]\r\e[0Kccache statistics:"
- ccache --show-stats --verbose
- ccache --show-log-stats --verbose
- |
# ccahe_stats
echo -e "\e[0Ksection_end:`date +%s`:ccache_stats\r\e[0K"
Alpine 3 GCC Dedicated:
extends: Alpine 3 GCC
artifacts:
paths:
- "bin/"
- "src/comptime.h"
expose_as: "Apline-3-Dedicated"
name: "$CI_PROJECT_PATH_SLUG-$CI_COMMIT_REF_SLUG-$CI_COMMIT_SHORT_SHA-Apline-3-Dedicated"
script:
- - |
# apk_toolchain
echo -e "\e[0Ksection_start:`date +%s`:apk_toolchain[collapsed=true]\r\e[0KInstalling toolchain packages"
- apk add gcc
- |
# apk_toolchain
echo -e "\e[0Ksection_end:`date +%s`:apk_toolchain\r\e[0K"
- - |
# apk_development
echo -e "\e[0Ksection_start:`date +%s`:apk_development[collapsed=true]\r\e[0KInstalling development packages"
- apk add musl-dev libpng-dev curl-dev
- |
# apk_development
echo -e "\e[0Ksection_end:`date +%s`:apk_development\r\e[0K"
- - |
# make
echo -e "\e[0Ksection_start:`date +%s`:make[collapsed=false]\r\e[0KCompiling SRB2"
- make --directory=src --keep-going CCACHE=1 ERRORMODE=1 NONX86=1 NOEXECINFO=1 DEDICATED=1 || make --directory=src --keep-going CCACHE=1 ERRORMODE=1 NONX86=1 NOEXECINFO=1 DEDICATED=1
- |
# make
echo -e "\e[0Ksection_end:`date +%s`:make\r\e[0K"
osxcross x86_64:
stage: build
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"
variables:
OSXCROSS_HOST: x86_64-apple-darwin21.4
LD: x86_64-apple-darwin21.4-ld
script:
- - |
# 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
- |
# apt_development
echo -e "\e[0Ksection_end:`date +%s`:macports_development\r\e[0K"
- - |
# make
echo -e "\e[0Ksection_start:`date +%s`:make[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"
- |
# make
echo -e "\e[0Ksection_end:`date +%s`:make\r\e[0K"
- - |
# 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
- |
# make
echo -e "\e[0Ksection_end:`date +%s`:make\r\e[0K"
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"
variables:
OSXCROSS_HOST: arm64-apple-darwin21.4
LD: arm64-apple-darwin21.4-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
- |
# apt_development
echo -e "\e[0Ksection_end:`date +%s`:macports_development\r\e[0K"
- - |
# make
echo -e "\e[0Ksection_start:`date +%s`:make[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"
- |
# make
echo -e "\e[0Ksection_end:`date +%s`:make\r\e[0K"
- - |
# 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
- |
# make
echo -e "\e[0Ksection_end:`date +%s`:make\r\e[0K"

View file

@ -0,0 +1,34 @@
Alpine 3 GCC Dedicated:
extends: Alpine 3 GCC
artifacts:
paths:
- "bin/"
- "src/comptime.h"
expose_as: "Apline-3-Dedicated"
name: "$CI_PROJECT_PATH_SLUG-$CI_COMMIT_REF_SLUG-$CI_COMMIT_SHORT_SHA-Apline-3-Dedicated"
script:
- - |
# apk_toolchain
echo -e "\e[0Ksection_start:`date +%s`:apk_toolchain[collapsed=true]\r\e[0KInstalling toolchain packages"
- apk add gcc
- |
# apk_toolchain
echo -e "\e[0Ksection_end:`date +%s`:apk_toolchain\r\e[0K"
- - |
# apk_development
echo -e "\e[0Ksection_start:`date +%s`:apk_development[collapsed=true]\r\e[0KInstalling development packages"
- apk add musl-dev libpng-dev curl-dev
- |
# apk_development
echo -e "\e[0Ksection_end:`date +%s`:apk_development\r\e[0K"
- - |
# make
echo -e "\e[0Ksection_start:`date +%s`:make[collapsed=false]\r\e[0KCompiling SRB2"
- make --directory=src --keep-going CCACHE=1 ERRORMODE=1 NONX86=1 NOEXECINFO=1 DEDICATED=1 || make --directory=src --keep-going CCACHE=1 ERRORMODE=1 NONX86=1 NOEXECINFO=1 DEDICATED=1
- |
# make
echo -e "\e[0Ksection_end:`date +%s`:make\r\e[0K"

View file

@ -0,0 +1,135 @@
Alpine 3 GCC:
stage: build
when: manual
image: alpine:3
allow_failure: true
cache:
- key: apk-$CI_JOB_IMAGE
paths:
- apk-cache
unprotect: true
artifacts:
paths:
- "bin/"
- "src/comptime.h"
expose_as: "Apline-3"
name: "$CI_PROJECT_PATH_SLUG-$CI_COMMIT_REF_SLUG-$CI_COMMIT_SHORT_SHA-Apline-3"
before_script:
- - |
# apk_cache
echo -e "\e[0Ksection_start:`date +%s`:apk_cache[collapsed=true]\r\e[0KUpdating APK listing"
- export APK_CACHE_DIR=`pwd`/apk-cache
- mkdir --parents --verbose $APK_CACHE_DIR/
- ln -sf /etc/apk/cache $APK_CACHE_DIR
- |
# apk_cache
echo -e "\e[0Ksection_end:`date +%s`:apk_cache\r\e[0K"
- - |
# apk_update
echo -e "\e[0Ksection_start:`date +%s`:apk_update[collapsed=true]\r\e[0KUpdating APK listing"
- apk update
- |
# apk_update
echo -e "\e[0Ksection_end:`date +%s`:apk_update\r\e[0K"
- - |
# apk_upgrade
echo -e "\e[0Ksection_start:`date +%s`:apk_upgrade[collapsed=true]\r\e[0KUpdating existing packages"
- apk upgrade
- |
# apk_update
echo -e "\e[0Ksection_end:`date +%s`:apk_upgrade\r\e[0K"
- - |
# apk_common
echo -e "\e[0Ksection_start:`date +%s`:apk_common[collapsed=true]\r\e[0KInstalling common packages"
- apk add make git ccache nasm
- |
# apk_common
echo -e "\e[0Ksection_end:`date +%s`:apk_common\r\e[0K"
- - |
# 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
- |
# cache_dir
echo cache_dir = $PWD/ccache | tee -a ~/.ccache/ccache.conf
- |
# compiler_check
echo compiler_check = content | tee -a ~/.ccache/ccache.conf
- |
# stats_log
echo stats_log = $PWD/ccache_statslog | tee -a ~/.ccache/ccache.conf
- |
# max_size
echo max_size = 50M | tee -a ~/.ccache/ccache.conf
- |
# ccache_config
echo -e "\e[0Ksection_end:`date +%s`:ccache_config\r\e[0K"
- - |
# cache_reset
echo -e "\e[0Ksection_start:`date +%s`:ccache_reset[collapsed=true]\r\e[0KResetting ccache statistics"
- ccache --zero-stats
- ccache --show-stats
- |
# ccache_reset
echo -e "\e[0Ksection_end:`date +%s`:ccache_reset\r\e[0K"
script:
- - |
# apk_toolchain
echo -e "\e[0Ksection_start:`date +%s`:apk_toolchain[collapsed=true]\r\e[0KInstalling toolchain packages"
- apk add gcc
- |
# apk_toolchain
echo -e "\e[0Ksection_end:`date +%s`:apk_toolchain\r\e[0K"
- - |
# apk_development
echo -e "\e[0Ksection_start:`date +%s`:apk_development[collapsed=true]\r\e[0KInstalling development packages"
- apk add musl-dev sdl2_mixer-dev libpng-dev curl-dev libgme-dev libopenmpt-dev miniupnpc-dev
- |
# apk_development
echo -e "\e[0Ksection_end:`date +%s`:apk_development\r\e[0K"
- - |
# make
echo -e "\e[0Ksection_start:`date +%s`:make[collapsed=false]\r\e[0KCompiling SRB2"
- make --directory=src --keep-going CCACHE=1 ERRORMODE=1 NONX86=1 NOEXECINFO=1 || make --directory=src --keep-going CCACHE=1 ERRORMODE=1 NONX86=1 NOEXECINFO=1
- |
# make
echo -e "\e[0Ksection_end:`date +%s`:make\r\e[0K"
after_script:
- - |
# apk_clean
echo -e "\e[0Ksection_start:`date +%s`:apk_clean[collapsed=true]\r\e[0KCleaning of unneeded APK packages"
- apk cache clean
- |
# apk_clean
echo -e "\e[0Ksection_end:`date +%s`:apk_clean\r\e[0K"
- - |
# ccache_stats
echo -e "\e[0Ksection_start:`date +%s`:ccache_stats[collapsed=true]\r\e[0Kccache statistics:"
- ccache --show-stats --verbose
- ccache --show-log-stats --verbose
- |
# ccahe_stats
echo -e "\e[0Ksection_end:`date +%s`:ccache_stats\r\e[0K"

View file

@ -0,0 +1,38 @@
batocera:arm64:
extends: Debian stable:arm64
when: manual
allow_failure: true
artifacts:
paths:
- "bin/"
- "src/comptime.h"
expose_as: "Debian old arm64"
name: "$CI_PROJECT_PATH_SLUG-$CI_COMMIT_REF_SLUG-$CI_COMMIT_SHORT_SHA-batocera-aarch64"
script:
- - |
# apt_toolchain
echo -e "\e[0Ksection_start:`date +%s`:apt_toolchain[collapsed=true]\r\e[0KInstalling toolchain packages"
- apt-get install gcc-aarch64-linux-gnu || apt-get install gcc
- |
# apt_toolchain
echo -e "\e[0Ksection_end:`date +%s`:apt_toolchain\r\e[0K"
- - |
# apt_development
echo -e "\e[0Ksection_start:`date +%s`:apt_development[collapsed=true]\r\e[0KInstalling development packages"
- apt-get install libsdl2-mixer-dev:arm64 libpng-dev:arm64 libcurl4-openssl-dev:arm64 libopenmpt-dev:arm64 libminiupnpc-dev:arm64
- |
# apt_development
echo -e "\e[0Ksection_end:`date +%s`:apt_development\r\e[0K"
- - |
# make
echo -e "\e[0Ksection_start:`date +%s`:make[collapsed=false]\r\e[0KCompiling SRB2"
- make --directory=src --keep-going CCACHE=1 ERRORMODE=1 LINUX64=1 ERRORMODE=1 NONX86=1 ARM64=1 NOGME=1 || make --directory=src --keep-going CCACHE=1 ERRORMODE=1 LINUX64=1 NONX86=1 ARM64=1 NOGME=1
- |
# make
echo -e "\e[0Ksection_end:`date +%s`:make\r\e[0K"

View file

@ -0,0 +1,40 @@
Debian oldstable:amd64:
extends: Debian stable:amd64
when: manual
image: git.do.srb2.org:5050/stjr/srb2ci/srb2ci:oldstable
allow_failure: true
artifacts:
paths:
- "bin/"
- "src/comptime.h"
expose_as: "Debian old amd64"
name: "$CI_PROJECT_PATH_SLUG-$CI_COMMIT_REF_SLUG-$CI_COMMIT_SHORT_SHA-old-x86-64"
script:
- - |
# apt_toolchain
echo -e "\e[0Ksection_start:`date +%s`:apt_toolchain[collapsed=true]\r\e[0KInstalling toolchain packages"
- apt-get install gcc-x86-64-linux-gnu || apt-get install gcc
- |
# apt_toolchain
echo -e "\e[0Ksection_end:`date +%s`:apt_toolchain\r\e[0K"
- - |
# apt_development
echo -e "\e[0Ksection_start:`date +%s`:apt_development[collapsed=true]\r\e[0KInstalling development packages"
- apt-get install libsdl2-mixer-dev:amd64 libpng-dev:amd64 libcurl4-openssl-dev:amd64 libopenmpt-dev:amd64 libminiupnpc-dev:amd64
- |
# apt_development
echo -e "\e[0Ksection_end:`date +%s`:apt_development\r\e[0K"
- - |
# make
echo -e "\e[0Ksection_start:`date +%s`:make[collapsed=false]\r\e[0KCompiling SRB2"
- make --directory=src --keep-going CCACHE=1 ERRORMODE=1 LINUX64=1 NOGME=1 || make --directory=src --keep-going CCACHE=1 ERRORMODE=1 LINUX64=1 NOGME=1
- |
# make
echo -e "\e[0Ksection_end:`date +%s`:make\r\e[0K"

View file

@ -0,0 +1,40 @@
Debian oldstable:arm64:
extends: Debian stable:arm64
when: manual
image: git.do.srb2.org:5050/stjr/srb2ci/srb2ci:oldstable
allow_failure: true
artifacts:
paths:
- "bin/"
- "src/comptime.h"
expose_as: "Debian old arm64"
name: "$CI_PROJECT_PATH_SLUG-$CI_COMMIT_REF_SLUG-$CI_COMMIT_SHORT_SHA-old-aarch64"
script:
- - |
# apt_toolchain
echo -e "\e[0Ksection_start:`date +%s`:apt_toolchain[collapsed=true]\r\e[0KInstalling toolchain packages"
- apt-get install gcc-aarch64-linux-gnu || apt-get install gcc
- |
# apt_toolchain
echo -e "\e[0Ksection_end:`date +%s`:apt_toolchain\r\e[0K"
- - |
# apt_development
echo -e "\e[0Ksection_start:`date +%s`:apt_development[collapsed=true]\r\e[0KInstalling development packages"
- apt-get install libsdl2-mixer-dev:arm64 libpng-dev:arm64 libcurl4-openssl-dev:arm64 libopenmpt-dev:arm64 libminiupnpc-dev:arm64
- |
# apt_development
echo -e "\e[0Ksection_end:`date +%s`:apt_development\r\e[0K"
- - |
# make
echo -e "\e[0Ksection_start:`date +%s`:make[collapsed=false]\r\e[0KCompiling SRB2"
- make --directory=src --keep-going CCACHE=1 ERRORMODE=1 LINUX64=1 ERRORMODE=1 NONX86=1 ARM64=1 NOGME=1 || make --directory=src --keep-going CCACHE=1 ERRORMODE=1 LINUX64=1 NONX86=1 ARM64=1 NOGME=1
- |
# make
echo -e "\e[0Ksection_end:`date +%s`:make\r\e[0K"

View file

@ -0,0 +1,45 @@
Debian stable:amd64:
extends: .srb2ci
stage: build
artifacts:
paths:
- "bin/"
- "src/comptime.h"
expose_as: "Debian amd64"
name: "$CI_PROJECT_PATH_SLUG-$CI_COMMIT_REF_SLUG-$CI_COMMIT_SHORT_SHA-x86-64"
variables:
CC: x86_64-linux-gnu-gcc
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
when: on_success
script:
- - |
# apt_toolchain
echo -e "\e[0Ksection_start:`date +%s`:apt_toolchain[collapsed=true]\r\e[0KInstalling toolchain packages"
- apt-get install gcc-x86-64-linux-gnu || apt-get install gcc
- |
# apt_toolchain
echo -e "\e[0Ksection_end:`date +%s`:apt_toolchain\r\e[0K"
- - |
# apt_development
echo -e "\e[0Ksection_start:`date +%s`:apt_development[collapsed=true]\r\e[0KInstalling development packages"
- apt-get install libsdl2-mixer-dev:amd64 libpng-dev:amd64 libcurl4-openssl-dev:amd64 libgme-dev:amd64 libopenmpt-dev:amd64 libminiupnpc-dev:amd64
- |
# apt_development
echo -e "\e[0Ksection_end:`date +%s`:apt_development\r\e[0K"
- - |
# make
echo -e "\e[0Ksection_start:`date +%s`:make[collapsed=false]\r\e[0KCompiling SRB2"
- make --directory=src --keep-going CCACHE=1 ERRORMODE=1 LINUX64=1 || make --directory=src --keep-going CCACHE=1 ERRORMODE=1 LINUX64=1
- |
# make
echo -e "\e[0Ksection_end:`date +%s`:make\r\e[0K"

View file

@ -0,0 +1,45 @@
Debian stable:arm64:
extends: .srb2ci
stage: build
when: manual
artifacts:
paths:
- "bin/"
- "src/comptime.h"
expose_as: "Debian arm64"
name: "$CI_PROJECT_PATH_SLUG-$CI_COMMIT_REF_SLUG-$CI_COMMIT_SHORT_SHA-aarch64"
variables:
CC: aarch64-linux-gnu-gcc
LDFLAGS: -Wl,-fuse-ld=gold
OBJCOPY: aarch64-linux-gnu-objcopy
OBJDUMP: aarch64-linux-gnu-objdump
PKG_CONFIG_PATH: /usr/lib/aarch64-linux-gnu/pkgconfig
script:
- - |
# apt_toolchain
echo -e "\e[0Ksection_start:`date +%s`:apt_toolchain[collapsed=true]\r\e[0KInstalling toolchain packages"
- apt-get install gcc-aarch64-linux-gnu || apt-get install gcc
- |
# apt_toolchain
echo -e "\e[0Ksection_end:`date +%s`:apt_toolchain\r\e[0K"
- - |
# apt_development
echo -e "\e[0Ksection_start:`date +%s`:apt_development[collapsed=true]\r\e[0KInstalling development packages"
- apt-get install libsdl2-mixer-dev:arm64 libpng-dev:arm64 libcurl4-openssl-dev:arm64 libgme-dev:arm64 libopenmpt-dev:arm64 libminiupnpc-dev:arm64
- |
# apt_development
echo -e "\e[0Ksection_end:`date +%s`:apt_development\r\e[0K"
- - |
# make
echo -e "\e[0Ksection_start:`date +%s`:make[collapsed=false]\r\e[0KCompiling SRB2"
- make --directory=src --keep-going CCACHE=1 ERRORMODE=1 LINUX64=1 ERRORMODE=1 NONX86=1 ARM64=1 || make --directory=src --keep-going CCACHE=1 ERRORMODE=1 LINUX64=1 NONX86=1 ARM64=1
- |
# make
echo -e "\e[0Ksection_end:`date +%s`:make\r\e[0K"

View file

@ -0,0 +1,55 @@
Debian stable Clang:
extends: .srb2ci
stage: build
when: on_success
allow_failure: false
artifacts:
paths:
- "build.clang/bin/"
- "build.clang/src/config.h"
expose_as: "clang"
name: "$CI_PROJECT_PATH_SLUG-$CI_COMMIT_REF_SLUG-$CI_COMMIT_SHORT_SHA-clang"
variables:
CC: clang
CXX: clang
WFLAGS: -Wno-cast-align -Wno-implicit-const-int-float-conversion -Werror
CFLAGS: -Wno-cast-align -Wno-implicit-const-int-float-conversion -Werror
LDFLAGS: -Wl,-fuse-ld=gold
script:
- - |
# apt_toolchain
echo -e "\e[0Ksection_start:`date +%s`:apt_toolchain[collapsed=true]\r\e[0KInstalling toolchain packages"
- apt-get install clang
- |
# apt_toolchain
echo -e "\e[0Ksection_end:`date +%s`:apt_toolchain\r\e[0K"
- - |
# apt_development
echo -e "\e[0Ksection_start:`date +%s`:apt_development[collapsed=true]\r\e[0KInstalling development packages"
- apt-get install libsdl2-mixer-dev libpng-dev libcurl4-openssl-dev libgme-dev libopenmpt-dev libminiupnpc-dev
- |
# apt_development
echo -e "\e[0Ksection_end:`date +%s`:apt_development\r\e[0K"
- - |
# 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
echo -e "\e[0Ksection_end:`date +%s`:cmake\r\e[0K"
- - |
# 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
- |
# make
echo -e "\e[0Ksection_end:`date +%s`:make\r\e[0K"

View file

@ -0,0 +1,44 @@
Debian stable:i386:
extends: .srb2ci
stage: build
when: manual
artifacts:
paths:
- "bin/"
- "src/comptime.h"
expose_as: "Debian i386"
name: "$CI_PROJECT_PATH_SLUG-$CI_COMMIT_REF_SLUG-$CI_COMMIT_SHORT_SHA-i686"
variables:
CC: i686-linux-gnu-gcc
OBJCOPY: i686-linux-gnu-objcopy
OBJDUMP: i686-linux-gnu-objdump
PKG_CONFIG_PATH: /usr/lib/i386-linux-gnu/pkgconfig
script:
- - |
# apt_toolchain
echo -e "\e[0Ksection_start:`date +%s`:apt_toolchain[collapsed=true]\r\e[0KInstalling toolchain packages"
- apt-get install gcc-i686-linux-gnu || apt-get install gcc
- |
# apt_toolchain
echo -e "\e[0Ksection_end:`date +%s`:apt_toolchain\r\e[0K"
- - |
# apt_development
echo -e "\e[0Ksection_start:`date +%s`:apt_development[collapsed=true]\r\e[0KInstalling development packages"
- apt-get install libsdl2-mixer-dev:i386 libpng-dev:i386 libcurl4-openssl-dev:i386 libgme-dev:i386 libopenmpt-dev:i386 libminiupnpc-dev:i386
- |
# apt_development
echo -e "\e[0Ksection_end:`date +%s`:apt_development\r\e[0K"
- - |
# make
echo -e "\e[0Ksection_start:`date +%s`:make[collapsed=false]\r\e[0KCompiling SRB2"
- make --directory=src --keep-going CCACHE=1 ERRORMODE=1 LINUX=1 || make --directory=src --keep-going CCACHE=1 ERRORMODE=1 LINUX=1
- |
# make
echo -e "\e[0Ksection_end:`date +%s`:make\r\e[0K"

View file

@ -0,0 +1,22 @@
Debian testing Clang:
extends: Debian stable Clang
when: manual
allow_failure: true
image: debian:testing-slim
artifacts:
paths:
- "build.clang/bin/"
- "build.clang/src/config.h"
expose_as: "testing-clang"
name: "$CI_PROJECT_PATH_SLUG-$CI_COMMIT_REF_SLUG-$CI_COMMIT_SHORT_SHA-testing-clang"
variables:
CC: clang
CXX: clang
WFLAGS: -Wno-cast-align -Wno-implicit-const-int-float-conversion -Werror -Wno-deprecated-non-prototype -Wno-single-bit-bitfield-constant-conversion
CFLAGS: -Wno-cast-align -Wno-implicit-const-int-float-conversion -Werror -Wno-deprecated-non-prototype -Wno-single-bit-bitfield-constant-conversion
LDFLAGS: -Wl,-fuse-ld=gold

View file

@ -0,0 +1,46 @@
Debian testing GCC:
extends: .srb2ci
stage: build
when: manual
image: debian:testing-slim
allow_failure: true
artifacts:
paths:
- "bin/"
- "src/comptime.h"
expose_as: "testing-gcc"
name: "$CI_PROJECT_PATH_SLUG-$CI_COMMIT_REF_SLUG-$CI_COMMIT_SHORT_SHA-testing-gcc"
variables:
CC: gcc
LDFLAGS: -Wl,-fuse-ld=gold
script:
- - |
# apt_toolchain
echo -e "\e[0Ksection_start:`date +%s`:apt_toolchain[collapsed=true]\r\e[0KInstalling toolchain packages"
- apt-get install gcc
- |
# apt_toolchain
echo -e "\e[0Ksection_end:`date +%s`:apt_toolchain\r\e[0K"
- - |
# apt_development
echo -e "\e[0Ksection_start:`date +%s`:apt_development[collapsed=true]\r\e[0KInstalling development packages"
- apt-get install libsdl2-mixer-dev libpng-dev libcurl4-openssl-dev libgme-dev libopenmpt-dev libminiupnpc-dev
- |
# apt_development
echo -e "\e[0Ksection_end:`date +%s`:apt_development\r\e[0K"
- - |
# make
echo -e "\e[0Ksection_start:`date +%s`:make[collapsed=false]\r\e[0KCompiling SRB2"
- make --directory=src --keep-going CCACHE=1 ERRORMODE=1 NONX86=1 || make --directory=src --keep-going CCACHE=1 ERRORMODE=1 NONX86=1
- |
# make
echo -e "\e[0Ksection_end:`date +%s`:make\r\e[0K"

View file

@ -0,0 +1,44 @@
osxcross arm64:
extends: .srb2ci
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"
variables:
OSXCROSS_HOST: arm64-apple-darwin21.4
LD: arm64-apple-darwin21.4-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
- |
# apt_development
echo -e "\e[0Ksection_end:`date +%s`:macports_development\r\e[0K"
- - |
# 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"
- |
# make
echo -e "\e[0Ksection_end:`date +%s`:make\r\e[0K"
- - |
# 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
- |
# make
echo -e "\e[0Ksection_end:`date +%s`:make\r\e[0K"

View file

@ -0,0 +1,40 @@
osxcross x86_64:
extends: .srb2ci
stage: build
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"
variables:
OSXCROSS_HOST: x86_64-apple-darwin21.4
LD: x86_64-apple-darwin21.4-ld
script:
- - |
# 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
- |
# apt_development
echo -e "\e[0Ksection_end:`date +%s`:macports_development\r\e[0K"
- - |
# 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"
- |
# make
echo -e "\e[0Ksection_end:`date +%s`:make\r\e[0K"
- - |
# 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
- |
# make
echo -e "\e[0Ksection_end:`date +%s`:make\r\e[0K"

View file

@ -0,0 +1,35 @@
Windows x64:
extends: .srb2ci
stage: build
when: manual
allow_failure: true
artifacts:
paths:
- "bin/"
- "src/comptime.h"
expose_as: "Win64"
name: "$CI_PROJECT_PATH_SLUG-$CI_COMMIT_REF_SLUG-$CI_COMMIT_SHORT_SHA-Win64"
variables:
PREFIX: x86_64-w64-mingw32
script:
- - |
# apt_toolchain
echo -e "\e[0Ksection_start:`date +%s`:apt_toolchain[collapsed=true]\r\e[0KInstalling toolchain packages"
- apt-get install gcc-mingw-w64-x86-64-win32
- |
# apt_toolchain
echo -e "\e[0Ksection_end:`date +%s`:apt_toolchain\r\e[0K"
- - |
# make
echo -e "\e[0Ksection_start:`date +%s`:make[collapsed=false]\r\e[0KCompiling SRB2"
- make --directory=src --keep-going CCACHE=1 ERRORMODE=1 MINGW64=1 SDL=1 || make --directory=src --keep-going CCACHE=1 ERRORMODE=1 MINGW64=1 SDL=1
- |
# make
echo -e "\e[0Ksection_end:`date +%s`:make\r\e[0K"

View file

@ -0,0 +1,35 @@
Windows x86:
extends: .srb2ci
stage: build
when: on_success
artifacts:
paths:
- "bin/"
- "src/comptime.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
script:
- - |
# apt_toolchain
echo -e "\e[0Ksection_start:`date +%s`:apt_toolchain[collapsed=true]\r\e[0KInstalling toolchain packages"
- apt-get install gcc-mingw-w64-i686-win32
- |
# apt_toolchain
echo -e "\e[0Ksection_end:`date +%s`:apt_toolchain\r\e[0K"
- - |
# make
echo -e "\e[0Ksection_start:`date +%s`:make[collapsed=false]\r\e[0KCompiling SRB2"
- make --directory=src --keep-going CCACHE=1 ERRORMODE=1 MINGW=1 SDL=1 || make --directory=src --keep-going CCACHE=1 ERRORMODE=1 MINGW=1 SDL=1
- |
# make
echo -e "\e[0Ksection_end:`date +%s`:make\r\e[0K"

View file

@ -0,0 +1,145 @@
.srb2ci:
image: git.do.srb2.org:5050/stjr/srb2ci/srb2ci:stable
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
before_script:
- - |
# debconf
echo -e "\e[0Ksection_start:`date +%s`:debconf[collapsed=true]\r\e[0KSetup debconf's environment"
- export DEBIAN_FRONTEND="noninteractive"
- export DEBIAN_PRIORITY="low"
- export DEBCONF_NONINTERACTIVE_SEEN="true"
- |
# debconf
echo -e "\e[0Ksection_end:`date +%s`:debconf\r\e[0K"
- - |
# dpkg_aa
echo -e "\e[0Ksection_start:`date +%s`:dpkg_aa[collapsed=true]\r\e[0KAdding architectures to dpkg"
- dpkg --add-architecture i386
- dpkg --add-architecture amd64
- dpkg --add-architecture arm64
- |
# dpkg_aa
echo -e "\e[0Ksection_end:`date +%s`:dpkg_aa\r\e[0K"
- - |
# apt_conf
echo -e "\e[0Ksection_start:`date +%s`:apt_conf[collapsed=true]\r\e[0KSetting up APT conf"
- export APT_CACHE_DIR=$CI_PROJECT_DIR/build/apt-cache
- mkdir --parents --verbose $APT_CACHE_DIR/partial/
- touch /etc/apt/apt.conf.d/99build
- |
# apt.conf
echo Adding options to apt.conf':'
- |
# APT::Install-Recommends
echo APT::Install-Recommends "false"\; | tee --append /etc/apt/apt.conf.d/99build
- |
# quit
echo quiet "1"\; | tee --append /etc/apt/apt.conf.d/99build
- |
# APT::Get::Assume-Yes
echo APT::Get::Assume-Yes "true"\; | tee --append /etc/apt/apt.conf.d/99build
- |
# Dir::Cache::Archives
echo Dir::Cache::Archives "$APT_CACHE_DIR"\; | tee --append /etc/apt/apt.conf.d/99build
- |
# apt_conf
echo -e "\e[0Ksection_end:`date +%s`:apt_conf\r\e[0K"
- - |
# apt_update
echo -e "\e[0Ksection_start:`date +%s`:apt_update[collapsed=true]\r\e[0KUpdating APT listing"
- apt-get update
- |
# apt_update
echo -e "\e[0Ksection_end:`date +%s`:apt_update\r\e[0K"
- - |
# apt_pre
echo -e "\e[0Ksection_start:`date +%s`:apt_pre[collapsed=true]\r\e[0KInstalling pre packages"
- apt-get install apt-utils
- |
# apt_pre
echo -e "\e[0Ksection_end:`date +%s`:apt_pre\r\e[0K"
- - |
# apt_upgrade
echo -e "\e[0Ksection_start:`date +%s`:apt_upgrade[collapsed=true]\r\e[0KUpdating existing packages"
- apt-get upgrade
- |
# apt_update
echo -e "\e[0Ksection_end:`date +%s`:apt_upgrade\r\e[0K"
- - |
# apt_common
echo -e "\e[0Ksection_start:`date +%s`:apt_common[collapsed=true]\r\e[0KInstalling common packages"
- apt-get install make git ccache nasm cmake ca-certificates
- |
# apt_common
echo -e "\e[0Ksection_end:`date +%s`:apt_common\r\e[0K"
- - |
# 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
- |
# cache_dir
echo cache_dir = $CI_PROJECT_DIR/build/ccache | tee --append ~/.ccache/ccache.conf
- |
# compiler_check
echo compiler_check = content | tee --append ~/.ccache/ccache.conf
- |
# stats_log
echo stats_log = $CI_PROJECT_DIR/build/ccache_statslog | tee --append ~/.ccache/ccache.conf
- |
# max_size
echo max_size = 300M | tee --append ~/.ccache/ccache.conf
- |
# ccache_config
echo -e "\e[0Ksection_end:`date +%s`:ccache_config\r\e[0K"
- - |
# cache_reset
echo -e "\e[0Ksection_start:`date +%s`:ccache_reset[collapsed=true]\r\e[0KResetting ccache statistics"
- ccache --zero-stats
- ccache --show-stats
- |
# ccache_reset
echo -e "\e[0Ksection_end:`date +%s`:ccache_reset\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"

View file

@ -8,7 +8,6 @@ endif()
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/Modules/") set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/Modules/")
include(CMakeDependentOption) include(CMakeDependentOption)
include(cmake/CPM.cmake)
file(STRINGS src/version.h SRB2_VERSION) file(STRINGS src/version.h SRB2_VERSION)
string(REGEX MATCH "[0-9]+\\.[0-9.]+" SRB2_VERSION ${SRB2_VERSION}) string(REGEX MATCH "[0-9]+\\.[0-9.]+" SRB2_VERSION ${SRB2_VERSION})
@ -46,28 +45,23 @@ SET(CPACK_OUTPUT_FILE_PREFIX package)
include(CPack) include(CPack)
# Options # Options
if("${CMAKE_SYSTEM_NAME}" MATCHES Windows)
if("${CMAKE_SYSTEM_NAME}" MATCHES Linux) if(DEFINED VCPKG_TARGET_TRIPLET)
set(SRB2_CONFIG_SYSTEM_LIBRARIES_DEFAULT ON) set(SRB2_CONFIG_SYSTEM_LIBRARIES_DEFAULT ON)
else() else()
set(SRB2_CONFIG_SYSTEM_LIBRARIES_DEFAULT OFF) set(SRB2_CONFIG_SYSTEM_LIBRARIES_DEFAULT OFF)
endif()
else()
set(SRB2_CONFIG_SYSTEM_LIBRARIES_DEFAULT ON)
endif() endif()
# Clang tidy options will be ignored if CMAKE_<LANG>_CLANG_TIDY are set. # Clang tidy options will be ignored if CMAKE_<LANG>_CLANG_TIDY are set.
option(SRB2_CONFIG_ENABLE_CLANG_TIDY_C "Enable default clang-tidy check configuration for C" OFF) option(SRB2_CONFIG_ENABLE_CLANG_TIDY_C "Enable default clang-tidy check configuration for C" OFF)
option(SRB2_CONFIG_ENABLE_CLANG_TIDY_CXX "Enable default clang-tidy check configuration for C++" OFF) option(SRB2_CONFIG_ENABLE_CLANG_TIDY_CXX "Enable default clang-tidy check configuration for C++" OFF)
option( option(
SRB2_CONFIG_SYSTEM_LIBRARIES SRB2_CONFIG_STATIC_STDLIB
"Link dependencies using CMake's find_package and do not use internal builds" "Link static version of standard library. All dependencies must also be static"
${SRB2_CONFIG_SYSTEM_LIBRARIES_DEFAULT} ON
)
option(SRB2_CONFIG_ENABLE_TESTS "Build the test suite" ON)
# This option isn't recommended for distribution builds and probably won't work (yet).
cmake_dependent_option(
SRB2_CONFIG_SHARED_INTERNAL_LIBRARIES
"Use dynamic libraries when compiling internal dependencies"
OFF "NOT SRB2_CONFIG_SYSTEM_LIBRARIES"
OFF
) )
option(SRB2_CONFIG_HWRENDER "Enable hardware render (OpenGL) support" ON) option(SRB2_CONFIG_HWRENDER "Enable hardware render (OpenGL) support" ON)
option(SRB2_CONFIG_USE_GME "Enable GME playback support" OFF) option(SRB2_CONFIG_USE_GME "Enable GME playback support" OFF)
@ -82,64 +76,28 @@ option(SRB2_CONFIG_ZDEBUG "Compile with ZDEBUG defined." OFF)
option(SRB2_CONFIG_PROFILEMODE "Compile for profiling (GCC only)." OFF) option(SRB2_CONFIG_PROFILEMODE "Compile for profiling (GCC only)." OFF)
set(SRB2_CONFIG_ASSET_DIRECTORY "" CACHE PATH "Path to directory that contains all asset files for the installer. If set, assets will be part of installation and cpack.") set(SRB2_CONFIG_ASSET_DIRECTORY "" CACHE PATH "Path to directory that contains all asset files for the installer. If set, assets will be part of installation and cpack.")
if(SRB2_CONFIG_ENABLE_TESTS)
# https://github.com/catchorg/Catch2
CPMAddPackage(
NAME Catch2
VERSION 3.4.0
GITHUB_REPOSITORY catchorg/Catch2
OPTIONS
"CATCH_INSTALL_DOCS OFF"
)
list(APPEND CMAKE_MODULE_PATH "${Catch2_SOURCE_DIR}/extras")
include(CTest)
include(Catch)
add_executable(srb2tests)
# To add tests, use target_sources to add individual test files to the target in subdirs.
target_link_libraries(srb2tests PRIVATE Catch2::Catch2 Catch2::Catch2WithMain)
target_compile_features(srb2tests PRIVATE c_std_11 cxx_std_17)
catch_discover_tests(srb2tests)
endif()
# Enable CCache
# (Set USE_CCACHE=ON to use, CCACHE_OPTIONS for options)
if("${CMAKE_HOST_SYSTEM_NAME}" STREQUAL Windows)
option(USE_CCACHE "Enable ccache support" OFF)
if(USE_CCACHE)
find_program(CCACHE_TOOL_PATH ccache)
if(CCACHE_TOOL_PATH)
set(CMAKE_C_COMPILER_LAUNCHER ${CCACHE_TOOL_PATH} CACHE STRING "" FORCE)
set(CMAKE_CXX_COMPILER_LAUNCHER ${CCACHE_TOOL_PATH} CACHE STRING "" FORCE)
else()
message(WARNING "USE_CCACHE was set but ccache is not found (set CCACHE_TOOL_PATH)")
endif()
endif()
else()
CPMAddPackage(
NAME Ccache.cmake
GITHUB_REPOSITORY TheLartians/Ccache.cmake
VERSION 1.2
)
endif()
# Dependencies # Dependencies
add_subdirectory(thirdparty) add_subdirectory(thirdparty)
if("${SRB2_CONFIG_SYSTEM_LIBRARIES}") if(SRB2_CONFIG_SHARED_INTERNAL_LIBRARIES)
find_package(ZLIB REQUIRED) set(SRB2_INTERNAL_LIBRARY_TYPE SHARED)
find_package(PNG REQUIRED) set(NOT_SRB2_CONFIG_SHARED_INTERNAL_LIBRARIES OFF)
find_package(SDL2 REQUIRED) else()
find_package(SDL2_mixer REQUIRED) set(SRB2_INTERNAL_LIBRARY_TYPE STATIC)
find_package(CURL REQUIRED) set(NOT_SRB2_CONFIG_SHARED_INTERNAL_LIBRARIES ON)
find_package(OPENMPT REQUIRED)
# libgme defaults to "Nuked" YM2612 emulator, which is
# very SLOW. The system library probably uses the
# default so just always build it.
#find_package(GME REQUIRED)
endif() endif()
find_package(ZLIB REQUIRED)
find_package(PNG REQUIRED)
find_package(CURL REQUIRED)
find_package(libopenmpt QUIET)
if("${SRB2_CONFIG_USE_GME}")
find_package(libgme QUIET)
endif()
find_package(miniupnpc QUIET)
if(${PROJECT_SOURCE_DIR} MATCHES ${PROJECT_BINARY_DIR}) if(${PROJECT_SOURCE_DIR} MATCHES ${PROJECT_BINARY_DIR})
message(FATAL_ERROR "In-source builds will bring you a world of pain. Please make a separate directory to invoke CMake from.") message(FATAL_ERROR "In-source builds will bring you a world of pain. Please make a separate directory to invoke CMake from.")
endif() endif()

View file

@ -2,26 +2,263 @@
"version": 3, "version": 3,
"configurePresets": [ "configurePresets": [
{ {
"name": "default", "name": "__debug",
"description": "Build using default generator", "hidden": true,
"binaryDir": "build",
"cacheVariables": { "cacheVariables": {
"SRB2_CONFIG_DEV_BUILD": "ON",
"CMAKE_BUILD_TYPE": "Debug"
}
},
{
"name": "__develop",
"hidden": true,
"cacheVariables": {
"CMAKE_C_FLAGS_RELWITHDEBINFO": "-DNDEBUG",
"CMAKE_CXX_FLAGS_RELWITHDEBINFO": "-DNDEBUG",
"SRB2_CONFIG_DEV_BUILD": "ON",
"CMAKE_BUILD_TYPE": "RelWithDebInfo" "CMAKE_BUILD_TYPE": "RelWithDebInfo"
} }
}, },
{ {
"name": "debug", "name": "__release",
"description": "Build for development (no optimizations)", "hidden": true,
"inherits": "default",
"cacheVariables": { "cacheVariables": {
"CMAKE_BUILD_TYPE": "Debug" "CMAKE_C_FLAGS_RELWITHDEBINFO": "-DNDEBUG",
"CMAKE_CXX_FLAGS_RELWITHDEBINFO": "-DNDEBUG",
"SRB2_CONFIG_DEV_BUILD": "OFF",
"CMAKE_BUILD_TYPE": "RelWithDebInfo"
} }
},
{
"name": "__testers",
"hidden": true,
"cacheVariables": {
"CMAKE_C_FLAGS_RELWITHDEBINFO": "-DNDEBUG",
"CMAKE_CXX_FLAGS_RELWITHDEBINFO": "-DNDEBUG",
"SRB2_CONFIG_DEV_BUILD": "ON",
"CMAKE_BUILD_TYPE": "RelWithDebInfo",
"SRB2_CONFIG_TESTERS": "ON"
}
},
{
"name": "__ninja",
"hidden": true,
"generator": "Ninja",
"cacheVariables": {
"CMAKE_COLOR_DIAGNOSTICS": "ON"
}
},
{
"name": "__vcpkg-toolchain",
"hidden": true,
"cacheVariables": {
"CMAKE_TOOLCHAIN_FILE": "$env{VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake"
}
},
{
"name": "__compiler-mingw-w64-i686",
"hidden": true,
"cacheVariables": {
"CMAKE_C_COMPILER": "i686-w64-mingw32-gcc",
"CMAKE_CXX_COMPILER": "i686-w64-mingw32-g++"
}
},
{
"name": "__mingw-dynamic",
"hidden": true,
"cacheVariables": {
"VCPKG_TARGET_TRIPLET": "x86-mingw-dynamic"
}
},
{
"name": "__mingw-static",
"hidden": true,
"cacheVariables": {
"VCPKG_HOST_TRIPLET": "x86-mingw-static",
"VCPKG_TARGET_TRIPLET": "x86-mingw-static"
}
},
{
"name": "__osx_x64",
"hidden": true,
"cacheVariables": {
"VCPKG_TARGET_TRIPLET": "x64-osx"
}
},
{
"name": "__osx_arm64",
"hidden": true,
"cacheVariables": {
"VCPKG_TARGET_TRIPLET": "arm64-osx"
}
},
{
"name": "ninja-debug",
"hidden": false,
"binaryDir": "build/${presetName}",
"inherits": ["__debug", "__ninja"]
},
{
"name": "ninja-develop",
"hidden": false,
"binaryDir": "build/${presetName}",
"inherits": ["__develop", "__ninja"]
},
{
"name": "ninja-release",
"hidden": false,
"binaryDir": "build/${presetName}",
"inherits": ["__release", "__ninja"]
},
{
"name": "ninja-testers",
"hidden": false,
"binaryDir": "build/${presetName}",
"inherits": ["__testers", "__ninja"]
},
{
"name": "ninja-vcpkg-debug",
"hidden": false,
"binaryDir": "build/${presetName}",
"inherits": ["__debug", "__ninja", "__vcpkg-toolchain"]
},
{
"name": "ninja-vcpkg-develop",
"hidden": false,
"binaryDir": "build/${presetName}",
"inherits": ["__develop", "__ninja", "__vcpkg-toolchain"]
},
{
"name": "ninja-vcpkg-release",
"hidden": false,
"binaryDir": "build/${presetName}",
"inherits": ["__release", "__ninja", "__vcpkg-toolchain"]
},
{
"name": "ninja-vcpkg-testers",
"hidden": false,
"binaryDir": "build/${presetName}",
"inherits": ["__testers", "__ninja", "__vcpkg-toolchain"]
},
{
"name": "ninja-x86_mingw_static_vcpkg-debug",
"hidden": false,
"binaryDir": "build/${presetName}",
"inherits": ["__debug", "__compiler-mingw-w64-i686", "__ninja", "__vcpkg-toolchain", "__mingw-static"]
},
{
"name": "ninja-x86_mingw_static_vcpkg-develop",
"hidden": false,
"binaryDir": "build/${presetName}",
"inherits": ["__develop", "__compiler-mingw-w64-i686", "__ninja", "__vcpkg-toolchain", "__mingw-static"]
},
{
"name": "ninja-x86_mingw_static_vcpkg-release",
"hidden": false,
"binaryDir": "build/${presetName}",
"inherits": ["__release", "__compiler-mingw-w64-i686", "__ninja", "__vcpkg-toolchain", "__mingw-static"]
},
{
"name": "ninja-x86_mingw_static_vcpkg-testers",
"hidden": false,
"binaryDir": "build/${presetName}",
"inherits": ["__testers", "__compiler-mingw-w64-i686", "__ninja", "__vcpkg-toolchain", "__mingw-static"]
},
{
"name": "ninja-x64_osx_vcpkg-debug",
"hidden": false,
"binaryDir": "build/${presetName}",
"inherits": ["__debug", "__ninja", "__vcpkg-toolchain", "__osx_x64"]
},
{
"name": "ninja-x64_osx_vcpkg-develop",
"hidden": false,
"binaryDir": "build/${presetName}",
"inherits": ["__develop", "__ninja", "__vcpkg-toolchain", "__osx_x64"]
},
{
"name": "ninja-x64_osx_vcpkg-release",
"hidden": false,
"binaryDir": "build/${presetName}",
"inherits": ["__release", "__ninja", "__vcpkg-toolchain", "__osx_x64"]
},
{
"name": "ninja-arm64_osx_vcpkg-debug",
"hidden": false,
"binaryDir": "build/${presetName}",
"inherits": ["__debug", "__ninja", "__vcpkg-toolchain", "__osx_arm64"]
},
{
"name": "ninja-arm64_osx_vcpkg-develop",
"hidden": false,
"binaryDir": "build/${presetName}",
"inherits": ["__develop", "__ninja", "__vcpkg-toolchain", "__osx_arm64"]
},
{
"name": "ninja-arm64_osx_vcpkg-release",
"hidden": false,
"binaryDir": "build/${presetName}",
"inherits": ["__release", "__ninja", "__vcpkg-toolchain", "__osx_arm64"]
} }
], ],
"buildPresets": [ "buildPresets": [
{ {
"name": "default", "name": "ninja-debug",
"configurePreset": "default" "configurePreset": "ninja-debug"
},
{
"name": "ninja-develop",
"configurePreset": "ninja-develop"
},
{
"name": "ninja-release",
"configurePreset": "ninja-release"
},
{
"name": "ninja-x86_mingw_static_vcpkg-debug",
"configurePreset": "ninja-x86_mingw_static_vcpkg-debug"
},
{
"name": "ninja-x86_mingw_static_vcpkg-develop",
"configurePreset": "ninja-x86_mingw_static_vcpkg-develop"
},
{
"name": "ninja-x86_mingw_static_vcpkg-release",
"configurePreset": "ninja-x86_mingw_static_vcpkg-release"
},
{
"name": "ninja-x86_mingw_static_vcpkg-testers",
"configurePreset": "ninja-x86_mingw_static_vcpkg-testers"
},
{
"name": "ninja-x64_osx_vcpkg-debug",
"configurePreset": "ninja-x64_osx_vcpkg-debug"
},
{
"name": "ninja-x64_osx_vcpkg-develop",
"configurePreset": "ninja-x64_osx_vcpkg-develop"
},
{
"name": "ninja-x64_osx_vcpkg-release",
"configurePreset": "ninja-x64_osx_vcpkg-release"
},
{
"name": "ninja-arm64_osx_vcpkg-debug",
"configurePreset": "ninja-arm64_osx_vcpkg-debug"
},
{
"name": "ninja-arm64_osx_vcpkg-develop",
"configurePreset": "ninja-arm64_osx_vcpkg-develop"
},
{
"name": "ninja-arm64_osx_vcpkg-release",
"configurePreset": "ninja-arm64_osx_vcpkg-release"
} }
] ]
} }

View file

@ -1,21 +0,0 @@
set(CPM_DOWNLOAD_VERSION 0.38.7)
if(CPM_SOURCE_CACHE)
set(CPM_DOWNLOAD_LOCATION "${CPM_SOURCE_CACHE}/cpm/CPM_${CPM_DOWNLOAD_VERSION}.cmake")
elseif(DEFINED ENV{CPM_SOURCE_CACHE})
set(CPM_DOWNLOAD_LOCATION "$ENV{CPM_SOURCE_CACHE}/cpm/CPM_${CPM_DOWNLOAD_VERSION}.cmake")
else()
set(CPM_DOWNLOAD_LOCATION "${CMAKE_BINARY_DIR}/cmake/CPM_${CPM_DOWNLOAD_VERSION}.cmake")
endif()
# Expand relative path. This is important if the provided path contains a tilde (~)
get_filename_component(CPM_DOWNLOAD_LOCATION ${CPM_DOWNLOAD_LOCATION} ABSOLUTE)
if(NOT (EXISTS ${CPM_DOWNLOAD_LOCATION}))
message(STATUS "Downloading CPM.cmake to ${CPM_DOWNLOAD_LOCATION}")
file(DOWNLOAD
https://github.com/cpm-cmake/CPM.cmake/releases/download/v${CPM_DOWNLOAD_VERSION}/CPM.cmake
${CPM_DOWNLOAD_LOCATION}
)
endif()
include(${CPM_DOWNLOAD_LOCATION})

View file

@ -1,33 +0,0 @@
include(LibFindMacros)
libfind_pkg_check_modules(GME_PKGCONF GME)
find_path(GME_INCLUDE_DIR
NAMES gme.h
PATHS
${GME_PKGCONF_INCLUDE_DIRS}
"/usr/include/gme"
"/usr/local/include/gme"
)
find_library(GME_LIBRARY
NAMES gme
PATHS
${GME_PKGCONF_LIBRARY_DIRS}
"/usr/lib"
"/usr/local/lib"
)
set(GME_PROCESS_INCLUDES GME_INCLUDE_DIR)
set(GME_PROCESS_LIBS GME_LIBRARY)
libfind_process(GME)
if(GME_FOUND AND NOT TARGET gme)
add_library(gme UNKNOWN IMPORTED)
set_target_properties(
gme
PROPERTIES
IMPORTED_LOCATION "${GME_LIBRARY}"
INTERFACE_INCLUDE_DIRECTORIES "${GME_INCLUDE_DIR}"
)
endif()

View file

@ -1,33 +0,0 @@
include(LibFindMacros)
libfind_pkg_check_modules(OPENMPT_PKGCONF OPENMPT)
find_path(OPENMPT_INCLUDE_DIR
NAMES libopenmpt.h
PATHS
${OPENMPT_PKGCONF_INCLUDE_DIRS}
"/usr/include/libopenmpt"
"/usr/local/include/libopenmpt"
)
find_library(OPENMPT_LIBRARY
NAMES openmpt
PATHS
${OPENMPT_PKGCONF_LIBRARY_DIRS}
"/usr/lib"
"/usr/local/lib"
)
set(OPENMPT_PROCESS_INCLUDES OPENMPT_INCLUDE_DIR)
set(OPENMPT_PROCESS_LIBS OPENMPT_LIBRARY)
libfind_process(OPENMPT)
if(OPENMPT_FOUND AND NOT TARGET openmpt)
add_library(openmpt UNKNOWN IMPORTED)
set_target_properties(
openmpt
PROPERTIES
IMPORTED_LOCATION "${OPENMPT_LIBRARY}"
INTERFACE_INCLUDE_DIRECTORIES "${OPENMPT_INCLUDE_DIR}"
)
endif()

View file

@ -0,0 +1,38 @@
include(LibFindMacros)
libfind_pkg_check_modules(libgme_PKGCONF gme libgme)
find_path(libgme_INCLUDE_DIR
NAMES gme.h
PATHS
${libgme_PKGCONF_INCLUDE_DIRS}
"/usr/include"
"/usr/local/include"
PATH_SUFFIXES
gme
)
find_library(libgme_LIBRARY
NAMES gme
PATHS
${libgme_PKGCONF_LIBRARY_DIRS}
"/usr/lib"
"/usr/local/lib"
)
include(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(libgme
REQUIRED_VARS libgme_LIBRARY libgme_INCLUDE_DIR)
if(libgme_FOUND AND NOT TARGET gme)
add_library(gme UNKNOWN IMPORTED)
set_target_properties(
gme
PROPERTIES
IMPORTED_LOCATION "${libgme_LIBRARY}"
INTERFACE_INCLUDE_DIRECTORIES "${libgme_INCLUDE_DIR}"
)
add_library(gme::gme ALIAS gme)
endif()
mark_as_advanced(libgme_LIBRARY libgme_INCLUDE_DIR)

View file

@ -0,0 +1,37 @@
include(LibFindMacros)
libfind_pkg_check_modules(libopenmpt_PKGCONF openmpt)
find_path(libopenmpt_INCLUDE_DIR
NAMES libopenmpt.h
PATHS
${libopenmpt_PKGCONF_INCLUDE_DIRS}
"${VCPKG_INSTALLED_DIR}/${VCPKG_TARGET_TRIPLET}/include/libopenmpt"
"/usr/include/libopenmpt"
"/usr/local/include/libopenmpt"
)
find_library(libopenmpt_LIBRARY
NAMES openmpt
PATHS
${libopenmpt_PKGCONF_LIBRARY_DIRS}
"/usr/lib"
"/usr/local/lib"
)
include(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(libopenmpt
REQUIRED_VARS libopenmpt_LIBRARY libopenmpt_INCLUDE_DIR)
if(libopenmpt_FOUND AND NOT TARGET openmpt)
add_library(openmpt UNKNOWN IMPORTED)
set_target_properties(
openmpt
PROPERTIES
IMPORTED_LOCATION "${libopenmpt_LIBRARY}"
INTERFACE_INCLUDE_DIRECTORIES "${libopenmpt_INCLUDE_DIR}"
)
add_library(libopenmpt::libopenmpt ALIAS openmpt)
endif()
mark_as_advanced(libopenmpt_LIBRARY libopenmpt_INCLUDE_DIR)

View file

@ -0,0 +1,39 @@
include(LibFindMacros)
libfind_pkg_check_modules(libminiupnpc_PKGCONF miniupnpc libminiupnpc)
find_path(libminiupnpc_INCLUDE_DIR
NAMES miniupnpc.h
PATHS
${libminiupnpc_PKGCONF_INCLUDE_DIRS}
"${VCPKG_INSTALLED_DIR}/${VCPKG_TARGET_TRIPLET}/include"
"/usr/include"
"/usr/local/include"
PATH_SUFFIXES
miniupnpc
)
find_library(libminiupnpc_LIBRARY
NAMES miniupnpc
PATHS
${libminiupnpc_PKGCONF_LIBRARY_DIRS}
"/usr/lib"
"/usr/local/lib"
)
include(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(miniupnpc
REQUIRED_VARS libminiupnpc_LIBRARY libminiupnpc_INCLUDE_DIR)
if(miniupnpc_FOUND AND NOT TARGET miniupnpc)
add_library(miniupnpc UNKNOWN IMPORTED)
set_target_properties(
miniupnpc
PROPERTIES
IMPORTED_LOCATION "${libminiupnpc_LIBRARY}"
INTERFACE_INCLUDE_DIRECTORIES "${libminiupnpc_INCLUDE_DIR}"
)
add_library(miniupnpc::miniupnpc ALIAS miniupnpc)
endif()
mark_as_advanced(libminiupnpc_LIBRARY libminiupnpc_INCLUDE_DIR)

30
cmake/PatchFile.cmake Normal file
View file

@ -0,0 +1,30 @@
# use GNU Patch from any platform
if(WIN32)
# prioritize Git Patch on Windows as other Patches may be very old and incompatible.
find_package(Git)
if(Git_FOUND)
get_filename_component(GIT_DIR ${GIT_EXECUTABLE} DIRECTORY)
get_filename_component(GIT_DIR ${GIT_DIR} DIRECTORY)
endif()
endif()
find_program(PATCH
NAMES patch
HINTS ${GIT_DIR}
PATH_SUFFIXES usr/bin
)
if(NOT PATCH)
message(FATAL_ERROR "Did not find GNU Patch")
endif()
execute_process(COMMAND ${PATCH} ${in_file} --input=${patch_file} --output=${out_file} --ignore-whitespace
TIMEOUT 15
COMMAND_ECHO STDOUT
RESULT_VARIABLE ret
)
if(NOT ret EQUAL 0)
message(FATAL_ERROR "Failed to apply patch ${patch_file} to ${in_file} with ${PATCH}")
endif()

View file

@ -0,0 +1,16 @@
set(CMAKE_SYSTEM_NAME Windows)
set(TOOLCHAIN_PREFIX i686-w64-mingw32)
# cross compilers to use for C, C++ and Fortran
set(CMAKE_C_COMPILER ${TOOLCHAIN_PREFIX}-gcc)
set(CMAKE_CXX_COMPILER ${TOOLCHAIN_PREFIX}-g++)
set(CMAKE_Fortran_COMPILER ${TOOLCHAIN_PREFIX}-gfortran)
set(CMAKE_RC_COMPILER ${TOOLCHAIN_PREFIX}-windres)
# target environment on the build host system
set(CMAKE_FIND_ROOT_PATH /usr/${TOOLCHAIN_PREFIX})
# modify default behavior of FIND_XXX() commands
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)

View file

@ -0,0 +1,16 @@
set(CMAKE_SYSTEM_NAME Windows)
set(TOOLCHAIN_PREFIX x86_64-w64-mingw32)
# cross compilers to use for C, C++ and Fortran
set(CMAKE_C_COMPILER ${TOOLCHAIN_PREFIX}-gcc)
set(CMAKE_CXX_COMPILER ${TOOLCHAIN_PREFIX}-g++)
set(CMAKE_Fortran_COMPILER ${TOOLCHAIN_PREFIX}-gfortran)
set(CMAKE_RC_COMPILER ${TOOLCHAIN_PREFIX}-windres)
# target environment on the build host system
set(CMAKE_FIND_ROOT_PATH /usr/${TOOLCHAIN_PREFIX})
# modify default behavior of FIND_XXX() commands
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)

View file

@ -126,7 +126,7 @@ Sonic Robo Blast 2 defines the following standardized fields:
texturebottom = <string>; // Lower texture. Default = "-". texturebottom = <string>; // Lower texture. Default = "-".
texturemiddle = <string>; // Middle texture. Default = "-". texturemiddle = <string>; // Middle texture. Default = "-".
repeatcnt = <string>; // Number of middle texture repetitions. Default = 0 repeatcnt = <integer>; // Number of middle texture repetitions. Default = 0.
sector = <integer>; // Sector index. No valid default. sector = <integer>; // Sector index. No valid default.
@ -228,6 +228,8 @@ Sonic Robo Blast 2 defines the following standardized fields:
ropehang = <bool>; // Sector is a rope hang. Must be applied to a 3D floor. ropehang = <bool>; // Sector is a rope hang. Must be applied to a 3D floor.
jumpflip = <bool>; // Sector flips the gravity of players who jump from it. jumpflip = <bool>; // Sector flips the gravity of players who jump from it.
gravityoverride = <bool>; // Reverse gravity effect is only applied when an object is in the sector. gravityoverride = <bool>; // Reverse gravity effect is only applied when an object is in the sector.
nophysics_floor = <bool>; // Disables floor slope physics if created through a plane equation.
nophysics_ceiling = <bool>; // Disables ceiling slope physics if created through a plane equation.
friction = <float>; // Sector's friction factor. friction = <float>; // Sector's friction factor.
gravity = <float>; // Sector's gravity. Default is 1.0. gravity = <float>; // Sector's gravity. Default is 1.0.

View file

@ -39,6 +39,7 @@ common
defaulttexturescale = 1.0f; defaulttexturescale = 1.0f;
defaultflatscale = 1.0f; defaultflatscale = 1.0f;
scaledtextureoffsets = true; scaledtextureoffsets = true;
scaledflatoffsets = true;
// Colormap/fade related options // Colormap/fade related options
maxcolormapalpha = 25; maxcolormapalpha = 25;

File diff suppressed because it is too large Load diff

View file

@ -78,6 +78,8 @@ sectorflags
ropehang = "Rope Hang"; ropehang = "Rope Hang";
jumpflip = "Flip Gravity on Jump"; jumpflip = "Flip Gravity on Jump";
gravityoverride = "Make Reverse Gravity Temporary"; gravityoverride = "Make Reverse Gravity Temporary";
nophysics_floor = "Disable Floor Slope Physics";
nophysics_ceiling = "Disable Ceiling Slope Physics";
flipspecial_nofloor = "No Trigger on Floor Touch"; flipspecial_nofloor = "No Trigger on Floor Touch";
flipspecial_ceiling = "Trigger on Ceiling Touch"; flipspecial_ceiling = "Trigger on Ceiling Touch";
triggerspecial_touch = "Trigger on Edge Touch"; triggerspecial_touch = "Trigger on Edge Touch";
@ -114,6 +116,8 @@ sectorflagscategories
ropehang = "special"; ropehang = "special";
jumpflip = "special"; jumpflip = "special";
gravityoverride = "special"; gravityoverride = "special";
nophysics_floor = "special";
nophysics_ceiling = "special";
flipspecial_nofloor = "trigger"; flipspecial_nofloor = "trigger";
flipspecial_ceiling = "trigger"; flipspecial_ceiling = "trigger";
triggerspecial_touch = "trigger"; triggerspecial_touch = "trigger";
@ -586,6 +590,12 @@ universalfields
type = 3; type = 3;
default = false; default = false;
} }
triggertag
{
type = 0;
default = 0;
}
} }
} }

View file

@ -3938,6 +3938,7 @@ udmf
width = 30; width = 30;
height = 32; height = 32;
color = 17; color = 17;
hangs = 1;
arg0 arg0
{ {
title = "Initial delay"; title = "Initial delay";

View file

@ -134,10 +134,13 @@ add_dependencies(SRB2SDL2 _SRB2_reconf)
if("${CMAKE_COMPILER_IS_GNUCC}" AND "${CMAKE_SYSTEM_NAME}" MATCHES "Windows") if("${CMAKE_COMPILER_IS_GNUCC}" AND "${CMAKE_SYSTEM_NAME}" MATCHES "Windows")
target_link_options(SRB2SDL2 PRIVATE "-Wl,--disable-dynamicbase") target_link_options(SRB2SDL2 PRIVATE "-Wl,--disable-dynamicbase")
if(NOT "${SRB2_CONFIG_SYSTEM_LIBRARIES}" AND NOT "${SRB2_CONFIG_SHARED_INTERNAL_LIBRARIES}") if("${SRB2_CONFIG_STATIC_STDLIB}")
# On MinGW with internal libraries, link the standard library statically # On MinGW with internal libraries, link the standard library statically
target_link_options(SRB2SDL2 PRIVATE "-static") target_link_options(SRB2SDL2 PRIVATE "-static")
endif() endif()
if(CMAKE_SIZEOF_VOID_P EQUAL 4)
target_link_options(SRB2SDL2 PRIVATE "-Wl,--large-address-aware")
endif()
endif() endif()
target_compile_features(SRB2SDL2 PRIVATE c_std_11 cxx_std_17) target_compile_features(SRB2SDL2 PRIVATE c_std_11 cxx_std_17)
@ -182,12 +185,7 @@ if("${SRB2_CONFIG_USE_GME}")
endif() endif()
endif() endif()
target_link_libraries(SRB2SDL2 PRIVATE openmpt) target_compile_definitions(SRB2SDL2 PRIVATE -D_LARGEFILE64_SOURCE)
target_compile_definitions(SRB2SDL2 PRIVATE -DHAVE_OPENMPT)
target_link_libraries(SRB2SDL2 PRIVATE ZLIB::ZLIB PNG::PNG CURL::libcurl)
target_compile_definitions(SRB2SDL2 PRIVATE -DHAVE_ZLIB -DHAVE_PNG -DHAVE_CURL -D_LARGEFILE64_SOURCE)
target_sources(SRB2SDL2 PRIVATE apng.c)
set(SRB2_HAVE_THREADS ON) set(SRB2_HAVE_THREADS ON)
target_compile_definitions(SRB2SDL2 PRIVATE -DHAVE_THREADS) target_compile_definitions(SRB2SDL2 PRIVATE -DHAVE_THREADS)
@ -245,6 +243,7 @@ target_compile_options(SRB2SDL2 PRIVATE
# This is a direct translation from versions.mk # This is a direct translation from versions.mk
$<$<AND:$<COMPILE_LANGUAGE:C>,$<C_COMPILER_ID:GNU>>: $<$<AND:$<COMPILE_LANGUAGE:C>,$<C_COMPILER_ID:GNU>>:
-Wall -Wall
-Wextra
-Wno-trigraphs -Wno-trigraphs
-W # Was controlled by RELAXWARNINGS -W # Was controlled by RELAXWARNINGS
-Wfloat-equal -Wfloat-equal
@ -312,11 +311,7 @@ target_compile_options(SRB2SDL2 PRIVATE
$<$<VERSION_GREATER_EQUAL:$<C_COMPILER_VERSION>,8.1.0>: $<$<VERSION_GREATER_EQUAL:$<C_COMPILER_VERSION>,8.1.0>:
-Wno-error=format-overflow -Wno-error=format-overflow
-Wno-error=stringop-truncation
-Wno-error=stringop-overflow
-Wno-format-overflow -Wno-format-overflow
-Wno-stringop-truncation
-Wno-stringop-overflow
-Wno-error=multistatement-macros -Wno-error=multistatement-macros
> >
@ -329,7 +324,9 @@ target_compile_options(SRB2SDL2 PRIVATE
$<$<AND:$<COMPILE_LANGUAGE:C>,$<OR:$<C_COMPILER_ID:AppleClang>,$<C_COMPILER_ID:Clang>>>: $<$<AND:$<COMPILE_LANGUAGE:C>,$<OR:$<C_COMPILER_ID:AppleClang>,$<C_COMPILER_ID:Clang>>>:
-Wall -Wall
-Wno-absolute-value -Wno-absolute-value
-Wextra
-Wno-trigraphs -Wno-trigraphs
-Wconditional-uninitialized
-Wno-error=non-literal-null-conversion -Wno-error=non-literal-null-conversion
-Wno-error=constant-conversion -Wno-error=constant-conversion
-Wno-error=unused-but-set-variable -Wno-error=unused-but-set-variable
@ -346,6 +343,9 @@ target_compile_options(SRB2SDL2 PRIVATE
# C++, GNU, Clang and Apple Clang # C++, GNU, Clang and Apple Clang
$<$<AND:$<COMPILE_LANGUAGE:CXX>,$<OR:$<C_COMPILER_ID:GNU>,$<C_COMPILER_ID:AppleClang>,$<C_COMPILER_ID:Clang>>>: $<$<AND:$<COMPILE_LANGUAGE:CXX>,$<OR:$<C_COMPILER_ID:GNU>,$<C_COMPILER_ID:AppleClang>,$<C_COMPILER_ID:Clang>>>:
-Wall -Wall
-Wextra
-Wno-trigraphs
-Wconditional-uninitialized
> >
# C++, MSVC # C++, MSVC
@ -401,8 +401,66 @@ if(SRB2_CONFIG_PROFILEMODE AND "${CMAKE_C_COMPILER_ID}" STREQUAL "GNU")
endif() endif()
add_subdirectory(sdl) add_subdirectory(sdl)
if(SRB2_CONFIG_ENABLE_TESTS)
add_subdirectory(tests) if(TARGET ZLIB::ZLIB)
target_compile_definitions(SRB2SDL2 PRIVATE -DHAVE_ZLIB)
message(STATUS "Zlib Found")
else()
message(STATUS "No Zlib Found")
endif()
if(TARGET PNG::PNG)
target_compile_definitions(SRB2SDL2 PRIVATE -DHAVE_PNG)
target_sources(SRB2SDL2 PRIVATE apng.c ${libapng_HEADER})
target_include_directories(SRB2SDL2 PRIVATE ${libapng_INCLUDE_DIRS} ${libpng_BINARY_DIR})
#message(STATUS "libpng inc DIRS at ${libapng_INCLUDE_DIRS}")
#message(STATUS "libpng bin DIRS at ${libpng_BINARY_DIR}")
#message(STATUS "png.h at ${libapng_HEADER}")
message(STATUS "libpng Found")
else()
message(STATUS "No libpng Found")
endif()
if(TARGET PNG::PNG AND TARGET ZLIB::ZLIB)
#libpng links zlib too?
target_link_libraries(SRB2SDL2 PRIVATE PNG::PNG)
endif()
if(NOT TARGET PNG::PNG AND TARGET ZLIB::ZLIB)
#got no libpng? we need zlib
target_link_libraries(SRB2SDL2 PRIVATE ZLIB::ZLIB)
endif()
if(TARGET gme::gme)
target_compile_definitions(SRB2SDL2 PRIVATE -DHAVE_GME)
target_link_libraries(SRB2SDL2 PRIVATE gme::gme)
message(STATUS "libgme Found")
else()
message(STATUS "No libgme Found")
endif()
if(TARGET libopenmpt::libopenmpt)
target_compile_definitions(SRB2SDL2 PRIVATE -DHAVE_OPENMPT)
target_link_libraries(SRB2SDL2 PRIVATE libopenmpt::libopenmpt)
message(STATUS "libopenmpt Found")
else()
message(STATUS "No libopenmpt Found")
endif()
if(TARGET CURL::libcurl)
target_compile_definitions(SRB2SDL2 PRIVATE -DHAVE_CURL)
target_link_libraries(SRB2SDL2 PRIVATE CURL::libcurl)
message(STATUS "libcurl Found")
else()
message(STATUS "No libcurl Found")
endif()
if(TARGET miniupnpc::miniupnpc)
target_compile_definitions(SRB2SDL2 PRIVATE -DHAVE_MINIUPNPC)
target_link_libraries(SRB2SDL2 PRIVATE miniupnpc::miniupnpc)
message(STATUS "miniupnpc Found")
else()
message(STATUS "No miniupnpc Found")
endif() endif()
# strip debug symbols into separate file when using gcc. # strip debug symbols into separate file when using gcc.

View file

@ -47,8 +47,6 @@
# HAVE_MINIUPNPC=1 - Enable automated port forwarding. # HAVE_MINIUPNPC=1 - Enable automated port forwarding.
# Already enabled by default for 32-bit # Already enabled by default for 32-bit
# Windows. # Windows.
# NOPNG=1 - Disable PNG graphics support. (TODO: double
# check netplay compatible.)
# NOCURL=1 - Disable libcurl--HTTP capability. # NOCURL=1 - Disable libcurl--HTTP capability.
# NOGME=1 - Disable game music emu, retro VGM support. # NOGME=1 - Disable game music emu, retro VGM support.
# NOOPENMPT=1 - Disable module (tracker) music support. # NOOPENMPT=1 - Disable module (tracker) music support.
@ -69,8 +67,6 @@
# NOEXECINFO=1 - Disable stack trace dump support # NOEXECINFO=1 - Disable stack trace dump support
# DEBUGMODE=1 - Enable various debugging capabilities. # DEBUGMODE=1 - Enable various debugging capabilities.
# Also disables optimizations. # Also disables optimizations.
# NOZLIB=1 - Disable some compression capability. Implies
# NOPNG=1.
# #
# Development flags: # Development flags:
# #

View file

@ -22,8 +22,6 @@ ifndef NOMD5
sources+=md5.c sources+=md5.c
endif endif
ifndef NOZLIB
ifndef NOPNG
ifdef PNG_PKGCONFIG ifdef PNG_PKGCONFIG
$(eval $(call Use_pkg_config,PNG_PKGCONFIG)) $(eval $(call Use_pkg_config,PNG_PKGCONFIG))
else else
@ -36,8 +34,6 @@ opts+=-D_LARGEFILE64_SOURCE
endif endif
opts+=-DHAVE_PNG opts+=-DHAVE_PNG
sources+=apng.c sources+=apng.c
endif
endif
ifndef NOCURL ifndef NOCURL
CURLCONFIG?=curl-config CURLCONFIG?=curl-config

View file

@ -135,11 +135,7 @@ ifdef GCC71
endif endif
ifdef GCC81 ifdef GCC81
WFLAGS+=-Wno-error=format-overflow WFLAGS+=-Wno-error=format-overflow
WFLAGS+=-Wno-error=stringop-truncation
WFLAGS+=-Wno-error=stringop-overflow
WFLAGS+=-Wno-format-overflow WFLAGS+=-Wno-format-overflow
WFLAGS+=-Wno-stringop-truncation
WFLAGS+=-Wno-stringop-overflow
WFLAGS+=-Wno-error=multistatement-macros WFLAGS+=-Wno-error=multistatement-macros
endif endif

View file

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

View file

@ -387,6 +387,7 @@ void B_BuildTiccmd(player_t *player, ticcmd_t *cmd)
} }
// Bot AI isn't programmed in analog. // Bot AI isn't programmed in analog.
if (!dedicated)
CV_SetValue(&cv_analog[1], false); CV_SetValue(&cv_analog[1], false);
// Let Lua scripts build ticcmds // Let Lua scripts build ticcmds
@ -589,8 +590,9 @@ void B_RespawnBot(INT32 playernum)
} }
else else
P_SetMobjState(tails, S_PLAY_FALL); P_SetMobjState(tails, S_PLAY_FALL);
P_SetScale(tails, sonic->scale); P_SetScale(tails, sonic->scale, false);
tails->destscale = sonic->destscale; tails->destscale = sonic->destscale;
tails->old_scale = sonic->old_scale;
} }
void B_HandleFlightIndicator(player_t *player) void B_HandleFlightIndicator(player_t *player)

View file

@ -134,7 +134,7 @@ void luaV_gettable (lua_State *L, TValue *t, TValue *key, StkId val) {
void luaV_settable (lua_State *L, TValue *t, TValue *key, StkId val) { void luaV_settable (lua_State *L, TValue *t, TValue *key, StkId val) {
int loop; int loop;
for (loop = 0; loop < MAXTAGLOOP; loop++) { for (loop = 0; loop < MAXTAGLOOP; loop++) {
TValue *tm; TValue *tm = NULL;
if (ttistable(t)) { /* `t' is a table? */ if (ttistable(t)) { /* `t' is a table? */
Table *h = hvalue(t); Table *h = hvalue(t);
TValue *oldval = luaH_set(L, h, key); /* do a primitive set */ TValue *oldval = luaH_set(L, h, key); /* do a primitive set */

View file

@ -11,9 +11,6 @@
/// \brief Macros to read/write from/to a UINT8 *, /// \brief Macros to read/write from/to a UINT8 *,
/// used for packet creation and such /// used for packet creation and such
#if defined (__alpha__) || defined (__arm__) || defined (__mips__) || defined (__ia64__) || defined (__clang__)
#define DEALIGNED
#endif
#include "endian.h" #include "endian.h"
@ -21,7 +18,6 @@
// //
// Little-endian machines // Little-endian machines
// //
#ifdef DEALIGNED
#define WRITEUINT8(p,b) do { UINT8 *p_tmp = (void *)p; const UINT8 tv = ( UINT8)(b); memcpy(p, &tv, sizeof( UINT8)); p_tmp++; p = (void *)p_tmp; } while (0) #define WRITEUINT8(p,b) do { UINT8 *p_tmp = (void *)p; const UINT8 tv = ( UINT8)(b); memcpy(p, &tv, sizeof( UINT8)); p_tmp++; p = (void *)p_tmp; } while (0)
#define WRITESINT8(p,b) do { SINT8 *p_tmp = (void *)p; const SINT8 tv = ( UINT8)(b); memcpy(p, &tv, sizeof( UINT8)); p_tmp++; p = (void *)p_tmp; } while (0) #define WRITESINT8(p,b) do { SINT8 *p_tmp = (void *)p; const SINT8 tv = ( UINT8)(b); memcpy(p, &tv, sizeof( UINT8)); p_tmp++; p = (void *)p_tmp; } while (0)
#define WRITEINT16(p,b) do { INT16 *p_tmp = (void *)p; const INT16 tv = ( INT16)(b); memcpy(p, &tv, sizeof( INT16)); p_tmp++; p = (void *)p_tmp; } while (0) #define WRITEINT16(p,b) do { INT16 *p_tmp = (void *)p; const INT16 tv = ( INT16)(b); memcpy(p, &tv, sizeof( INT16)); p_tmp++; p = (void *)p_tmp; } while (0)
@ -31,20 +27,8 @@
#define WRITECHAR(p,b) do { char *p_tmp = (void *)p; const char tv = ( char)(b); memcpy(p, &tv, sizeof( char)); p_tmp++; p = (void *)p_tmp; } while (0) #define WRITECHAR(p,b) do { char *p_tmp = (void *)p; const char tv = ( char)(b); memcpy(p, &tv, sizeof( char)); p_tmp++; p = (void *)p_tmp; } while (0)
#define WRITEFIXED(p,b) do { fixed_t *p_tmp = (void *)p; const fixed_t tv = (fixed_t)(b); memcpy(p, &tv, sizeof(fixed_t)); p_tmp++; p = (void *)p_tmp; } while (0) #define WRITEFIXED(p,b) do { fixed_t *p_tmp = (void *)p; const fixed_t tv = (fixed_t)(b); memcpy(p, &tv, sizeof(fixed_t)); p_tmp++; p = (void *)p_tmp; } while (0)
#define WRITEANGLE(p,b) do { angle_t *p_tmp = (void *)p; const angle_t tv = (angle_t)(b); memcpy(p, &tv, sizeof(angle_t)); p_tmp++; p = (void *)p_tmp; } while (0) #define WRITEANGLE(p,b) do { angle_t *p_tmp = (void *)p; const angle_t tv = (angle_t)(b); memcpy(p, &tv, sizeof(angle_t)); p_tmp++; p = (void *)p_tmp; } while (0)
#else
#define WRITEUINT8(p,b) do { UINT8 *p_tmp = ( UINT8 *)p; *p_tmp = ( UINT8)(b); p_tmp++; p = (void *)p_tmp; } while (0)
#define WRITESINT8(p,b) do { SINT8 *p_tmp = ( SINT8 *)p; *p_tmp = ( SINT8)(b); p_tmp++; p = (void *)p_tmp; } while (0)
#define WRITEINT16(p,b) do { INT16 *p_tmp = ( INT16 *)p; *p_tmp = ( INT16)(b); p_tmp++; p = (void *)p_tmp; } while (0)
#define WRITEUINT16(p,b) do { UINT16 *p_tmp = ( UINT16 *)p; *p_tmp = ( UINT16)(b); p_tmp++; p = (void *)p_tmp; } while (0)
#define WRITEINT32(p,b) do { INT32 *p_tmp = ( INT32 *)p; *p_tmp = ( INT32)(b); p_tmp++; p = (void *)p_tmp; } while (0)
#define WRITEUINT32(p,b) do { UINT32 *p_tmp = ( UINT32 *)p; *p_tmp = ( UINT32)(b); p_tmp++; p = (void *)p_tmp; } while (0)
#define WRITECHAR(p,b) do { char *p_tmp = ( char *)p; *p_tmp = ( char)(b); p_tmp++; p = (void *)p_tmp; } while (0)
#define WRITEFIXED(p,b) do { fixed_t *p_tmp = (fixed_t *)p; *p_tmp = (fixed_t)(b); p_tmp++; p = (void *)p_tmp; } while (0)
#define WRITEANGLE(p,b) do { angle_t *p_tmp = (angle_t *)p; *p_tmp = (angle_t)(b); p_tmp++; p = (void *)p_tmp; } while (0)
#endif
#ifdef __GNUC__ #ifdef __GNUC__
#ifdef DEALIGNED
#define READUINT8(p) ({ UINT8 *p_tmp = (void *)p; UINT8 b; memcpy(&b, p, sizeof( UINT8)); p_tmp++; p = (void *)p_tmp; b; }) #define READUINT8(p) ({ UINT8 *p_tmp = (void *)p; UINT8 b; memcpy(&b, p, sizeof( UINT8)); p_tmp++; p = (void *)p_tmp; b; })
#define READSINT8(p) ({ SINT8 *p_tmp = (void *)p; SINT8 b; memcpy(&b, p, sizeof( SINT8)); p_tmp++; p = (void *)p_tmp; b; }) #define READSINT8(p) ({ SINT8 *p_tmp = (void *)p; SINT8 b; memcpy(&b, p, sizeof( SINT8)); p_tmp++; p = (void *)p_tmp; b; })
#define READINT16(p) ({ INT16 *p_tmp = (void *)p; INT16 b; memcpy(&b, p, sizeof( INT16)); p_tmp++; p = (void *)p_tmp; b; }) #define READINT16(p) ({ INT16 *p_tmp = (void *)p; INT16 b; memcpy(&b, p, sizeof( INT16)); p_tmp++; p = (void *)p_tmp; b; })
@ -55,17 +39,6 @@
#define READFIXED(p) ({ fixed_t *p_tmp = (void *)p; fixed_t b; memcpy(&b, p, sizeof(fixed_t)); p_tmp++; p = (void *)p_tmp; b; }) #define READFIXED(p) ({ fixed_t *p_tmp = (void *)p; fixed_t b; memcpy(&b, p, sizeof(fixed_t)); p_tmp++; p = (void *)p_tmp; b; })
#define READANGLE(p) ({ angle_t *p_tmp = (void *)p; angle_t b; memcpy(&b, p, sizeof(angle_t)); p_tmp++; p = (void *)p_tmp; b; }) #define READANGLE(p) ({ angle_t *p_tmp = (void *)p; angle_t b; memcpy(&b, p, sizeof(angle_t)); p_tmp++; p = (void *)p_tmp; b; })
#else #else
#define READUINT8(p) ({ UINT8 *p_tmp = ( UINT8 *)p; UINT8 b = *p_tmp; p_tmp++; p = (void *)p_tmp; b; })
#define READSINT8(p) ({ SINT8 *p_tmp = ( SINT8 *)p; SINT8 b = *p_tmp; p_tmp++; p = (void *)p_tmp; b; })
#define READINT16(p) ({ INT16 *p_tmp = ( INT16 *)p; INT16 b = *p_tmp; p_tmp++; p = (void *)p_tmp; b; })
#define READUINT16(p) ({ UINT16 *p_tmp = ( UINT16 *)p; UINT16 b = *p_tmp; p_tmp++; p = (void *)p_tmp; b; })
#define READINT32(p) ({ INT32 *p_tmp = ( INT32 *)p; INT32 b = *p_tmp; p_tmp++; p = (void *)p_tmp; b; })
#define READUINT32(p) ({ UINT32 *p_tmp = ( UINT32 *)p; UINT32 b = *p_tmp; p_tmp++; p = (void *)p_tmp; b; })
#define READCHAR(p) ({ char *p_tmp = ( char *)p; char b = *p_tmp; p_tmp++; p = (void *)p_tmp; b; })
#define READFIXED(p) ({ fixed_t *p_tmp = (fixed_t *)p; fixed_t b = *p_tmp; p_tmp++; p = (void *)p_tmp; b; })
#define READANGLE(p) ({ angle_t *p_tmp = (angle_t *)p; angle_t b = *p_tmp; p_tmp++; p = (void *)p_tmp; b; })
#endif
#else
#define READUINT8(p) *(( UINT8 *)p)++ #define READUINT8(p) *(( UINT8 *)p)++
#define READSINT8(p) *(( SINT8 *)p)++ #define READSINT8(p) *(( SINT8 *)p)++
#define READINT16(p) *(( INT16 *)p)++ #define READINT16(p) *(( INT16 *)p)++
@ -148,8 +121,6 @@ FUNCINLINE static ATTRINLINE UINT32 readulong(void *ptr)
#define READANGLE(p) ({ angle_t *p_tmp = (angle_t *)p; angle_t b = readulong(p); p_tmp++; p = (void *)p_tmp; b; }) #define READANGLE(p) ({ angle_t *p_tmp = (angle_t *)p; angle_t b = readulong(p); p_tmp++; p = (void *)p_tmp; b; })
#endif //SRB2_BIG_ENDIAN #endif //SRB2_BIG_ENDIAN
#undef DEALIGNED
#define WRITESTRINGN(p, s, n) { \ #define WRITESTRINGN(p, s, n) { \
size_t tmp_i; \ size_t tmp_i; \
\ \

View file

@ -1992,7 +1992,7 @@ static void CV_SetCVar(consvar_t *var, const char *value, boolean stealth)
if (var->flags & CV_NETVAR) if (var->flags & CV_NETVAR)
{ {
// send the value of the variable // send the value of the variable
UINT8 buf[128]; UINT8 buf[512];
UINT8 *p = buf; UINT8 *p = buf;
// Loading from a config in a netgame? Set revert value. // Loading from a config in a netgame? Set revert value.
@ -2060,16 +2060,15 @@ void CV_StealthSet(consvar_t *var, const char *value)
*/ */
static void CV_SetValueMaybeStealth(consvar_t *var, INT32 value, boolean stealth) static void CV_SetValueMaybeStealth(consvar_t *var, INT32 value, boolean stealth)
{ {
char val[SKINNAMESIZE+1]; char val[SKINNAMESIZE+1] = "None";
if (var == &cv_forceskin) // Special handling. if (var == &cv_forceskin) // Special handling.
{ {
const char *tmpskin = NULL; const char *tmpskin = NULL;
if ((value < 0) || (value >= numskins)) if (value >= 0 && value < numskins)
tmpskin = "None";
else
tmpskin = skins[value]->name; tmpskin = skins[value]->name;
strncpy(val, tmpskin, SKINNAMESIZE); if (tmpskin)
memcpy(val, tmpskin, SKINNAMESIZE);
} }
else else
sprintf(val, "%d", value); sprintf(val, "%d", value);

View file

@ -861,12 +861,6 @@ static void CON_InputDelSelection(void)
Lock_state(); Lock_state();
if (!input_cur)
{
Unlock_state();
return;
}
if (input_cur > input_sel) if (input_cur > input_sel)
{ {
start = input_sel; start = input_sel;
@ -928,8 +922,6 @@ static void CON_InputDelChar(void)
// //
boolean CON_Responder(event_t *ev) boolean CON_Responder(event_t *ev)
{ {
static UINT8 consdown = false; // console is treated differently due to rare usage
// sequential completions a la 4dos // sequential completions a la 4dos
static char completioncmd[80 + sizeof("find ")] = "find "; static char completioncmd[80 + sizeof("find ")] = "find ";
static char *completion = &completioncmd[sizeof("find ")-1]; static char *completion = &completioncmd[sizeof("find ")-1];
@ -949,32 +941,28 @@ boolean CON_Responder(event_t *ev)
// let go keyup events, don't eat them // let go keyup events, don't eat them
if (ev->type != ev_keydown && ev->type != ev_text && ev->type != ev_console) if (ev->type != ev_keydown && ev->type != ev_text && ev->type != ev_console)
{ {
if (ev->key == gamecontrol[GC_CONSOLE][0] || ev->key == gamecontrol[GC_CONSOLE][1])
consdown = false;
return false; return false;
} }
key = ev->key; key = ev->key;
// check for console toggle key // check for console toggle key
if (ev->type != ev_console) if (ev->type == ev_keydown)
{ {
if (modeattacking || metalrecording || marathonmode) if (modeattacking || metalrecording || marathonmode)
return false; return false;
if (ev->type == ev_keydown && ((key == gamecontrol[GC_CONSOLE][0] || key == gamecontrol[GC_CONSOLE][1]) && !shiftdown)) if ((key == gamecontrol[GC_CONSOLE][0] || key == gamecontrol[GC_CONSOLE][1]) && !shiftdown)
{ {
if (consdown) // ignore repeat I_SetTextInputMode(con_destlines == 0); // inverse, since this is changed next tic.
return true;
consoletoggle = true; consoletoggle = true;
consdown = true;
return true; return true;
} }
// check other keys only if console prompt is active // check other keys only if console prompt is active
if (!consoleready && key < NUMINPUTS) // metzgermeister: boundary check!! if (!consoleready && key < NUMINPUTS) // metzgermeister: boundary check!!
{ {
if (ev->type == ev_keydown && !menuactive && bindtable[key]) if (!menuactive && bindtable[key])
{ {
COM_BufAddText(bindtable[key]); COM_BufAddText(bindtable[key]);
COM_BufAddText("\n"); COM_BufAddText("\n");
@ -986,14 +974,14 @@ boolean CON_Responder(event_t *ev)
// escape key toggle off console // escape key toggle off console
if (key == KEY_ESCAPE) if (key == KEY_ESCAPE)
{ {
I_SetTextInputMode(false);
consoletoggle = true; consoletoggle = true;
return true; return true;
} }
} }
else if (ev->type == ev_text)
if (ev->type == ev_text)
{ {
if (!consoletoggle) if (!consoletoggle && consoleready)
CON_InputAddChar(key); CON_InputAddChar(key);
return true; return true;
} }
@ -1042,7 +1030,7 @@ boolean CON_Responder(event_t *ev)
} }
else if (key == KEY_BACKSPACE) else if (key == KEY_BACKSPACE)
{ {
if (ctrldown) if (ctrldown && input_cur != 0)
{ {
input_sel = M_JumpWordReverse(inputlines[inputline], input_cur); input_sel = M_JumpWordReverse(inputlines[inputline], input_cur);
CON_InputDelSelection(); CON_InputDelSelection();
@ -1100,7 +1088,9 @@ boolean CON_Responder(event_t *ev)
if (key == 'x' || key == 'X') if (key == 'x' || key == 'X')
{ {
if (input_sel > input_cur) if (input_sel == input_cur) // Don't replace the clipboard without a text selection
return true;
else if (input_sel > input_cur)
I_ClipboardCopy(&inputlines[inputline][input_cur], input_sel-input_cur); I_ClipboardCopy(&inputlines[inputline][input_cur], input_sel-input_cur);
else else
I_ClipboardCopy(&inputlines[inputline][input_sel], input_cur-input_sel); I_ClipboardCopy(&inputlines[inputline][input_sel], input_cur-input_sel);
@ -1110,7 +1100,9 @@ boolean CON_Responder(event_t *ev)
} }
else if (key == 'c' || key == 'C') else if (key == 'c' || key == 'C')
{ {
if (input_sel > input_cur) if (input_sel == input_cur) // Don't replace the clipboard without a text selection
return true;
else if (input_sel > input_cur)
I_ClipboardCopy(&inputlines[inputline][input_cur], input_sel-input_cur); I_ClipboardCopy(&inputlines[inputline][input_cur], input_sel-input_cur);
else else
I_ClipboardCopy(&inputlines[inputline][input_sel], input_cur-input_sel); I_ClipboardCopy(&inputlines[inputline][input_sel], input_cur-input_sel);
@ -1713,11 +1705,11 @@ static void CON_DrawHudlines(void)
} }
if (c >= con_width) if (c >= con_width)
break; break;
if (*p < HU_FONTSTART) if (*p < FONTSTART)
;//charwidth = 4 * con_scalefactor; ;//charwidth = 4 * con_scalefactor;
else else
{ {
//charwidth = (hu_font['A'-HU_FONTSTART]->width) * con_scalefactor; //charwidth = (hu_font.chars['A'-FONTSTART]->width) * con_scalefactor;
V_DrawCharacter(x, y, (INT32)(*p) | charflags | cv_constextsize.value | V_NOSCALESTART, true); V_DrawCharacter(x, y, (INT32)(*p) | charflags | cv_constextsize.value | V_NOSCALESTART, true);
} }
} }
@ -1736,12 +1728,12 @@ static void CON_DrawBackpic(void)
// Get the lumpnum for CONSBACK, STARTUP (Only during game startup) or fallback into MISSING. // Get the lumpnum for CONSBACK, STARTUP (Only during game startup) or fallback into MISSING.
if (con_startup) if (con_startup)
piclump = W_CheckNumForName("STARTUP"); piclump = W_CheckNumForPatchName("STARTUP");
else else
piclump = W_CheckNumForName("CONSBACK"); piclump = W_CheckNumForPatchName("CONSBACK");
if (piclump == LUMPERROR) if (piclump == LUMPERROR)
piclump = W_GetNumForName("MISSING"); piclump = W_GetNumForPatchName("MISSING");
// Cache the patch. // Cache the patch.
con_backpic = W_CachePatchNum(piclump, PU_PATCH); con_backpic = W_CachePatchNum(piclump, PU_PATCH);

View file

@ -475,6 +475,18 @@ static void D_Display(void)
if (gamestate == GS_LEVEL || (gamestate == GS_TITLESCREEN && titlemapinaction && curbghide && (!hidetitlemap))) if (gamestate == GS_LEVEL || (gamestate == GS_TITLESCREEN && titlemapinaction && curbghide && (!hidetitlemap)))
{ {
// draw the view directly // draw the view directly
if (cv_debug)
{
r_renderwalls = cv_renderwalls.value;
r_renderfloors = cv_renderfloors.value;
r_renderthings = cv_renderthings.value;
}
else
{
r_renderwalls = true;
r_renderfloors = true;
r_renderthings = true;
}
if (!automapactive && !dedicated && cv_renderview.value) if (!automapactive && !dedicated && cv_renderview.value)
{ {
@ -745,9 +757,9 @@ void D_SRB2Loop(void)
/* Smells like a hack... Don't fade Sonic's ass into the title screen. */ /* Smells like a hack... Don't fade Sonic's ass into the title screen. */
if (gamestate != GS_TITLESCREEN) if (gamestate != GS_TITLESCREEN)
{ {
gstartuplumpnum = W_CheckNumForName("STARTUP"); gstartuplumpnum = W_CheckNumForPatchName("STARTUP");
if (gstartuplumpnum == LUMPERROR) if (gstartuplumpnum == LUMPERROR)
gstartuplumpnum = W_GetNumForName("MISSING"); gstartuplumpnum = W_GetNumForPatchName("MISSING");
V_DrawScaledPatch(0, 0, 0, W_CachePatchNum(gstartuplumpnum, PU_PATCH)); V_DrawScaledPatch(0, 0, 0, W_CachePatchNum(gstartuplumpnum, PU_PATCH));
} }
@ -970,7 +982,7 @@ void D_StartTitle(void)
emeralds = 0; emeralds = 0;
memset(&luabanks, 0, sizeof(luabanks)); memset(&luabanks, 0, sizeof(luabanks));
lastmaploaded = 0; lastmaploaded = 0;
pickedchar = R_SkinAvailable(cv_defaultskin.string); pickedchar = R_SkinAvailable(cv_skin.string);
// In case someone exits out at the same time they start a time attack run, // In case someone exits out at the same time they start a time attack run,
// reset modeattacking // reset modeattacking
@ -1011,7 +1023,7 @@ void D_StartTitle(void)
#define REALLOC_FILE_LIST \ #define REALLOC_FILE_LIST \
if (list->files == NULL) \ if (list->files == NULL) \
{ \ { \
list->files = calloc(sizeof(list->files), 2); \ list->files = calloc(2, sizeof(list->files)); \
list->numfiles = 1; \ list->numfiles = 1; \
} \ } \
else \ else \
@ -1814,17 +1826,21 @@ static boolean check_top_dir(const char **path, const char *top)
return true; return true;
} }
static int cmp_strlen_desc(const void *a, const void *b) static int cmp_strlen_desc(const void *A, const void *B)
{ {
return ((int)strlen(*(const char*const*)b) - (int)strlen(*(const char*const*)a)); const char *pA = A;
const char *pB = B;
size_t As = strlen(pA);
size_t Bs = strlen(pB);
return ((int)Bs - (int)As);
} }
boolean D_IsPathAllowed(const char *path) boolean D_IsPathAllowed(const char *path)
{ {
const char *paths[] = { char *paths[] = {
srb2home, srb2home,
srb2path, srb2path,
cv_addons_folder.string cv_addons_folder.zstring
}; };
const size_t n_paths = sizeof paths / sizeof *paths; const size_t n_paths = sizeof paths / sizeof *paths;

View file

@ -373,6 +373,16 @@ typedef enum
AI_SPINFOLLOW AI_SPINFOLLOW
} aistatetype_t; } aistatetype_t;
// NiGHTS text
typedef enum
{
NTV_NONE = 0,
NTV_GETSPHERES,
NTV_GETMORESPHERES,
NTV_BONUSTIMESTART,
NTV_BONUSTIMEEND,
} nightstextvar_t;
// ======================================================================== // ========================================================================
// PLAYER STRUCTURE // PLAYER STRUCTURE
@ -572,7 +582,8 @@ typedef struct player_s
// Statistical purposes. // Statistical purposes.
tic_t marebegunat; // Leveltime when mare begun tic_t marebegunat; // Leveltime when mare begun
tic_t startedtime; // Time which you started this mare with. tic_t startedtime; // Time which you started this mare with.
tic_t finishedtime; // Time it took you to finish the mare (used for display) tic_t finishedtime; // The time it took to destroy the capsule on this mare (used for bonus time display)
tic_t lastmaretime; // The time it took to complete the last mare (used for rank display)
tic_t lapbegunat; // Leveltime when lap begun tic_t lapbegunat; // Leveltime when lap begun
tic_t lapstartedtime; // Time which you started this lap with. tic_t lapstartedtime; // Time which you started this lap with.
INT16 finishedspheres; // The spheres you had left upon finishing the mare INT16 finishedspheres; // The spheres you had left upon finishing the mare
@ -587,7 +598,7 @@ typedef struct player_s
UINT8 totalmarebonuslap; // total mare bonus lap UINT8 totalmarebonuslap; // total mare bonus lap
INT32 maxlink; // maximum link obtained INT32 maxlink; // maximum link obtained
UINT8 texttimer; // nights_texttime should not be local UINT8 texttimer; // nights_texttime should not be local
UINT8 textvar; // which line of NiGHTS text to show -- let's not use cheap hacks UINT8 textvar; // which line of NiGHTS text to show -- see nightstextvar_t
INT16 lastsidehit, lastlinehit; INT16 lastsidehit, lastlinehit;
@ -603,6 +614,7 @@ typedef struct player_s
boolean spectator; boolean spectator;
boolean outofcoop; boolean outofcoop;
boolean removing; boolean removing;
boolean muted;
UINT8 bot; UINT8 bot;
struct player_s *botleader; struct player_s *botleader;
UINT16 lastbuttons; UINT16 lastbuttons;

View file

@ -1433,9 +1433,15 @@ static const char *locateWad(void)
#ifndef NOHOME #ifndef NOHOME
// find in $HOME // find in $HOME
I_OutputMsg(",HOME"); I_OutputMsg(",HOME/" DEFAULTDIR);
if ((envstr = I_GetEnv("HOME")) != NULL) if ((envstr = I_GetEnv("HOME")) != NULL)
{
char *tmp = malloc(strlen(envstr) + sizeof(DEFAULTDIR));
strcpy(tmp, envstr);
strcat(tmp, DEFAULTDIR);
SEARCHWAD(envstr); SEARCHWAD(envstr);
free(tmp);
}
#endif #endif
// search paths // search paths
@ -1585,5 +1591,15 @@ void I_GetCursorPosition(INT32 *x, INT32 *y)
(void)y; (void)y;
} }
void I_SetTextInputMode(boolean active)
{
(void)active;
}
boolean I_GetTextInputMode(void)
{
return false;
}
#include "../sdl/dosstr.c" #include "../sdl/dosstr.c"

View file

@ -11,6 +11,7 @@
/// \brief Lua SOC library /// \brief Lua SOC library
#include "deh_lua.h" #include "deh_lua.h"
#include "g_input.h"
// freeslot takes a name (string only!) // freeslot takes a name (string only!)
// and allocates it to the appropriate free slot. // and allocates it to the appropriate free slot.
@ -58,24 +59,19 @@ static inline int lib_freeslot(lua_State *L)
} }
else if (fastcmp(type, "SPR")) else if (fastcmp(type, "SPR"))
{ {
char wad;
spritenum_t j; spritenum_t j;
lua_getfield(L, LUA_REGISTRYINDEX, "WAD");
wad = (char)lua_tointeger(L, -1); if (strlen(word) > MAXSPRITENAME)
lua_pop(L, 1); return luaL_error(L, "Sprite name is longer than %d characters\n", MAXSPRITENAME);
for (j = SPR_FIRSTFREESLOT; j <= SPR_LASTFREESLOT; j++) for (j = SPR_FIRSTFREESLOT; j <= SPR_LASTFREESLOT; j++)
{ {
if (used_spr[(j-SPR_FIRSTFREESLOT)/8] & (1<<(j%8))) if (in_bit_array(used_spr, j - SPR_FIRSTFREESLOT))
{
if (!sprnames[j][4] && memcmp(sprnames[j],word,4)==0)
sprnames[j][4] = wad;
continue; // Already allocated, next. continue; // Already allocated, next.
}
// Found a free slot! // Found a free slot!
CONS_Printf("Sprite SPR_%s allocated.\n",word); CONS_Printf("Sprite SPR_%s allocated.\n",word);
strncpy(sprnames[j],word,4); strcpy(sprnames[j], word);
//sprnames[j][4] = 0; set_bit_array(used_spr, j - SPR_FIRSTFREESLOT); // Okay, this sprite slot has been named now.
used_spr[(j-SPR_FIRSTFREESLOT)/8] |= 1<<(j%8); // Okay, this sprite slot has been named now.
// Lua needs to update the value in _G if it exists // Lua needs to update the value in _G if it exists
LUA_UpdateSprName(word, j); LUA_UpdateSprName(word, j);
lua_pushinteger(L, j); lua_pushinteger(L, j);
@ -454,8 +450,9 @@ static int ScanConstants(lua_State *L, boolean mathlib, const char *word)
} }
else if (fastncmp("SPR_",word,4)) { else if (fastncmp("SPR_",word,4)) {
p = word+4; p = word+4;
for (i = 0; i < NUMSPRITES; i++) i = R_GetSpriteNumByName(p);
if (!sprnames[i][4] && fastncmp(p,sprnames[i],4)) { if (i != NUMSPRITES)
{
// updating overridden sprnames is not implemented for soc parser, // updating overridden sprnames is not implemented for soc parser,
// so don't use cache // so don't use cache
if (mathlib) if (mathlib)
@ -464,7 +461,8 @@ static int ScanConstants(lua_State *L, boolean mathlib, const char *word)
CacheAndPushConstant(L, word, i); CacheAndPushConstant(L, word, i);
return 1; return 1;
} }
if (mathlib) return luaL_error(L, "sprite '%s' could not be found.\n", word); else if (mathlib)
return luaL_error(L, "sprite '%s' could not be found.\n", word);
return 0; return 0;
} }
else if (fastncmp("SPR2_",word,5)) { else if (fastncmp("SPR2_",word,5)) {
@ -596,12 +594,20 @@ static int ScanConstants(lua_State *L, boolean mathlib, const char *word)
return luaL_error(L, "translation '%s' could not be found.\n", word); return luaL_error(L, "translation '%s' could not be found.\n", word);
} }
// TODO: 2.3: Delete this alias // TODO: 2.3: Delete these aliases
if (fastcmp(word, "BT_USE")) else if (fastcmp(word, "BT_USE"))
{ {
CacheAndPushConstant(L, word, (lua_Integer)BT_SPIN); CacheAndPushConstant(L, word, (lua_Integer)BT_SPIN);
return 1; return 1;
} }
else if (fastcmp(word, "GC_WEPSLOT8") || fastcmp(word, "GC_WEPSLOT9") || fastcmp(word, "GC_WEPSLOT10"))
{
// Using GC_WEPSLOT7 isn't accurate, but ensures that "if x >= GC_WEPSLOT1 and x <= GC_WEPSLOT10" keeps the intended effect
CacheAndPushConstant(L, word, (lua_Integer)GC_WEPSLOT7);
if (!mathlib)
LUA_Deprecated(L, "GC_WEPSLOT8\"-\"GC_WEPSLOT10", "GC_WEPSLOT1\"-\"GC_WEPSLOT7");
return 1;
}
for (i = 0; INT_CONST[i].n; i++) for (i = 0; INT_CONST[i].n; i++)
if (fastcmp(word,INT_CONST[i].n)) { if (fastcmp(word,INT_CONST[i].n)) {
@ -729,18 +735,18 @@ static inline int lib_getenum(lua_State *L)
// If a sprname has been "cached" to _G, update it to a new value. // If a sprname has been "cached" to _G, update it to a new value.
void LUA_UpdateSprName(const char *name, lua_Integer value) void LUA_UpdateSprName(const char *name, lua_Integer value)
{ {
char fullname[9] = "SPR_XXXX"; char fullname[4 + MAXSPRITENAME + 1] = "SPR_";
if (!gL) if (!gL)
return; return;
strncpy(&fullname[4], name, 4); strcpy(&fullname[4], name);
lua_pushstring(gL, fullname); lua_pushstring(gL, fullname);
lua_rawget(gL, LUA_GLOBALSINDEX); lua_rawget(gL, LUA_GLOBALSINDEX);
if (!lua_isnil(gL, -1)) if (!lua_isnil(gL, -1))
{ {
lua_pushstring(gL, name); lua_pushstring(gL, fullname);
lua_pushinteger(gL, value); lua_pushinteger(gL, value);
lua_rawset(gL, LUA_GLOBALSINDEX); lua_rawset(gL, LUA_GLOBALSINDEX);
} }

View file

@ -324,7 +324,7 @@ void readPlayer(MYFILE *f, INT32 num)
if (fastcmp(word, "PICNAME")) if (fastcmp(word, "PICNAME"))
{ {
SLOTFOUND SLOTFOUND
strncpy(description[num].picname, word2, 8); strncpy(description[num].picname, word2, sizeof(description[num].picname)-1);
} }
else if (fastcmp(word, "DISPLAYNAME")) else if (fastcmp(word, "DISPLAYNAME"))
{ {
@ -355,7 +355,7 @@ void readPlayer(MYFILE *f, INT32 num)
else if (fastcmp(word, "NAMETAG") || fastcmp(word, "TAGNAME")) else if (fastcmp(word, "NAMETAG") || fastcmp(word, "TAGNAME"))
{ {
SLOTFOUND SLOTFOUND
strncpy(description[num].nametag, word2, 8); strncpy(description[num].nametag, word2, sizeof(description[num].nametag)-1);
} }
else if (fastcmp(word, "TAGTEXTCOLOR") || fastcmp(word, "TAGTEXTCOLOUR")) else if (fastcmp(word, "TAGTEXTCOLOR") || fastcmp(word, "TAGTEXTCOLOUR"))
{ {
@ -405,7 +405,6 @@ void readfreeslots(MYFILE *f)
{ {
char *s = Z_Malloc(MAXLINELEN, PU_STATIC, NULL); char *s = Z_Malloc(MAXLINELEN, PU_STATIC, NULL);
char *word,*type; char *word,*type;
char *tmp;
int i; int i;
do do
@ -415,10 +414,13 @@ void readfreeslots(MYFILE *f)
if (s[0] == '\n') if (s[0] == '\n')
break; break;
tmp = strchr(s, '#'); char *hashtag = strchr(s, '#');
if (tmp) char *space = strchr(s, ' ');
*tmp = '\0'; if (hashtag)
if (s == tmp) *hashtag = '\0';
if (space)
*space = '\0';
if (s == hashtag || s == space)
continue; // Skip comment lines, but don't break. continue; // Skip comment lines, but don't break.
type = strtok(s, "_"); type = strtok(s, "_");
@ -440,18 +442,16 @@ void readfreeslots(MYFILE *f)
S_AddSoundFx(word, false, 0, false); S_AddSoundFx(word, false, 0, false);
else if (fastcmp(type, "SPR")) else if (fastcmp(type, "SPR"))
{ {
if (strlen(word) > MAXSPRITENAME)
I_Error("Sprite name is longer than %d characters\n", MAXSPRITENAME);
for (i = SPR_FIRSTFREESLOT; i <= SPR_LASTFREESLOT; i++) for (i = SPR_FIRSTFREESLOT; i <= SPR_LASTFREESLOT; i++)
{ {
if (used_spr[(i-SPR_FIRSTFREESLOT)/8] & (1<<(i%8))) if (in_bit_array(used_spr, i - SPR_FIRSTFREESLOT))
{
if (!sprnames[i][4] && memcmp(sprnames[i],word,4)==0)
sprnames[i][4] = (char)f->wad;
continue; // Already allocated, next. continue; // Already allocated, next.
}
// Found a free slot! // Found a free slot!
strncpy(sprnames[i],word,4); strcpy(sprnames[i], word);
//sprnames[i][4] = 0; set_bit_array(used_spr, i - SPR_FIRSTFREESLOT); // Okay, this sprite slot has been named now.
used_spr[(i-SPR_FIRSTFREESLOT)/8] |= 1<<(i%8); // Okay, this sprite slot has been named now.
// Lua needs to update the value in _G if it exists // Lua needs to update the value in _G if it exists
LUA_UpdateSprName(word, i); LUA_UpdateSprName(word, i);
break; break;
@ -1163,7 +1163,7 @@ void readgametype(MYFILE *f, char *gtname)
INT16 newgtrankingstype = -1; INT16 newgtrankingstype = -1;
int newgtinttype = 0; int newgtinttype = 0;
char gtdescription[441]; char gtdescription[441];
char gtconst[MAXLINELEN]; char gtconst[MAXLINELEN+1];
// Empty strings. // Empty strings.
gtdescription[0] = '\0'; gtdescription[0] = '\0';
@ -1543,6 +1543,12 @@ void readlevelheader(MYFILE *f, INT32 num)
P_AddGradesForMare((INT16)(num-1), mare-1, word2); P_AddGradesForMare((INT16)(num-1), mare-1, word2);
} }
// NiGHTS time limits (per mare)
else if (fastncmp(word, "NIGHTSTIME", 10))
{
P_AddNiGHTSTimes((INT16)(num-1), word2);
}
// Strings that can be truncated // Strings that can be truncated
else if (fastcmp(word, "SELECTHEADING")) else if (fastcmp(word, "SELECTHEADING"))
{ {
@ -1676,7 +1682,7 @@ void readlevelheader(MYFILE *f, INT32 num)
else if (fastcmp(word, "SKYNUM")) else if (fastcmp(word, "SKYNUM"))
mapheaderinfo[num-1]->skynum = (INT16)i; mapheaderinfo[num-1]->skynum = (INT16)i;
else if (fastcmp(word, "INTERSCREEN")) else if (fastcmp(word, "INTERSCREEN"))
strncpy(mapheaderinfo[num-1]->interscreen, word2, 8); strncpy(mapheaderinfo[num-1]->interscreen, word2, sizeof(mapheaderinfo[num-1]->interscreen)-1);
else if (fastcmp(word, "PRECUTSCENENUM")) else if (fastcmp(word, "PRECUTSCENENUM"))
mapheaderinfo[num-1]->precutscenenum = (UINT8)i; mapheaderinfo[num-1]->precutscenenum = (UINT8)i;
else if (fastcmp(word, "CUTSCENENUM")) else if (fastcmp(word, "CUTSCENENUM"))
@ -2293,7 +2299,7 @@ static void readtextpromptpage(MYFILE *f, INT32 num, INT32 pagenum)
char name[34]; char name[34];
name[0] = '\x82'; // color yellow name[0] = '\x82'; // color yellow
name[1] = 0; name[1] = 0;
strncat(name, word2, 33); strncat(name, word2, 32);
name[33] = 0; name[33] = 0;
// Replace _ with ' ' // Replace _ with ' '
@ -2303,7 +2309,7 @@ static void readtextpromptpage(MYFILE *f, INT32 num, INT32 pagenum)
name[j] = ' '; name[j] = ' ';
} }
strncpy(textprompts[num]->page[pagenum].name, name, 32); strncpy(textprompts[num]->page[pagenum].name, name, sizeof(textprompts[num]->page[pagenum].name));
} }
else else
*textprompts[num]->page[pagenum].name = '\0'; *textprompts[num]->page[pagenum].name = '\0';
@ -2784,7 +2790,7 @@ void readframe(MYFILE *f, INT32 num)
size_t z; size_t z;
boolean found = false; boolean found = false;
size_t actionlen = strlen(word2) + 1; size_t actionlen = strlen(word2) + 1;
char *actiontocompare = calloc(actionlen, 1); char *actiontocompare = calloc(1, actionlen);
strcpy(actiontocompare, word2); strcpy(actiontocompare, word2);
strupr(actiontocompare); strupr(actiontocompare);
@ -3793,7 +3799,7 @@ void readmaincfg(MYFILE *f)
} }
else if (fastcmp(word, "TITLEPICSNAME")) else if (fastcmp(word, "TITLEPICSNAME"))
{ {
strncpy(ttname, word2, 9); strncpy(ttname, word2, sizeof(ttname)-1);
titlechanged = true; titlechanged = true;
} }
else if (fastcmp(word, "TITLEPICSX")) else if (fastcmp(word, "TITLEPICSX"))
@ -3877,8 +3883,12 @@ void readmaincfg(MYFILE *f)
savemoddata = true; savemoddata = true;
// Also save a time attack folder // Also save a time attack folder
filenamelen = strlen(gamedatafilename)-4; // Strip off the extension filenamelen = strlen(gamedatafilename); // Strip off the extension
strncpy(timeattackfolder, gamedatafilename, min(filenamelen, sizeof (timeattackfolder))); if (filenamelen >= 4)
filenamelen -= 4;
if (filenamelen >= sizeof(timeattackfolder))
filenamelen = sizeof(timeattackfolder)-1;
strncpy(timeattackfolder, gamedatafilename, filenamelen);
timeattackfolder[min(filenamelen, sizeof (timeattackfolder) - 1)] = '\0'; timeattackfolder[min(filenamelen, sizeof (timeattackfolder) - 1)] = '\0';
strcpy(savegamename, timeattackfolder); strcpy(savegamename, timeattackfolder);
@ -4171,8 +4181,8 @@ spritenum_t get_sprite(const char *word)
return atoi(word); return atoi(word);
if (fastncmp("SPR_",word,4)) if (fastncmp("SPR_",word,4))
word += 4; // take off the SPR_ word += 4; // take off the SPR_
for (i = 0; i < NUMSPRITES; i++) i = R_GetSpriteNumByName(word);
if (!sprnames[i][4] && memcmp(word,sprnames[i],4)==0) if (i != NUMSPRITES)
return i; return i;
deh_warning("Couldn't find sprite named 'SPR_%s'",word); deh_warning("Couldn't find sprite named 'SPR_%s'",word);
return SPR_NULL; return SPR_NULL;

View file

@ -31,7 +31,7 @@
char *FREE_STATES[NUMSTATEFREESLOTS]; char *FREE_STATES[NUMSTATEFREESLOTS];
char *FREE_MOBJS[NUMMOBJFREESLOTS]; char *FREE_MOBJS[NUMMOBJFREESLOTS];
char *FREE_SKINCOLORS[NUMCOLORFREESLOTS]; char *FREE_SKINCOLORS[NUMCOLORFREESLOTS];
UINT8 used_spr[(NUMSPRITEFREESLOTS / 8) + 1]; // Bitwise flag for sprite freeslot in use! I would use ceil() here if I could, but it only saves 1 byte of memory anyway. bitarray_t used_spr[BIT_ARRAY_SIZE(NUMSPRITEFREESLOTS)]; // Sprite freeslots in use
const char NIGHTSGRADE_LIST[] = { const char NIGHTSGRADE_LIST[] = {
'F', // GRADE_F 'F', // GRADE_F
@ -4483,6 +4483,8 @@ const char *const PLAYERFLAG_LIST[] = {
"CANCARRY", // Can carry? "CANCARRY", // Can carry?
"FINISHED", "FINISHED",
"SHIELDDOWN", // Shield has been pressed.
NULL // stop loop here. NULL // stop loop here.
}; };
@ -5096,6 +5098,10 @@ struct int_const_s const INT_CONST[] = {
{"RF_SHADOWEFFECTS",RF_SHADOWEFFECTS}, {"RF_SHADOWEFFECTS",RF_SHADOWEFFECTS},
{"RF_DROPSHADOW",RF_DROPSHADOW}, {"RF_DROPSHADOW",RF_DROPSHADOW},
// Animation flags
{"SPR2F_MASK",SPR2F_MASK},
{"SPR2F_SUPER",SPR2F_SUPER},
// Level flags // Level flags
{"LF_SCRIPTISFILE",LF_SCRIPTISFILE}, {"LF_SCRIPTISFILE",LF_SCRIPTISFILE},
{"LF_SPEEDMUSIC",LF_SPEEDMUSIC}, {"LF_SPEEDMUSIC",LF_SPEEDMUSIC},
@ -5738,6 +5744,7 @@ struct int_const_s const INT_CONST[] = {
{"JA_DIGITAL",JA_DIGITAL}, {"JA_DIGITAL",JA_DIGITAL},
{"JA_JUMP",JA_JUMP}, {"JA_JUMP",JA_JUMP},
{"JA_SPIN",JA_SPIN}, {"JA_SPIN",JA_SPIN},
{"JA_SHIELD",JA_SHIELD},
{"JA_FIRE",JA_FIRE}, {"JA_FIRE",JA_FIRE},
{"JA_FIRENORMAL",JA_FIRENORMAL}, {"JA_FIRENORMAL",JA_FIRENORMAL},
{"JOYAXISRANGE",JOYAXISRANGE}, {"JOYAXISRANGE",JOYAXISRANGE},
@ -5799,6 +5806,10 @@ struct int_const_s const INT_CONST[] = {
{"MB_SCROLLUP",MB_SCROLLUP}, {"MB_SCROLLUP",MB_SCROLLUP},
{"MB_SCROLLDOWN",MB_SCROLLDOWN}, {"MB_SCROLLDOWN",MB_SCROLLDOWN},
// screen.h constants
{"BASEVIDWIDTH",BASEVIDWIDTH},
{"BASEVIDHEIGHT",BASEVIDHEIGHT},
// Music flags & stuff // Music flags & stuff
{"MUSIC_TRACKMASK", MUSIC_TRACKMASK}, {"MUSIC_TRACKMASK", MUSIC_TRACKMASK},
{"MUSIC_FORCERESET", MUSIC_FORCERESET}, {"MUSIC_FORCERESET", MUSIC_FORCERESET},

View file

@ -23,13 +23,13 @@
extern char *FREE_STATES[NUMSTATEFREESLOTS]; extern char *FREE_STATES[NUMSTATEFREESLOTS];
extern char *FREE_MOBJS[NUMMOBJFREESLOTS]; extern char *FREE_MOBJS[NUMMOBJFREESLOTS];
extern char *FREE_SKINCOLORS[NUMCOLORFREESLOTS]; extern char *FREE_SKINCOLORS[NUMCOLORFREESLOTS];
extern UINT8 used_spr[(NUMSPRITEFREESLOTS / 8) + 1]; // Bitwise flag for sprite freeslot in use! I would use ceil() here if I could, but it only saves 1 byte of memory anyway. extern bitarray_t used_spr[BIT_ARRAY_SIZE(NUMSPRITEFREESLOTS)]; // Sprite freeslots in use
#define initfreeslots() {\ #define initfreeslots() {\
memset(FREE_STATES,0,sizeof(char *) * NUMSTATEFREESLOTS);\ memset(FREE_STATES, 0, sizeof(FREE_STATES));\
memset(FREE_MOBJS,0,sizeof(char *) * NUMMOBJFREESLOTS);\ memset(FREE_MOBJS, 0, sizeof(FREE_MOBJS));\
memset(FREE_SKINCOLORS,0,sizeof(char *) * NUMCOLORFREESLOTS);\ memset(FREE_SKINCOLORS, 0, sizeof(FREE_SKINCOLORS));\
memset(used_spr,0,sizeof(UINT8) * ((NUMSPRITEFREESLOTS / 8) + 1));\ memset(used_spr, 0, sizeof(used_spr));\
memset(actionsoverridden, LUA_REFNIL, sizeof(actionsoverridden));\ memset(actionsoverridden, LUA_REFNIL, sizeof(actionsoverridden));\
} }

View file

@ -82,6 +82,7 @@
#include "version.h" #include "version.h"
#include "doomtype.h" #include "doomtype.h"
#include <assert.h>
#include <stdarg.h> #include <stdarg.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@ -648,6 +649,7 @@ UINT32 quickncasehash (const char *p, size_t n)
#else #else
#define I_Assert(e) ((void)0) #define I_Assert(e) ((void)0)
#endif #endif
#define I_StaticAssert(e) static_assert(e, "Static assertion failed: " #e)
// The character that separates pathnames. Forward slash on // The character that separates pathnames. Forward slash on
// most systems, but reverse solidus (\) on Windows. // most systems, but reverse solidus (\) on Windows.

View file

@ -164,7 +164,7 @@ extern boolean exitfadestarted;
typedef struct typedef struct
{ {
UINT8 numpics; UINT8 numpics;
char picname[8][8]; char picname[8][8+1];
UINT8 pichires[8]; UINT8 pichires[8];
char *text; char *text;
UINT16 xcoord[8]; UINT16 xcoord[8];
@ -295,17 +295,17 @@ typedef struct
typedef struct typedef struct
{ {
// The original eight, plus one. // The original eight, plus one.
char lvlttl[22]; ///< Level name without "Zone". (21 character limit instead of 32, 21 characters can display on screen max anyway) char lvlttl[21+1]; ///< Level name without "Zone". (21 character limit instead of 32, 21 characters can display on screen max anyway)
char subttl[33]; ///< Subtitle for level char subttl[32+1]; ///< Subtitle for level
UINT8 actnum; ///< Act number or 0 for none. UINT8 actnum; ///< Act number or 0 for none.
UINT32 typeoflevel; ///< Combination of typeoflevel flags. UINT32 typeoflevel; ///< Combination of typeoflevel flags.
INT16 nextlevel; ///< Map number of next level, or 1100-1102 to end. INT16 nextlevel; ///< Map number of next level, or 1100-1102 to end.
INT16 marathonnext; ///< See nextlevel, but for Marathon mode. Necessary to support hub worlds ala SUGOI. INT16 marathonnext; ///< See nextlevel, but for Marathon mode. Necessary to support hub worlds ala SUGOI.
char keywords[33]; ///< Keywords separated by space to search for. 32 characters. char keywords[32+1]; ///< Keywords separated by space to search for. 32 characters.
char musname[7]; ///< Music track to play. "" for no music. char musname[7]; ///< Music track to play. "" for no music.
UINT16 mustrack; ///< Subsong to play. Only really relevant for music modules and specific formats supported by GME. 0 to ignore. UINT16 mustrack; ///< Subsong to play. Only really relevant for music modules and specific formats supported by GME. 0 to ignore.
UINT32 muspos; ///< Music position to jump to. UINT32 muspos; ///< Music position to jump to.
char forcecharacter[17]; ///< (SKINNAMESIZE+1) Skin to switch to or "" to disable. char forcecharacter[16+1]; ///< (SKINNAMESIZE+1) Skin to switch to or "" to disable.
UINT8 weather; ///< 0 = sunny day, 1 = storm, 2 = snow, 3 = rain, 4 = blank, 5 = thunder w/o rain, 6 = rain w/o lightning, 7 = heat wave. UINT8 weather; ///< 0 = sunny day, 1 = storm, 2 = snow, 3 = rain, 4 = blank, 5 = thunder w/o rain, 6 = rain w/o lightning, 7 = heat wave.
INT16 skynum; ///< Sky number to use. INT16 skynum; ///< Sky number to use.
INT16 skybox_scalex; ///< Skybox X axis scale. (0 = no movement, 1 = 1:1 movement, 16 = 16:1 slow movement, -4 = 1:4 fast movement, etc.) INT16 skybox_scalex; ///< Skybox X axis scale. (0 = no movement, 1 = 1:1 movement, 16 = 16:1 slow movement, -4 = 1:4 fast movement, etc.)
@ -313,9 +313,9 @@ typedef struct
INT16 skybox_scalez; ///< Skybox Z axis scale. INT16 skybox_scalez; ///< Skybox Z axis scale.
// Extra information. // Extra information.
char interscreen[8]; ///< 320x200 patch to display at intermission. char interscreen[8+1]; ///< 320x200 patch to display at intermission.
char runsoc[33]; ///< SOC to execute at start of level (32 character limit instead of 63) char runsoc[32+1]; ///< SOC to execute at start of level (32 character limit instead of 63)
char scriptname[33]; ///< Script to use when the map is switched to. (32 character limit instead of 191) char scriptname[32+1]; ///< Script to use when the map is switched to. (32 character limit instead of 191)
UINT8 precutscenenum; ///< Cutscene number to play BEFORE a level starts. UINT8 precutscenenum; ///< Cutscene number to play BEFORE a level starts.
UINT8 cutscenenum; ///< Cutscene number to use, 0 for none. UINT8 cutscenenum; ///< Cutscene number to use, 0 for none.
INT16 countdown; ///< Countdown until level end? INT16 countdown; ///< Countdown until level end?
@ -334,11 +334,12 @@ typedef struct
INT32 sstimer; ///< Timer for special stages. INT32 sstimer; ///< Timer for special stages.
UINT32 ssspheres; ///< Sphere requirement in special stages. UINT32 ssspheres; ///< Sphere requirement in special stages.
fixed_t gravity; ///< Map-wide gravity. fixed_t gravity; ///< Map-wide gravity.
UINT16 nightstimer[8]; ///< Per-mare time limits for NiGHTS stages.
// Title card. // Title card.
char ltzzpatch[9]; ///< Zig zag patch. char ltzzpatch[8+1]; ///< Zig zag patch.
char ltzztext[9]; ///< Zig zag text. char ltzztext[8+1]; ///< Zig zag text.
char ltactdiamond[9]; ///< Act diamond. char ltactdiamond[8+1]; ///< Act diamond.
// Freed animals stuff. // Freed animals stuff.
UINT8 numFlickies; ///< Internal. For freed flicky support. UINT8 numFlickies; ///< Internal. For freed flicky support.

View file

@ -108,6 +108,7 @@ char *nongnu_strcasestr(const char *in, const char *what);
int startswith (const char *base, const char *tag); int startswith (const char *base, const char *tag);
int endswith (const char *base, const char *tag); int endswith (const char *base, const char *tag);
char *xstrtok(char *line, const char *delims);
#if defined (_WIN32) || defined (__HAIKU__) #if defined (_WIN32) || defined (__HAIKU__)
#define HAVE_DOSSTR_FUNCS #define HAVE_DOSSTR_FUNCS

View file

@ -211,5 +211,15 @@ const char *I_GetSysName(void)
return NULL; return NULL;
} }
void I_SetTextInputMode(boolean active)
{
(void)active;
}
boolean I_GetTextInputMode(void)
{
return false;
}
#include "../sdl/dosstr.c" #include "../sdl/dosstr.c"

View file

@ -229,6 +229,7 @@ static UINT8 cutscene_boostspeed = 0;
char stjrintro[9] = "STJRI000"; char stjrintro[9] = "STJRI000";
static huddrawlist_h luahuddrawlist_title; static huddrawlist_h luahuddrawlist_title;
static huddrawlist_h luahuddrawlist_continue[2];
// //
// This alters the text string cutscene_disptext. // This alters the text string cutscene_disptext.
@ -2335,7 +2336,7 @@ void F_SkyScroll(const char *patchname)
} }
#define LOADTTGFX(arr, name, maxf) \ #define LOADTTGFX(arr, name, maxf) \
lumpnum = W_CheckNumForName(name); \ lumpnum = W_CheckNumForPatchName(name); \
if (lumpnum != LUMPERROR) \ if (lumpnum != LUMPERROR) \
{ \ { \
arr[0] = W_CachePatchName(name, PU_PATCH_LOWPRIORITY); \ arr[0] = W_CachePatchName(name, PU_PATCH_LOWPRIORITY); \
@ -2349,7 +2350,7 @@ else if (strlen(name) <= 6) \
{ \ { \
sprintf(&lumpname[cnt], "%.2hu", (UINT16)(i+1)); \ sprintf(&lumpname[cnt], "%.2hu", (UINT16)(i+1)); \
lumpname[8] = 0; \ lumpname[8] = 0; \
lumpnum = W_CheckNumForName(lumpname); \ lumpnum = W_CheckNumForPatchName(lumpname); \
if (lumpnum != LUMPERROR) \ if (lumpnum != LUMPERROR) \
arr[i] = W_CachePatchName(lumpname, PU_PATCH_LOWPRIORITY); \ arr[i] = W_CachePatchName(lumpname, PU_PATCH_LOWPRIORITY); \
else \ else \
@ -3530,11 +3531,16 @@ void F_TitleDemoTicker(void)
// ========== // ==========
static skin_t *contskins[2]; static skin_t *contskins[2];
static UINT8 cont_spr2[2][6]; static UINT16 cont_spr2[2][6];
static UINT8 *contcolormaps[2]; static UINT8 *contcolormaps[2];
static player_t *contPlayers[2];
static skincolornum_t contColors[2]; // it's possible to change your skincolor in the continue screen, so this is for Lua to identify the skincolor that was used to cache the colormap
static boolean contOverrides[2];
void F_StartContinue(void) void F_StartContinue(void)
{ {
UINT8 i;
I_Assert(!netgame && !multiplayer); I_Assert(!netgame && !multiplayer);
if (continuesInSession && players[consoleplayer].continues <= 0) if (continuesInSession && players[consoleplayer].continues <= 0)
@ -3557,9 +3563,12 @@ void F_StartContinue(void)
S_ChangeMusicInternal("_conti", false); S_ChangeMusicInternal("_conti", false);
S_StopSounds(); S_StopSounds();
contPlayers[0] = &players[consoleplayer];
contskins[0] = skins[players[consoleplayer].skin]; contskins[0] = skins[players[consoleplayer].skin];
cont_spr2[0][0] = P_GetSkinSprite2(contskins[0], SPR2_CNT1, NULL); cont_spr2[0][0] = P_GetSkinSprite2(contskins[0], SPR2_CNT1, NULL);
cont_spr2[0][2] = contskins[0]->contangle & 7; cont_spr2[0][2] = contskins[0]->contangle & 7;
contColors[0] = players[consoleplayer].skincolor;
contcolormaps[0] = R_GetTranslationColormap(players[consoleplayer].skin, players[consoleplayer].skincolor, GTC_CACHE); contcolormaps[0] = R_GetTranslationColormap(players[consoleplayer].skin, players[consoleplayer].skincolor, GTC_CACHE);
cont_spr2[0][4] = contskins[0]->sprites[cont_spr2[0][0]].numframes; cont_spr2[0][4] = contskins[0]->sprites[cont_spr2[0][0]].numframes;
cont_spr2[0][5] = max(1, contskins[0]->contspeed); cont_spr2[0][5] = max(1, contskins[0]->contspeed);
@ -3573,9 +3582,12 @@ void F_StartContinue(void)
else // HACK else // HACK
secondplaya = 1; secondplaya = 1;
contPlayers[1] = &players[secondplaya];
contskins[1] = skins[players[secondplaya].skin]; contskins[1] = skins[players[secondplaya].skin];
cont_spr2[1][0] = P_GetSkinSprite2(contskins[1], SPR2_CNT4, NULL); cont_spr2[1][0] = P_GetSkinSprite2(contskins[1], SPR2_CNT4, NULL);
cont_spr2[1][2] = (contskins[1]->contangle >> 3) & 7; cont_spr2[1][2] = (contskins[1]->contangle >> 3) & 7;
contColors[1] = players[secondplaya].skincolor;
contcolormaps[1] = R_GetTranslationColormap(players[secondplaya].skin, players[secondplaya].skincolor, GTC_CACHE); contcolormaps[1] = R_GetTranslationColormap(players[secondplaya].skin, players[secondplaya].skincolor, GTC_CACHE);
cont_spr2[1][4] = contskins[1]->sprites[cont_spr2[1][0]].numframes; cont_spr2[1][4] = contskins[1]->sprites[cont_spr2[1][0]].numframes;
if (cont_spr2[1][0] == SPR2_CNT4) if (cont_spr2[1][0] == SPR2_CNT4)
@ -3595,6 +3607,58 @@ void F_StartContinue(void)
timetonext = (11*TICRATE)+11; timetonext = (11*TICRATE)+11;
continuetime = 0; continuetime = 0;
// allocate and/or clear Lua continue screen draw lists
for (i = 0; i < 2; i++)
{
if (!LUA_HUD_IsDrawListValid(luahuddrawlist_continue[i]))
{
LUA_HUD_DestroyDrawList(luahuddrawlist_continue[i]);
luahuddrawlist_continue[i] = LUA_HUD_CreateDrawList();
}
LUA_HUD_ClearDrawList(luahuddrawlist_continue[i]);
contOverrides[i] = false;
}
}
static void F_DestroyContinueDrawLists(void)
{
UINT8 i;
for (i = 0; i < 2; i++)
{
LUA_HUD_DestroyDrawList(luahuddrawlist_continue[i]);
luahuddrawlist_continue[i] = NULL;
contOverrides[i] = false;
}
}
static void F_DrawContinueCharacter(INT32 dx, INT32 dy, UINT8 n)
{
spritedef_t *sprdef;
spriteframe_t *sprframe;
patch_t *patch;
if (renderisnewtic)
{
LUA_HUD_ClearDrawList(luahuddrawlist_continue[n]);
contOverrides[n] = LUA_HookCharacterHUD
(
HUD_HOOK(continue), luahuddrawlist_continue[n], contPlayers[n],
dx, dy, contskins[n]->highresscale,
(INT32)(&contskins[n] - skins), cont_spr2[n][0], cont_spr2[n][1], cont_spr2[n][2] + 1, contColors[n], // add 1 to rotation to convert internal angle numbers (0-7) to WAD editor angle numbers (1-8)
imcontinuing ? continuetime : timetonext, imcontinuing
);
}
LUA_HUD_DrawList(luahuddrawlist_continue[n]);
if (contOverrides[n] == true)
return;
sprdef = &contskins[n]->sprites[cont_spr2[n][0]];
sprframe = &sprdef->spriteframes[cont_spr2[n][1]];
patch = W_CachePatchNum(sprframe->lumppat[cont_spr2[n][2]], PU_PATCH_LOWPRIORITY);
V_DrawFixedPatch((dx), (dy), contskins[n]->highresscale, (sprframe->flip & (1<<cont_spr2[n][2])) ? V_FLIP : 0, patch, contcolormaps[n]);
} }
// //
@ -3603,8 +3667,6 @@ void F_StartContinue(void)
// //
void F_ContinueDrawer(void) void F_ContinueDrawer(void)
{ {
spritedef_t *sprdef;
spriteframe_t *sprframe;
patch_t *patch; patch_t *patch;
INT32 i, x = (BASEVIDWIDTH>>1), ncontinues = players[consoleplayer].continues; INT32 i, x = (BASEVIDWIDTH>>1), ncontinues = players[consoleplayer].continues;
char numbuf[9] = "CONTNUM*"; char numbuf[9] = "CONTNUM*";
@ -3649,7 +3711,7 @@ void F_ContinueDrawer(void)
else if (ncontinues > 10) else if (ncontinues > 10)
{ {
if (!(continuetime & 1) || continuetime > 17) if (!(continuetime & 1) || continuetime > 17)
V_DrawContinueIcon(x, 68, 0, players[consoleplayer].skin, players[consoleplayer].skincolor); V_DrawContinueIcon(x, 68, 0, (INT32)(&contskins[0] - skins), contColors[0]);
V_DrawScaledPatch(x+12, 66, 0, stlivex); V_DrawScaledPatch(x+12, 66, 0, stlivex);
V_DrawRightAlignedString(x+38, 64, 0, V_DrawRightAlignedString(x+38, 64, 0,
va("%d",(imcontinuing ? ncontinues-1 : ncontinues))); va("%d",(imcontinuing ? ncontinues-1 : ncontinues)));
@ -3663,7 +3725,7 @@ void F_ContinueDrawer(void)
{ {
if (i == (ncontinues/2) && ((continuetime & 1) || continuetime > 17)) if (i == (ncontinues/2) && ((continuetime & 1) || continuetime > 17))
continue; continue;
V_DrawContinueIcon(x - (i*30), 68, 0, players[consoleplayer].skin, players[consoleplayer].skincolor); V_DrawContinueIcon(x - (i*30), 68, 0, (INT32)(&contskins[0] - skins), contColors[0]);
} }
x = BASEVIDWIDTH>>1; x = BASEVIDWIDTH>>1;
} }
@ -3703,21 +3765,12 @@ void F_ContinueDrawer(void)
else if (lift[0] > TICRATE+5) else if (lift[0] > TICRATE+5)
lift[0] = TICRATE+5; lift[0] = TICRATE+5;
#define drawchar(dx, dy, n) {\
sprdef = &contskins[n]->sprites[cont_spr2[n][0]];\
sprframe = &sprdef->spriteframes[cont_spr2[n][1]];\
patch = W_CachePatchNum(sprframe->lumppat[cont_spr2[n][2]], PU_PATCH_LOWPRIORITY);\
V_DrawFixedPatch((dx), (dy), contskins[n]->highresscale, (sprframe->flip & (1<<cont_spr2[n][2])) ? V_FLIP : 0, patch, contcolormaps[n]);\
}
if (offsy < 0) if (offsy < 0)
drawchar((BASEVIDWIDTH<<(FRACBITS-1))-offsx, ((140-lift[0])<<FRACBITS)-offsy, 0); F_DrawContinueCharacter((BASEVIDWIDTH<<(FRACBITS-1))-offsx, ((140-lift[0])<<FRACBITS)-offsy, 0);
if (contskins[1]) if (contskins[1])
drawchar((BASEVIDWIDTH<<(FRACBITS-1))+offsx, ((140-lift[1])<<FRACBITS)+offsy, 1); F_DrawContinueCharacter((BASEVIDWIDTH<<(FRACBITS-1))+offsx, ((140-lift[1])<<FRACBITS)+offsy, 1);
if (offsy >= 0) if (offsy >= 0)
drawchar((BASEVIDWIDTH<<(FRACBITS-1))-offsx, ((140-lift[0])<<FRACBITS)-offsy, 0); F_DrawContinueCharacter((BASEVIDWIDTH<<(FRACBITS-1))-offsx, ((140-lift[0])<<FRACBITS)-offsy, 0);
#undef drawchar
if (timetonext > (11*TICRATE)) if (timetonext > (11*TICRATE))
V_DrawFadeScreen(31, timetonext-(11*TICRATE)); V_DrawFadeScreen(31, timetonext-(11*TICRATE));
@ -3733,6 +3786,7 @@ void F_ContinueTicker(void)
{ {
if (!(--timetonext)) if (!(--timetonext))
{ {
F_DestroyContinueDrawLists();
Command_ExitGame_f(); Command_ExitGame_f();
return; return;
} }
@ -3742,6 +3796,7 @@ void F_ContinueTicker(void)
{ {
if (++continuetime == 3*TICRATE) if (++continuetime == 3*TICRATE)
{ {
F_DestroyContinueDrawLists();
G_Continue(); G_Continue();
return; return;
} }
@ -4061,7 +4116,7 @@ static void F_GetPageTextGeometry(UINT8 *pagelines, boolean *rightside, INT32 *b
// reuse: // reuse:
// cutnum -> promptnum // cutnum -> promptnum
// scenenum -> pagenum // scenenum -> pagenum
lumpnum_t iconlump = W_CheckNumForName(textprompts[cutnum]->page[scenenum].iconname); lumpnum_t iconlump = W_CheckNumForPatchName(textprompts[cutnum]->page[scenenum].iconname);
*pagelines = textprompts[cutnum]->page[scenenum].lines ? textprompts[cutnum]->page[scenenum].lines : 4; *pagelines = textprompts[cutnum]->page[scenenum].lines ? textprompts[cutnum]->page[scenenum].lines : 4;
*rightside = (iconlump != LUMPERROR && textprompts[cutnum]->page[scenenum].rightside); *rightside = (iconlump != LUMPERROR && textprompts[cutnum]->page[scenenum].rightside);
@ -4387,11 +4442,10 @@ void F_GetPromptPageByNamedTag(const char *tag, INT32 *promptnum, INT32 *pagenum
if (!tag || !tag[0]) if (!tag || !tag[0])
return; return;
strncpy(suffixedtag, tag, 33); strncpy(suffixedtag, tag, sizeof(suffixedtag)-1);
suffixedtag[32] = 0;
if (tutorialmode) if (tutorialmode)
suffixed = F_GetTextPromptTutorialTag(suffixedtag, 33); suffixed = F_GetTextPromptTutorialTag(suffixedtag, sizeof(suffixedtag)-1);
for (*promptnum = 0 + tutorialpromptnum; *promptnum < MAX_PROMPTS; (*promptnum)++) for (*promptnum = 0 + tutorialpromptnum; *promptnum < MAX_PROMPTS; (*promptnum)++)
{ {
@ -4454,7 +4508,7 @@ void F_TextPromptDrawer(void)
if (!promptactive) if (!promptactive)
return; return;
iconlump = W_CheckNumForName(textprompts[cutnum]->page[scenenum].iconname); iconlump = W_CheckNumForPatchName(textprompts[cutnum]->page[scenenum].iconname);
F_GetPageTextGeometry(&pagelines, &rightside, &boxh, &texth, &texty, &namey, &chevrony, &textx, &textr); F_GetPageTextGeometry(&pagelines, &rightside, &boxh, &texth, &texty, &namey, &chevrony, &textx, &textr);
// Draw gfx first // Draw gfx first

View file

@ -96,7 +96,7 @@ typedef enum
extern ttmode_enum ttmode; extern ttmode_enum ttmode;
extern UINT8 ttscale; extern UINT8 ttscale;
// ttmode user vars // ttmode user vars
extern char ttname[9]; extern char ttname[8+1];
extern INT16 ttx; extern INT16 ttx;
extern INT16 tty; extern INT16 tty;
extern INT16 ttloop; extern INT16 ttloop;

View file

@ -444,12 +444,11 @@ filestatus_t filesearch(char *filename, const char *startpath, const UINT8 *want
strcpy(&searchpath[searchpathindex[depthleft]],dent->d_name); strcpy(&searchpath[searchpathindex[depthleft]],dent->d_name);
#if defined(__linux__) || defined(__FreeBSD__) #if defined(__linux__) || defined(__FreeBSD__)
if (dent->d_type == DT_UNKNOWN) if (dent->d_type == DT_UNKNOWN || dent->d_type == DT_LNK)
if (lstat(searchpath,&fsstat) == 0 && S_ISDIR(fsstat.st_mode)) if (stat(searchpath,&fsstat) == 0 && S_ISDIR(fsstat.st_mode))
dent->d_type = DT_DIR; dent->d_type = DT_DIR;
// Linux and FreeBSD has a special field for file type on dirent, so use that to speed up lookups. // Linux and FreeBSD has a special field for file type on dirent, so use that to speed up lookups.
// FIXME: should we also follow symlinks?
if (dent->d_type == DT_DIR && depthleft) if (dent->d_type == DT_DIR && depthleft)
#else #else
if (stat(searchpath,&fsstat) < 0) // do we want to follow symlinks? if not: change it to lstat if (stat(searchpath,&fsstat) < 0) // do we want to follow symlinks? if not: change it to lstat
@ -699,6 +698,15 @@ static void initdirpath(char *dirpath, size_t *dirpathindex, int depthleft)
dirpathindex[depthleft]--; dirpathindex[depthleft]--;
} }
//sortdir by name?
static int lumpnamecompare(const void *A, const void *B)
{
const lumpinfo_t *pA = A;
const lumpinfo_t *pB = B;
return strcmp((pA->fullname), (pB->fullname));
}
lumpinfo_t *getdirectoryfiles(const char *path, UINT16 *nlmp, UINT16 *nfolders) lumpinfo_t *getdirectoryfiles(const char *path, UINT16 *nlmp, UINT16 *nfolders)
{ {
DIR **dirhandle; DIR **dirhandle;
@ -889,6 +897,9 @@ lumpinfo_t *getdirectoryfiles(const char *path, UINT16 *nlmp, UINT16 *nfolders)
free(dirpathindex); free(dirpathindex);
free(dirhandle); free(dirhandle);
//sort files and directories
qsort (lumpinfo, numlumps, sizeof(lumpinfo_t), lumpnamecompare);
(*nlmp) = numlumps; (*nlmp) = numlumps;
return lumpinfo; return lumpinfo;
} }
@ -1179,13 +1190,13 @@ boolean preparefilemenu(boolean samedepth)
size_t i; size_t i;
if (filenamebuf == NULL) if (filenamebuf == NULL)
filenamebuf = calloc(sizeof(char) * MAX_WADPATH, numwadfiles); filenamebuf = calloc(numwadfiles, sizeof(char) * MAX_WADPATH);
for (i = 0; i < numwadfiles; i++) for (i = 0; i < numwadfiles; i++)
{ {
if (!filenamebuf[i][0]) if (!filenamebuf[i][0])
{ {
strncpy(filenamebuf[i], wadfiles[i]->filename, MAX_WADPATH); strncpy(filenamebuf[i], wadfiles[i]->filename, MAX_WADPATH-1);
filenamebuf[i][MAX_WADPATH - 1] = '\0'; filenamebuf[i][MAX_WADPATH - 1] = '\0';
nameonly(filenamebuf[i]); nameonly(filenamebuf[i]);
} }

View file

@ -67,6 +67,8 @@ static UINT8 *metalbuffer = NULL;
static UINT8 *metal_p; static UINT8 *metal_p;
static UINT16 metalversion; static UINT16 metalversion;
consvar_t cv_resyncdemo = CVAR_INIT("resyncdemo", "On", 0, CV_OnOff, NULL);
// extra data stuff (events registered this frame while recording) // extra data stuff (events registered this frame while recording)
static struct { static struct {
UINT8 flags; // EZT flags UINT8 flags; // EZT flags
@ -98,7 +100,7 @@ demoghost *ghosts = NULL;
// DEMO RECORDING // DEMO RECORDING
// //
#define DEMOVERSION 0x0011 #define DEMOVERSION 0x0012
#define DEMOHEADER "\xF0" "SRB2Replay" "\x0F" #define DEMOHEADER "\xF0" "SRB2Replay" "\x0F"
#define DF_GHOST 0x01 // This demo contains ghost data too! #define DF_GHOST 0x01 // This demo contains ghost data too!
@ -183,7 +185,11 @@ void G_ReadDemoTiccmd(ticcmd_t *cmd, INT32 playernum)
if (ziptic & ZT_ANGLE) if (ziptic & ZT_ANGLE)
oldcmd.angleturn = READINT16(demo_p); oldcmd.angleturn = READINT16(demo_p);
if (ziptic & ZT_BUTTONS) if (ziptic & ZT_BUTTONS)
{
oldcmd.buttons = (oldcmd.buttons & (BT_CAMLEFT|BT_CAMRIGHT)) | (READUINT16(demo_p) & ~(BT_CAMLEFT|BT_CAMRIGHT)); oldcmd.buttons = (oldcmd.buttons & (BT_CAMLEFT|BT_CAMRIGHT)) | (READUINT16(demo_p) & ~(BT_CAMLEFT|BT_CAMRIGHT));
if (demoversion < 0x0012 && oldcmd.buttons & BT_SPIN)
oldcmd.buttons |= BT_SHIELD; // Copy BT_SPIN to BT_SHIELD for pre-Shield-button demos
}
if (ziptic & ZT_AIMING) if (ziptic & ZT_AIMING)
oldcmd.aiming = READINT16(demo_p); oldcmd.aiming = READINT16(demo_p);
if (ziptic & ZT_LATENCY) if (ziptic & ZT_LATENCY)
@ -409,7 +415,7 @@ void G_WriteGhostTic(mobj_t *ghost)
{ {
oldghost.sprite2 = ghost->sprite2; oldghost.sprite2 = ghost->sprite2;
ziptic |= GZT_SPR2; ziptic |= GZT_SPR2;
WRITEUINT8(demo_p,oldghost.sprite2); WRITEUINT16(demo_p,oldghost.sprite2);
} }
// Check for sprite set changes // Check for sprite set changes
@ -509,7 +515,7 @@ void G_WriteGhostTic(mobj_t *ghost)
temp = ghost->player->followmobj->z-ghost->z; temp = ghost->player->followmobj->z-ghost->z;
WRITEFIXED(demo_p,temp); WRITEFIXED(demo_p,temp);
if (followtic & FZT_SKIN) if (followtic & FZT_SKIN)
WRITEUINT8(demo_p,ghost->player->followmobj->sprite2); WRITEUINT16(demo_p,ghost->player->followmobj->sprite2);
WRITEUINT16(demo_p,ghost->player->followmobj->sprite); WRITEUINT16(demo_p,ghost->player->followmobj->sprite);
WRITEUINT8(demo_p,(ghost->player->followmobj->frame & FF_FRAMEMASK)); WRITEUINT8(demo_p,(ghost->player->followmobj->frame & FF_FRAMEMASK));
WRITEUINT16(demo_p,ghost->player->followmobj->color); WRITEUINT16(demo_p,ghost->player->followmobj->color);
@ -545,6 +551,9 @@ void G_ConsGhostTic(void)
testmo = players[0].mo; testmo = players[0].mo;
if (P_MobjWasRemoved(testmo))
return; // No valid mobj exists, probably because of unexpected quit
// Grab ghost data. // Grab ghost data.
ziptic = READUINT8(demo_p); ziptic = READUINT8(demo_p);
if (ziptic & GZT_XYZ) if (ziptic & GZT_XYZ)
@ -571,7 +580,7 @@ void G_ConsGhostTic(void)
if (ziptic & GZT_FRAME) if (ziptic & GZT_FRAME)
demo_p++; demo_p++;
if (ziptic & GZT_SPR2) if (ziptic & GZT_SPR2)
demo_p++; demo_p += (demoversion < 0x0011) ? sizeof(UINT8) : sizeof(UINT16);
if (ziptic & GZT_EXTRA) if (ziptic & GZT_EXTRA)
{ // But wait, there's more! { // But wait, there's more!
@ -640,7 +649,7 @@ void G_ConsGhostTic(void)
// momx, momy and momz // momx, momy and momz
demo_p += (demoversion < 0x000e) ? sizeof(INT16) * 3 : sizeof(fixed_t) * 3; demo_p += (demoversion < 0x000e) ? sizeof(INT16) * 3 : sizeof(fixed_t) * 3;
if (followtic & FZT_SKIN) if (followtic & FZT_SKIN)
demo_p++; demo_p += (demoversion < 0x0011) ? sizeof(UINT8) : sizeof(UINT16);
demo_p += sizeof(UINT16); demo_p += sizeof(UINT16);
demo_p++; demo_p++;
demo_p += (demoversion==0x000c) ? 1 : sizeof(UINT16); demo_p += (demoversion==0x000c) ? 1 : sizeof(UINT16);
@ -660,12 +669,15 @@ void G_ConsGhostTic(void)
CONS_Alert(CONS_WARNING, M_GetText("Demo playback has desynced!\n")); CONS_Alert(CONS_WARNING, M_GetText("Demo playback has desynced!\n"));
demosynced = false; demosynced = false;
if (cv_resyncdemo.value)
{
P_UnsetThingPosition(testmo); P_UnsetThingPosition(testmo);
testmo->x = oldghost.x; testmo->x = oldghost.x;
testmo->y = oldghost.y; testmo->y = oldghost.y;
P_SetThingPosition(testmo); P_SetThingPosition(testmo);
testmo->z = oldghost.z; testmo->z = oldghost.z;
} }
}
if (*demo_p == DEMOMARKER) if (*demo_p == DEMOMARKER)
{ {
@ -722,7 +734,7 @@ void G_GhostTicker(void)
if (ziptic & GZT_FRAME) if (ziptic & GZT_FRAME)
g->oldmo.frame = READUINT8(g->p); g->oldmo.frame = READUINT8(g->p);
if (ziptic & GZT_SPR2) if (ziptic & GZT_SPR2)
g->oldmo.sprite2 = READUINT8(g->p); g->oldmo.sprite2 = (g->version < 0x0011) ? READUINT8(g->p) : READUINT16(g->p);
// Update ghost // Update ghost
P_UnsetThingPosition(g->mo); P_UnsetThingPosition(g->mo);
@ -771,7 +783,7 @@ void G_GhostTicker(void)
{ {
g->mo->destscale = READFIXED(g->p); g->mo->destscale = READFIXED(g->p);
if (g->mo->destscale != g->mo->scale) if (g->mo->destscale != g->mo->scale)
P_SetScale(g->mo, g->mo->destscale); P_SetScale(g->mo, g->mo->destscale, false);
} }
if (xziptic & EZT_THOKMASK) if (xziptic & EZT_THOKMASK)
{ // Let's only spawn ONE of these per frame, thanks. { // Let's only spawn ONE of these per frame, thanks.
@ -810,7 +822,7 @@ void G_GhostTicker(void)
mobj->frame = (states[mobjinfo[type].spawnstate].frame & FF_FRAMEMASK) | tr_trans60<<FF_TRANSSHIFT; mobj->frame = (states[mobjinfo[type].spawnstate].frame & FF_FRAMEMASK) | tr_trans60<<FF_TRANSSHIFT;
mobj->color = g->mo->color; mobj->color = g->mo->color;
mobj->skin = g->mo->skin; mobj->skin = g->mo->skin;
P_SetScale(mobj, (mobj->destscale = g->mo->scale)); P_SetScale(mobj, g->mo->scale, true);
if (type == MT_THOK) // spintrail-specific modification for MT_THOK if (type == MT_THOK) // spintrail-specific modification for MT_THOK
{ {
@ -926,7 +938,7 @@ void G_GhostTicker(void)
else else
follow->destscale = g->mo->destscale; follow->destscale = g->mo->destscale;
if (follow->destscale != follow->scale) if (follow->destscale != follow->scale)
P_SetScale(follow, follow->destscale); P_SetScale(follow, follow->destscale, false);
P_UnsetThingPosition(follow); P_UnsetThingPosition(follow);
temp = (g->version < 0x000e) ? READINT16(g->p)<<8 : READFIXED(g->p); temp = (g->version < 0x000e) ? READINT16(g->p)<<8 : READFIXED(g->p);
@ -937,7 +949,7 @@ void G_GhostTicker(void)
follow->z = g->mo->z + temp; follow->z = g->mo->z + temp;
P_SetThingPosition(follow); P_SetThingPosition(follow);
if (followtic & FZT_SKIN) if (followtic & FZT_SKIN)
follow->sprite2 = READUINT8(g->p); follow->sprite2 = (g->version < 0x0011) ? READUINT8(g->p) : READUINT16(g->p);
else else
follow->sprite2 = 0; follow->sprite2 = 0;
follow->sprite = READUINT16(g->p); follow->sprite = READUINT16(g->p);
@ -1052,7 +1064,7 @@ void G_ReadMetalTic(mobj_t *metal)
oldmetal.frame = G_ConvertOldFrameFlags(oldmetal.frame); oldmetal.frame = G_ConvertOldFrameFlags(oldmetal.frame);
} }
if (ziptic & GZT_SPR2) if (ziptic & GZT_SPR2)
oldmetal.sprite2 = READUINT8(metal_p); oldmetal.sprite2 = (metalversion < 0x0011) ? READUINT8(metal_p) : READUINT16(metal_p);
// Set movement, position, and angle // Set movement, position, and angle
// oldmetal contains where you're supposed to be. // oldmetal contains where you're supposed to be.
@ -1079,7 +1091,7 @@ void G_ReadMetalTic(mobj_t *metal)
{ {
metal->destscale = READFIXED(metal_p); metal->destscale = READFIXED(metal_p);
if (metal->destscale != metal->scale) if (metal->destscale != metal->scale)
P_SetScale(metal, metal->destscale); P_SetScale(metal, metal->destscale, false);
} }
if (xziptic & EZT_THOKMASK) if (xziptic & EZT_THOKMASK)
{ // Let's only spawn ONE of these per frame, thanks. { // Let's only spawn ONE of these per frame, thanks.
@ -1117,7 +1129,7 @@ void G_ReadMetalTic(mobj_t *metal)
mobj->angle = metal->angle; mobj->angle = metal->angle;
mobj->color = metal->color; mobj->color = metal->color;
mobj->skin = metal->skin; mobj->skin = metal->skin;
P_SetScale(mobj, (mobj->destscale = metal->scale)); P_SetScale(mobj, metal->scale, true);
if (type == MT_THOK) // spintrail-specific modification for MT_THOK if (type == MT_THOK) // spintrail-specific modification for MT_THOK
{ {
@ -1184,7 +1196,7 @@ void G_ReadMetalTic(mobj_t *metal)
else else
follow->destscale = metal->destscale; follow->destscale = metal->destscale;
if (follow->destscale != follow->scale) if (follow->destscale != follow->scale)
P_SetScale(follow, follow->destscale); P_SetScale(follow, follow->destscale, false);
P_UnsetThingPosition(follow); P_UnsetThingPosition(follow);
temp = (metalversion < 0x000e) ? READINT16(metal_p)<<8 : READFIXED(metal_p); temp = (metalversion < 0x000e) ? READINT16(metal_p)<<8 : READFIXED(metal_p);
@ -1195,7 +1207,7 @@ void G_ReadMetalTic(mobj_t *metal)
follow->z = metal->z + temp; follow->z = metal->z + temp;
P_SetThingPosition(follow); P_SetThingPosition(follow);
if (followtic & FZT_SKIN) if (followtic & FZT_SKIN)
follow->sprite2 = READUINT8(metal_p); follow->sprite2 = (metalversion < 0x0011) ? READUINT8(metal_p) : READUINT16(metal_p);
else else
follow->sprite2 = 0; follow->sprite2 = 0;
follow->sprite = READUINT16(metal_p); follow->sprite = READUINT16(metal_p);
@ -1203,7 +1215,7 @@ void G_ReadMetalTic(mobj_t *metal)
if (metalversion < 0x000f) if (metalversion < 0x000f)
follow->frame = G_ConvertOldFrameFlags(follow->frame); follow->frame = G_ConvertOldFrameFlags(follow->frame);
follow->angle = metal->angle; follow->angle = metal->angle;
follow->color = (metalversion==0x000c) ? READUINT8(metal_p) : READUINT16(metal_p); follow->color = (metalversion == 0x000c) ? READUINT8(metal_p) : READUINT16(metal_p);
if (!(followtic & FZT_SPAWNED)) if (!(followtic & FZT_SPAWNED))
{ {
@ -1304,7 +1316,7 @@ void G_WriteMetalTic(mobj_t *metal)
{ {
oldmetal.sprite2 = metal->sprite2; oldmetal.sprite2 = metal->sprite2;
ziptic |= GZT_SPR2; ziptic |= GZT_SPR2;
WRITEUINT8(demo_p,oldmetal.sprite2); WRITEUINT16(demo_p,oldmetal.sprite2);
} }
// Check for sprite set changes // Check for sprite set changes
@ -1379,7 +1391,7 @@ void G_WriteMetalTic(mobj_t *metal)
temp = metal->player->followmobj->z-metal->z; temp = metal->player->followmobj->z-metal->z;
WRITEFIXED(demo_p,temp); WRITEFIXED(demo_p,temp);
if (followtic & FZT_SKIN) if (followtic & FZT_SKIN)
WRITEUINT8(demo_p,metal->player->followmobj->sprite2); WRITEUINT16(demo_p,metal->player->followmobj->sprite2);
WRITEUINT16(demo_p,metal->player->followmobj->sprite); WRITEUINT16(demo_p,metal->player->followmobj->sprite);
WRITEUINT32(demo_p,metal->player->followmobj->frame); // NOT & FF_FRAMEMASK here, so 32 bits WRITEUINT32(demo_p,metal->player->followmobj->frame); // NOT & FF_FRAMEMASK here, so 32 bits
WRITEUINT16(demo_p,metal->player->followmobj->color); WRITEUINT16(demo_p,metal->player->followmobj->color);
@ -1650,7 +1662,7 @@ static void G_LoadDemoExtraFiles(UINT8 **pp, UINT16 this_demo_version)
UINT16 totalfiles; UINT16 totalfiles;
char filename[MAX_WADPATH]; char filename[MAX_WADPATH];
UINT8 md5sum[16]; UINT8 md5sum[16];
filestatus_t ncs; filestatus_t ncs = FS_NOTFOUND;
boolean toomany = false; boolean toomany = false;
boolean alreadyloaded; boolean alreadyloaded;
UINT16 i, j; UINT16 i, j;
@ -2603,10 +2615,10 @@ void G_AddGhost(char *defdemoname)
} }
gh->oldmo.color = gh->mo->color; gh->oldmo.color = gh->mo->color;
gh->mo->state = states+S_PLAY_STND; gh->mo->state = &states[S_PLAY_STND];
gh->mo->sprite = gh->mo->state->sprite; gh->mo->sprite = gh->mo->state->sprite;
gh->mo->sprite2 = (gh->mo->state->frame & FF_FRAMEMASK); gh->mo->sprite2 = P_GetStateSprite2(gh->mo->state);
//gh->mo->frame = tr_trans30<<FF_TRANSSHIFT; gh->mo->frame = (gh->mo->state->frame & ~FF_FRAMEMASK) | P_GetSprite2StateFrame(gh->mo->state);
gh->mo->flags2 |= MF2_DONTDRAW; gh->mo->flags2 |= MF2_DONTDRAW;
gh->fadein = (9-3)*6; // fade from invisible to trans30 over as close to 35 tics as possible gh->fadein = (9-3)*6; // fade from invisible to trans30 over as close to 35 tics as possible
gh->mo->tics = -1; gh->mo->tics = -1;

View file

@ -35,6 +35,7 @@ typedef enum
} demo_file_override_e; } demo_file_override_e;
extern demo_file_override_e demofileoverride; extern demo_file_override_e demofileoverride;
extern consvar_t cv_resyncdemo;
// Quit after playing a demo from cmdline. // Quit after playing a demo from cmdline.
extern boolean singledemo; extern boolean singledemo;

View file

@ -409,6 +409,7 @@ consvar_t cv_lookaxis = CVAR_INIT ("joyaxis_look", "X-Rudder-", CV_SAVE, joyaxis
consvar_t cv_turnaxis = CVAR_INIT ("joyaxis_turn", "Z-Axis", CV_SAVE, joyaxis_cons_t, NULL); consvar_t cv_turnaxis = CVAR_INIT ("joyaxis_turn", "Z-Axis", CV_SAVE, joyaxis_cons_t, NULL);
consvar_t cv_jumpaxis = CVAR_INIT ("joyaxis_jump", "None", CV_SAVE, joyaxis_cons_t, NULL); consvar_t cv_jumpaxis = CVAR_INIT ("joyaxis_jump", "None", CV_SAVE, joyaxis_cons_t, NULL);
consvar_t cv_spinaxis = CVAR_INIT ("joyaxis_spin", "None", CV_SAVE, joyaxis_cons_t, NULL); consvar_t cv_spinaxis = CVAR_INIT ("joyaxis_spin", "None", CV_SAVE, joyaxis_cons_t, NULL);
consvar_t cv_shieldaxis = CVAR_INIT ("joyaxis_shield", "None", CV_SAVE, joyaxis_cons_t, NULL);
consvar_t cv_fireaxis = CVAR_INIT ("joyaxis_fire", "Z-Rudder", CV_SAVE, joyaxis_cons_t, NULL); consvar_t cv_fireaxis = CVAR_INIT ("joyaxis_fire", "Z-Rudder", CV_SAVE, joyaxis_cons_t, NULL);
consvar_t cv_firenaxis = CVAR_INIT ("joyaxis_firenormal", "Z-Axis", CV_SAVE, joyaxis_cons_t, NULL); consvar_t cv_firenaxis = CVAR_INIT ("joyaxis_firenormal", "Z-Axis", CV_SAVE, joyaxis_cons_t, NULL);
consvar_t cv_deadzone = CVAR_INIT ("joy_deadzone", "0.125", CV_FLOAT|CV_SAVE, zerotoone_cons_t, NULL); consvar_t cv_deadzone = CVAR_INIT ("joy_deadzone", "0.125", CV_FLOAT|CV_SAVE, zerotoone_cons_t, NULL);
@ -420,6 +421,7 @@ consvar_t cv_lookaxis2 = CVAR_INIT ("joyaxis2_look", "X-Rudder-", CV_SAVE, joyax
consvar_t cv_turnaxis2 = CVAR_INIT ("joyaxis2_turn", "Z-Axis", CV_SAVE, joyaxis_cons_t, NULL); consvar_t cv_turnaxis2 = CVAR_INIT ("joyaxis2_turn", "Z-Axis", CV_SAVE, joyaxis_cons_t, NULL);
consvar_t cv_jumpaxis2 = CVAR_INIT ("joyaxis2_jump", "None", CV_SAVE, joyaxis_cons_t, NULL); consvar_t cv_jumpaxis2 = CVAR_INIT ("joyaxis2_jump", "None", CV_SAVE, joyaxis_cons_t, NULL);
consvar_t cv_spinaxis2 = CVAR_INIT ("joyaxis2_spin", "None", CV_SAVE, joyaxis_cons_t, NULL); consvar_t cv_spinaxis2 = CVAR_INIT ("joyaxis2_spin", "None", CV_SAVE, joyaxis_cons_t, NULL);
consvar_t cv_shieldaxis2 = CVAR_INIT ("joyaxis2_shield", "None", CV_SAVE, joyaxis_cons_t, NULL);
consvar_t cv_fireaxis2 = CVAR_INIT ("joyaxis2_fire", "Z-Rudder", CV_SAVE, joyaxis_cons_t, NULL); consvar_t cv_fireaxis2 = CVAR_INIT ("joyaxis2_fire", "Z-Rudder", CV_SAVE, joyaxis_cons_t, NULL);
consvar_t cv_firenaxis2 = CVAR_INIT ("joyaxis2_firenormal", "Z-Axis", CV_SAVE, joyaxis_cons_t, NULL); consvar_t cv_firenaxis2 = CVAR_INIT ("joyaxis2_firenormal", "Z-Axis", CV_SAVE, joyaxis_cons_t, NULL);
consvar_t cv_deadzone2 = CVAR_INIT ("joy_deadzone2", "0.125", CV_FLOAT|CV_SAVE, zerotoone_cons_t, NULL); consvar_t cv_deadzone2 = CVAR_INIT ("joy_deadzone2", "0.125", CV_FLOAT|CV_SAVE, zerotoone_cons_t, NULL);
@ -894,6 +896,9 @@ INT32 JoyAxis(joyaxis_e axissel)
case JA_SPIN: case JA_SPIN:
axisval = cv_spinaxis.value; axisval = cv_spinaxis.value;
break; break;
case JA_SHIELD:
axisval = cv_shieldaxis.value;
break;
case JA_FIRE: case JA_FIRE:
axisval = cv_fireaxis.value; axisval = cv_fireaxis.value;
break; break;
@ -967,6 +972,9 @@ INT32 Joy2Axis(joyaxis_e axissel)
case JA_SPIN: case JA_SPIN:
axisval = cv_spinaxis2.value; axisval = cv_spinaxis2.value;
break; break;
case JA_SHIELD:
axisval = cv_shieldaxis2.value;
break;
case JA_FIRE: case JA_FIRE:
axisval = cv_fireaxis2.value; axisval = cv_fireaxis2.value;
break; break;
@ -1334,8 +1342,8 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer)
if (PLAYERINPUTDOWN(ssplayer, GC_WEAPONPREV)) if (PLAYERINPUTDOWN(ssplayer, GC_WEAPONPREV))
cmd->buttons |= BT_WEAPONPREV; // Previous Weapon cmd->buttons |= BT_WEAPONPREV; // Previous Weapon
#if NUM_WEAPONS > 10 #if NUM_WEAPONS > 7
"Add extra inputs to g_input.h/gamecontrols_e" "Add extra inputs to g_input.h/gamecontrols_e, and fix conflicts in d_ticcmd.h/ticcmd_t/buttons"
#endif #endif
//use the three avaliable bits to determine the weapon. //use the three avaliable bits to determine the weapon.
cmd->buttons &= ~BT_WEAPONMASK; cmd->buttons &= ~BT_WEAPONMASK;
@ -1361,7 +1369,8 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer)
cmd->buttons |= BT_TOSSFLAG; cmd->buttons |= BT_TOSSFLAG;
// Shield button // Shield button
if (PLAYERINPUTDOWN(ssplayer, GC_SHIELD)) axis = PlayerJoyAxis(ssplayer, JA_SHIELD);
if (PLAYERINPUTDOWN(ssplayer, GC_SHIELD) || (usejoystick && axis > 0))
cmd->buttons |= BT_SHIELD; cmd->buttons |= BT_SHIELD;
// Lua scriptable buttons // Lua scriptable buttons
@ -1377,6 +1386,13 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer)
if (PLAYERINPUTDOWN(ssplayer, GC_SPIN) || (usejoystick && axis > 0)) if (PLAYERINPUTDOWN(ssplayer, GC_SPIN) || (usejoystick && axis > 0))
cmd->buttons |= BT_SPIN; cmd->buttons |= BT_SPIN;
if (gamestate != GS_LEVEL) // not in a level, don't build anything else
{
cmd->angleturn = ticcmd_oldangleturn[forplayer];
cmd->aiming = G_ClipAimingPitch(myaiming);
return;
}
// Centerview can be a toggle in simple mode! // Centerview can be a toggle in simple mode!
{ {
static boolean last_centerviewdown[2], centerviewhold[2]; // detect taps for toggle behavior static boolean last_centerviewdown[2], centerviewhold[2]; // detect taps for toggle behavior
@ -1411,7 +1427,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer)
ticcmd_centerviewdown[forplayer] = true; ticcmd_centerviewdown[forplayer] = true;
} }
else if (ticcmd_centerviewdown[forplayer]) else if (ticcmd_centerviewdown[forplayer] || (leveltime < 5))
{ {
if (controlstyle == CS_SIMPLE) if (controlstyle == CS_SIMPLE)
{ {
@ -1426,6 +1442,9 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer)
{ {
if ( if (
P_MobjWasRemoved(ticcmd_ztargetfocus[forplayer]) || P_MobjWasRemoved(ticcmd_ztargetfocus[forplayer]) ||
(leveltime < 5) ||
(player->playerstate != PST_LIVE) ||
player->exiting ||
!ticcmd_ztargetfocus[forplayer]->health || !ticcmd_ztargetfocus[forplayer]->health ||
(ticcmd_ztargetfocus[forplayer]->type == MT_EGGMOBILE3 && !ticcmd_ztargetfocus[forplayer]->movecount) // Sea Egg is moving around underground and shouldn't be tracked (ticcmd_ztargetfocus[forplayer]->type == MT_EGGMOBILE3 && !ticcmd_ztargetfocus[forplayer]->movecount) // Sea Egg is moving around underground and shouldn't be tracked
) )
@ -1457,7 +1476,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer)
P_SetTarget(&newtarget->target, ticcmd_ztargetfocus[forplayer]); P_SetTarget(&newtarget->target, ticcmd_ztargetfocus[forplayer]);
newtarget->drawonlyforplayer = player; // Hide it from the other player in splitscreen, and yourself when spectating newtarget->drawonlyforplayer = player; // Hide it from the other player in splitscreen, and yourself when spectating
if (player->mo && P_AproxDistance( if (player->mo && R_PointToDist2(0, 0,
player->mo->x - ticcmd_ztargetfocus[forplayer]->x, player->mo->x - ticcmd_ztargetfocus[forplayer]->x,
player->mo->y - ticcmd_ztargetfocus[forplayer]->y player->mo->y - ticcmd_ztargetfocus[forplayer]->y
) > 50*player->mo->scale) ) > 50*player->mo->scale)
@ -1705,7 +1724,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer)
// At this point, cmd doesn't contain the final angle yet, // At this point, cmd doesn't contain the final angle yet,
// So we need to temporarily transform it so Lua scripters // So we need to temporarily transform it so Lua scripters
// don't need to handle it differently than in other hooks. // don't need to handle it differently than in other hooks.
if (addedtogame && gamestate == GS_LEVEL) if (addedtogame)
{ {
INT16 extra = ticcmd_oldangleturn[forplayer] - player->oldrelangleturn; INT16 extra = ticcmd_oldangleturn[forplayer] - player->oldrelangleturn;
INT16 origangle = cmd->angleturn; INT16 origangle = cmd->angleturn;
@ -5398,7 +5417,7 @@ void G_FreeMapSearch(mapsearchfreq_t *freq, INT32 freqc)
INT32 G_FindMapByNameOrCode(const char *mapname, char **realmapnamep) INT32 G_FindMapByNameOrCode(const char *mapname, char **realmapnamep)
{ {
boolean usemapcode = false; boolean usemapcode = false;
INT32 newmapnum; INT32 newmapnum = -1;
size_t mapnamelen = strlen(mapname); size_t mapnamelen = strlen(mapname);
char *p; char *p;

View file

@ -71,8 +71,8 @@ typedef enum {
#define P_ControlStyle(player) ((((player)->pflags & PF_ANALOGMODE) ? CS_LMAOGALOG : 0) | (((player)->pflags & PF_DIRECTIONCHAR) ? CS_STANDARD : 0)) #define P_ControlStyle(player) ((((player)->pflags & PF_ANALOGMODE) ? CS_LMAOGALOG : 0) | (((player)->pflags & PF_DIRECTIONCHAR) ? CS_STANDARD : 0))
extern consvar_t cv_autobrake, cv_autobrake2; extern consvar_t cv_autobrake, cv_autobrake2;
extern consvar_t cv_sideaxis,cv_turnaxis,cv_moveaxis,cv_lookaxis,cv_jumpaxis,cv_spinaxis,cv_fireaxis,cv_firenaxis,cv_deadzone,cv_digitaldeadzone; extern consvar_t cv_sideaxis, cv_turnaxis, cv_moveaxis, cv_lookaxis, cv_jumpaxis, cv_spinaxis, cv_shieldaxis, cv_fireaxis, cv_firenaxis, cv_deadzone, cv_digitaldeadzone;
extern consvar_t cv_sideaxis2,cv_turnaxis2,cv_moveaxis2,cv_lookaxis2,cv_jumpaxis2,cv_spinaxis2,cv_fireaxis2,cv_firenaxis2,cv_deadzone2,cv_digitaldeadzone2; extern consvar_t cv_sideaxis2,cv_turnaxis2,cv_moveaxis2,cv_lookaxis2,cv_jumpaxis2,cv_spinaxis2,cv_shieldaxis2,cv_fireaxis2,cv_firenaxis2,cv_deadzone2,cv_digitaldeadzone2;
extern consvar_t cv_ghost_bestscore, cv_ghost_besttime, cv_ghost_bestrings, cv_ghost_last, cv_ghost_guest; extern consvar_t cv_ghost_bestscore, cv_ghost_besttime, cv_ghost_bestrings, cv_ghost_last, cv_ghost_guest;
// hi here's some new controls // hi here's some new controls
@ -100,6 +100,7 @@ typedef enum
JA_JUMP = JA_DIGITAL, JA_JUMP = JA_DIGITAL,
JA_SPIN, JA_SPIN,
JA_SHIELD,
JA_FIRE, JA_FIRE,
JA_FIRENORMAL, JA_FIRENORMAL,
} joyaxis_e; } joyaxis_e;

View file

@ -743,34 +743,34 @@ void G_DefineDefaultControls(void)
// Gamepad controls -- same for both schemes // Gamepad controls -- same for both schemes
gamecontroldefault[i][GC_JUMP ][1] = KEY_JOY1+0; // A gamecontroldefault[i][GC_JUMP ][1] = KEY_JOY1+0; // A
gamecontroldefault[i][GC_SPIN ][1] = KEY_JOY1+2; // X gamecontroldefault[i][GC_SPIN ][1] = KEY_JOY1+2; // X
gamecontroldefault[i][GC_CUSTOM1 ][1] = KEY_JOY1+1; // B gamecontroldefault[i][GC_SHIELD ][1] = KEY_JOY1+1; // B
gamecontroldefault[i][GC_CUSTOM2 ][1] = KEY_JOY1+3; // Y gamecontroldefault[i][GC_CUSTOM1 ][1] = KEY_JOY1+3; // Y
gamecontroldefault[i][GC_CUSTOM3 ][1] = KEY_JOY1+8; // Left Stick gamecontroldefault[i][GC_CUSTOM2 ][1] = KEY_JOY1+4; // LB
gamecontroldefault[i][GC_SHIELD ][1] = KEY_JOY1+4; // LB
gamecontroldefault[i][GC_CENTERVIEW ][1] = KEY_JOY1+5; // RB gamecontroldefault[i][GC_CENTERVIEW ][1] = KEY_JOY1+5; // RB
gamecontroldefault[i][GC_CUSTOM3 ][1] = KEY_JOY1+8; // Left Stick
gamecontroldefault[i][GC_CAMTOGGLE ][1] = KEY_JOY1+9; // Right Stick
gamecontroldefault[i][GC_SCORES ][1] = KEY_JOY1+6; // Back gamecontroldefault[i][GC_SCORES ][1] = KEY_JOY1+6; // Back
gamecontroldefault[i][GC_SYSTEMMENU ][0] = KEY_JOY1+7; // Start gamecontroldefault[i][GC_SYSTEMMENU ][0] = KEY_JOY1+7; // Start
gamecontroldefault[i][GC_VIEWPOINTNEXT][1] = KEY_HAT1+0; // D-Pad Up
gamecontroldefault[i][GC_TOSSFLAG ][1] = KEY_HAT1+1; // D-Pad Down
gamecontroldefault[i][GC_WEAPONPREV ][1] = KEY_HAT1+2; // D-Pad Left gamecontroldefault[i][GC_WEAPONPREV ][1] = KEY_HAT1+2; // D-Pad Left
gamecontroldefault[i][GC_WEAPONNEXT ][1] = KEY_HAT1+3; // D-Pad Right gamecontroldefault[i][GC_WEAPONNEXT ][1] = KEY_HAT1+3; // D-Pad Right
gamecontroldefault[i][GC_VIEWPOINTNEXT][1] = KEY_JOY1+9; // Right Stick
gamecontroldefault[i][GC_TOSSFLAG ][1] = KEY_HAT1+0; // D-Pad Up
gamecontroldefault[i][GC_CAMTOGGLE ][1] = KEY_HAT1+1; // D-Pad Down
// Second player controls only have joypad defaults // Second player controls only have joypad defaults
gamecontrolbisdefault[i][GC_JUMP ][1] = KEY_2JOY1+0; // A gamecontrolbisdefault[i][GC_JUMP ][1] = KEY_2JOY1+0; // A
gamecontrolbisdefault[i][GC_SPIN ][1] = KEY_2JOY1+2; // X gamecontrolbisdefault[i][GC_SPIN ][1] = KEY_2JOY1+2; // X
gamecontrolbisdefault[i][GC_CUSTOM1 ][1] = KEY_2JOY1+1; // B gamecontrolbisdefault[i][GC_SHIELD ][1] = KEY_2JOY1+1; // B
gamecontrolbisdefault[i][GC_CUSTOM2 ][1] = KEY_2JOY1+3; // Y gamecontrolbisdefault[i][GC_CUSTOM1 ][1] = KEY_2JOY1+3; // Y
gamecontrolbisdefault[i][GC_CUSTOM3 ][1] = KEY_2JOY1+8; // Left Stick gamecontrolbisdefault[i][GC_CUSTOM2 ][1] = KEY_2JOY1+4; // LB
gamecontrolbisdefault[i][GC_SHIELD ][1] = KEY_2JOY1+4; // LB
gamecontrolbisdefault[i][GC_CENTERVIEW ][1] = KEY_2JOY1+5; // RB gamecontrolbisdefault[i][GC_CENTERVIEW ][1] = KEY_2JOY1+5; // RB
gamecontrolbisdefault[i][GC_CUSTOM3 ][1] = KEY_2JOY1+8; // Left Stick
gamecontrolbisdefault[i][GC_CAMTOGGLE ][1] = KEY_2JOY1+9; // Right Stick
//gamecontrolbisdefault[i][GC_SCORES ][1] = KEY_2JOY1+6; // Back //gamecontrolbisdefault[i][GC_SCORES ][1] = KEY_2JOY1+6; // Back
//gamecontrolbisdefault[i][GC_SYSTEMMENU ][0] = KEY_2JOY1+7; // Start //gamecontrolbisdefault[i][GC_SYSTEMMENU ][0] = KEY_2JOY1+7; // Start
gamecontrolbisdefault[i][GC_VIEWPOINTNEXT][1] = KEY_2HAT1+0; // D-Pad Up
gamecontrolbisdefault[i][GC_TOSSFLAG ][1] = KEY_2HAT1+1; // D-Pad Down
gamecontrolbisdefault[i][GC_WEAPONPREV ][1] = KEY_2HAT1+2; // D-Pad Left gamecontrolbisdefault[i][GC_WEAPONPREV ][1] = KEY_2HAT1+2; // D-Pad Left
gamecontrolbisdefault[i][GC_WEAPONNEXT ][1] = KEY_2HAT1+3; // D-Pad Right gamecontrolbisdefault[i][GC_WEAPONNEXT ][1] = KEY_2HAT1+3; // D-Pad Right
gamecontrolbisdefault[i][GC_VIEWPOINTNEXT][1] = KEY_2JOY1+9; // Right Stick
gamecontrolbisdefault[i][GC_TOSSFLAG ][1] = KEY_2HAT1+0; // D-Pad Up
gamecontrolbisdefault[i][GC_CAMTOGGLE ][1] = KEY_2HAT1+1; // D-Pad Down
} }
} }
@ -1002,7 +1002,6 @@ static void setcontrol(INT32 (*gc)[2])
// TODO: 2.3: Delete the "use" alias // TODO: 2.3: Delete the "use" alias
namectrl = (stricmp(COM_Argv(1), "use")) ? COM_Argv(1) : "spin"; namectrl = (stricmp(COM_Argv(1), "use")) ? COM_Argv(1) : "spin";
for (numctrl = 0; numctrl < NUM_GAMECONTROLS && stricmp(namectrl, gamecontrolname[numctrl]); for (numctrl = 0; numctrl < NUM_GAMECONTROLS && stricmp(namectrl, gamecontrolname[numctrl]);
numctrl++) numctrl++)
; ;

View file

@ -98,13 +98,11 @@ static void HWR_DrawColumnInCache(const column_t *patchcol, UINT8 *block, GLMipm
if (position + count >= pblockheight) if (position + count >= pblockheight)
count = pblockheight - position; count = pblockheight - position;
dest = block + (position*blockmodulo); for (dest = block + (position*blockmodulo); count > 0; count--, dest += blockmodulo, yfrac += yfracstep)
while (count > 0)
{ {
count--;
texel = source[yfrac>>FRACBITS]; texel = source[yfrac>>FRACBITS];
alpha = 0xFF; alpha = 0xFF;
// Make pixel transparent if chroma keyed // Make pixel transparent if chroma keyed
if ((mipmap->flags & TF_CHROMAKEYED) && (texel == HWR_PATCHES_CHROMAKEY_COLORINDEX)) if ((mipmap->flags & TF_CHROMAKEYED) && (texel == HWR_PATCHES_CHROMAKEY_COLORINDEX))
alpha = 0x00; alpha = 0x00;
@ -115,11 +113,20 @@ static void HWR_DrawColumnInCache(const column_t *patchcol, UINT8 *block, GLMipm
switch (bpp) switch (bpp)
{ {
case 2: case 2:
{
texelu16 = *((UINT16*)dest);
if ((originPatch != NULL) && (originPatch->style != AST_COPY)) if ((originPatch != NULL) && (originPatch->style != AST_COPY))
texel = ASTBlendPaletteIndexes(*(dest+1), texel, originPatch->style, originPatch->alpha); {
if (originPatch->style == AST_TRANSLUCENT && originPatch->alpha < ASTTextureBlendingThreshold[0])
continue;
if (!(texelu16 & 0xFF00) && originPatch->alpha <= ASTTextureBlendingThreshold[1])
continue;
texel = ASTBlendPaletteIndexes(texelu16 & 0xFF, texel, originPatch->style, originPatch->alpha);
}
texelu16 = (UINT16)((alpha<<8) | texel); texelu16 = (UINT16)((alpha<<8) | texel);
memcpy(dest, &texelu16, sizeof(UINT16)); memcpy(dest, &texelu16, sizeof(UINT16));
break; break;
}
case 3: case 3:
colortemp = palette[texel]; colortemp = palette[texel];
if ((originPatch != NULL) && (originPatch->style != AST_COPY)) if ((originPatch != NULL) && (originPatch->style != AST_COPY))
@ -149,9 +156,6 @@ static void HWR_DrawColumnInCache(const column_t *patchcol, UINT8 *block, GLMipm
*dest = texel; *dest = texel;
break; break;
} }
dest += blockmodulo;
yfrac += yfracstep;
} }
} }
} }
@ -202,13 +206,11 @@ static void HWR_DrawFlippedColumnInCache(const column_t *patchcol, UINT8 *block,
if (position + count >= pblockheight) if (position + count >= pblockheight)
count = pblockheight - position; count = pblockheight - position;
dest = block + (position*blockmodulo); for (dest = block + (position*blockmodulo); count > 0; count--, dest += blockmodulo, yfrac -= yfracstep)
while (count > 0)
{ {
count--;
texel = source[yfrac>>FRACBITS]; texel = source[yfrac>>FRACBITS];
alpha = 0xFF; alpha = 0xFF;
// Make pixel transparent if chroma keyed // Make pixel transparent if chroma keyed
if ((mipmap->flags & TF_CHROMAKEYED) && (texel == HWR_PATCHES_CHROMAKEY_COLORINDEX)) if ((mipmap->flags & TF_CHROMAKEYED) && (texel == HWR_PATCHES_CHROMAKEY_COLORINDEX))
alpha = 0x00; alpha = 0x00;
@ -219,8 +221,15 @@ static void HWR_DrawFlippedColumnInCache(const column_t *patchcol, UINT8 *block,
switch (bpp) switch (bpp)
{ {
case 2: case 2:
texelu16 = *((UINT16*)dest);
if ((originPatch != NULL) && (originPatch->style != AST_COPY)) if ((originPatch != NULL) && (originPatch->style != AST_COPY))
texel = ASTBlendPaletteIndexes(*(dest+1), texel, originPatch->style, originPatch->alpha); {
if (originPatch->style == AST_TRANSLUCENT && originPatch->alpha < ASTTextureBlendingThreshold[0])
continue;
if (!(texelu16 & 0xFF00) && originPatch->alpha <= ASTTextureBlendingThreshold[1])
continue;
texel = ASTBlendPaletteIndexes(texelu16 & 0xFF, texel, originPatch->style, originPatch->alpha);
}
texelu16 = (UINT16)((alpha<<8) | texel); texelu16 = (UINT16)((alpha<<8) | texel);
memcpy(dest, &texelu16, sizeof(UINT16)); memcpy(dest, &texelu16, sizeof(UINT16));
break; break;
@ -253,9 +262,6 @@ static void HWR_DrawFlippedColumnInCache(const column_t *patchcol, UINT8 *block,
*dest = texel; *dest = texel;
break; break;
} }
dest += blockmodulo;
yfrac -= yfracstep;
} }
} }
} }
@ -433,7 +439,7 @@ static UINT8 *MakeBlock(GLMipmap_t *grMipmap)
// Create a composite texture from patches, adapt the texture size to a power of 2 // Create a composite texture from patches, adapt the texture size to a power of 2
// height and width for the hardware texture cache. // height and width for the hardware texture cache.
// //
static void HWR_GenerateTexture(INT32 texnum, GLMapTexture_t *grtex) static void HWR_GenerateTexture(INT32 texnum, GLMapTexture_t *grtex, GLMipmap_t *mipmap)
{ {
UINT8 *block; UINT8 *block;
texture_t *texture; texture_t *texture;
@ -441,56 +447,13 @@ static void HWR_GenerateTexture(INT32 texnum, GLMapTexture_t *grtex)
INT32 blockwidth, blockheight, blocksize; INT32 blockwidth, blockheight, blocksize;
INT32 i; INT32 i;
boolean skyspecial = false; //poor hack for Legacy large skies..
RGBA_t *palette;
palette = HWR_GetTexturePalette();
texture = textures[texnum]; texture = textures[texnum];
// hack the Legacy skies..
if (texture->name[0] == 'S' &&
texture->name[1] == 'K' &&
texture->name[2] == 'Y' &&
(texture->name[4] == 0 ||
texture->name[5] == 0)
)
{
skyspecial = true;
grtex->mipmap.flags = TF_WRAPXY; // don't use the chromakey for sky
}
else
grtex->mipmap.flags = TF_CHROMAKEYED | TF_WRAPXY;
grtex->mipmap.width = (UINT16)texture->width;
grtex->mipmap.height = (UINT16)texture->height;
if (skyspecial)
grtex->mipmap.format = GL_TEXFMT_RGBA; // that skyspecial code below assumes this format ...
else
grtex->mipmap.format = textureformat;
blockwidth = texture->width; blockwidth = texture->width;
blockheight = texture->height; blockheight = texture->height;
blocksize = (blockwidth * blockheight); blocksize = blockwidth * blockheight;
block = MakeBlock(&grtex->mipmap); block = MakeBlock(mipmap);
if (skyspecial) //Hurdler: not efficient, but better than holes in the sky (and it's done only at level loading)
{
INT32 j;
RGBA_t col;
col = palette[HWR_PATCHES_CHROMAKEY_COLORINDEX];
for (j = 0; j < blockheight; j++)
{
for (i = 0; i < blockwidth; i++)
{
block[4*(j*blockwidth+i)+0] = col.s.red;
block[4*(j*blockwidth+i)+1] = col.s.green;
block[4*(j*blockwidth+i)+2] = col.s.blue;
block[4*(j*blockwidth+i)+3] = 0xff;
}
}
}
// Composite the columns together. // Composite the columns together.
for (i = 0, patch = texture->patches; i < texture->patchcount; i++, patch++) for (i = 0, patch = texture->patches; i < texture->patchcount; i++, patch++)
@ -520,19 +483,19 @@ static void HWR_GenerateTexture(INT32 texnum, GLMapTexture_t *grtex)
realpatch = W_CachePatchNumPwad(wadnum, lumpnum, PU_PATCH); realpatch = W_CachePatchNumPwad(wadnum, lumpnum, PU_PATCH);
} }
HWR_DrawTexturePatchInCache(&grtex->mipmap, blockwidth, blockheight, texture, patch, realpatch); HWR_DrawTexturePatchInCache(mipmap, blockwidth, blockheight, texture, patch, realpatch);
if (free_patch) if (free_patch)
Patch_Free(realpatch); Patch_Free(realpatch);
} }
//Hurdler: not efficient at all but I don't remember exactly how HWR_DrawPatchInCache works :( //Hurdler: not efficient at all but I don't remember exactly how HWR_DrawPatchInCache works :(
if (format2bpp(grtex->mipmap.format)==4) if (format2bpp(mipmap->format)==4)
{ {
for (i = 3; i < blocksize*4; i += 4) // blocksize*4 because blocksize doesn't include the bpp for (i = 3; i < blocksize*4; i += 4) // blocksize*4 because blocksize doesn't include the bpp
{ {
if (block[i] == 0) if (block[i] == 0)
{ {
grtex->mipmap.flags |= TF_TRANSPARENT; mipmap->flags |= TF_TRANSPARENT;
break; break;
} }
} }
@ -661,8 +624,6 @@ void HWR_FreeTextureColormaps(patch_t *patch)
Z_Free(next->data); Z_Free(next->data);
if (next->colormap) if (next->colormap)
Z_Free(next->colormap); Z_Free(next->colormap);
next->data = NULL;
next->colormap = NULL;
HWD.pfnDeleteTexture(next); HWD.pfnDeleteTexture(next);
// Free the old colormap mipmap from memory. // Free the old colormap mipmap from memory.
@ -714,12 +675,24 @@ void HWR_InitMapTextures(void)
gl_maptexturesloaded = false; gl_maptexturesloaded = false;
} }
static void FreeMapTexture(GLMapTexture_t *tex) static void DeleteTextureMipmap(GLMipmap_t *grMipmap, boolean delete_mipmap)
{ {
HWD.pfnDeleteTexture(&tex->mipmap); HWD.pfnDeleteTexture(grMipmap);
if (tex->mipmap.data)
Z_Free(tex->mipmap.data); if (delete_mipmap)
tex->mipmap.data = NULL; Z_Free(grMipmap->data);
}
static void FreeMapTexture(GLMapTexture_t *tex, boolean delete_chromakeys)
{
if (tex->mipmap.nextcolormap)
{
DeleteTextureMipmap(tex->mipmap.nextcolormap, delete_chromakeys);
free(tex->mipmap.nextcolormap);
tex->mipmap.nextcolormap = NULL;
}
DeleteTextureMipmap(&tex->mipmap, true);
} }
void HWR_FreeMapTextures(void) void HWR_FreeMapTextures(void)
@ -728,8 +701,8 @@ void HWR_FreeMapTextures(void)
for (i = 0; i < gl_numtextures; i++) for (i = 0; i < gl_numtextures; i++)
{ {
FreeMapTexture(&gl_textures[i]); FreeMapTexture(&gl_textures[i], true);
FreeMapTexture(&gl_flats[i]); FreeMapTexture(&gl_flats[i], false);
} }
// now the heap don't have any 'user' pointing to our // now the heap don't have any 'user' pointing to our
@ -762,41 +735,71 @@ void HWR_LoadMapTextures(size_t pnumtextures)
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
// Make sure texture is downloaded and set it as the source // Make sure texture is downloaded and set it as the source
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
GLMapTexture_t *HWR_GetTexture(INT32 tex) GLMapTexture_t *HWR_GetTexture(INT32 tex, boolean chromakeyed)
{ {
GLMapTexture_t *grtex; if (tex < 0 || tex >= (signed)gl_numtextures)
{
#ifdef PARANOIA #ifdef PARANOIA
if ((unsigned)tex >= gl_numtextures) I_Error("HWR_GetTexture: Invalid texture ID %d", tex);
I_Error("HWR_GetTexture: tex >= numtextures\n"); #else
tex = 0;
#endif #endif
}
// Every texture in memory, stored in the GLMapTexture_t *grtex = &gl_textures[tex];
// hardware renderer's bit depth format. Wow!
grtex = &gl_textures[tex];
// Generate texture if missing from the cache GLMipmap_t *grMipmap = &grtex->mipmap;
if (!grtex->mipmap.data && !grtex->mipmap.downloaded) GLMipmap_t *originalMipmap = grMipmap;
HWR_GenerateTexture(tex, grtex);
// If hardware does not have the texture, then call pfnSetTexture to upload it if (!originalMipmap->downloaded)
if (!grtex->mipmap.downloaded) {
HWD.pfnSetTexture(&grtex->mipmap); originalMipmap->flags = TF_WRAPXY;
HWR_SetCurrentTexture(&grtex->mipmap); originalMipmap->width = (UINT16)textures[tex]->width;
originalMipmap->height = (UINT16)textures[tex]->height;
originalMipmap->format = textureformat;
}
// The system-memory data can be purged now. // If chroma-keyed, create or use a different mipmap for the variant
Z_ChangeTag(grtex->mipmap.data, PU_HWRCACHE_UNLOCKED); if (chromakeyed && !textures[tex]->transparency)
{
// Allocate it if it wasn't already
if (!originalMipmap->nextcolormap)
{
GLMipmap_t *newMipmap = calloc(1, sizeof (*grMipmap));
if (newMipmap == NULL)
I_Error("%s: Out of memory", "HWR_GetTexture");
newMipmap->flags = originalMipmap->flags | TF_CHROMAKEYED;
newMipmap->width = originalMipmap->width;
newMipmap->height = originalMipmap->height;
newMipmap->format = originalMipmap->format;
originalMipmap->nextcolormap = newMipmap;
}
// Generate, upload and bind the variant texture instead of the original one
grMipmap = originalMipmap->nextcolormap;
}
if (!grMipmap->data)
HWR_GenerateTexture(tex, grtex, grMipmap);
if (!grMipmap->downloaded)
HWD.pfnSetTexture(grMipmap);
HWR_SetCurrentTexture(grMipmap);
Z_ChangeTag(grMipmap->data, PU_HWRCACHE_UNLOCKED);
return grtex; return grtex;
} }
static void HWR_CacheFlat(GLMipmap_t *grMipmap, lumpnum_t flatlumpnum) static void HWR_CacheRawFlat(GLMipmap_t *grMipmap, lumpnum_t flatlumpnum)
{ {
size_t size = W_LumpLength(flatlumpnum); size_t size = W_LumpLength(flatlumpnum);
UINT16 pflatsize = R_GetFlatSize(size); UINT16 pflatsize = R_GetFlatSize(size);
// setup the texture info // setup the texture info
grMipmap->format = GL_TEXFMT_P_8; grMipmap->format = GL_TEXFMT_P_8;
grMipmap->flags = TF_WRAPXY|TF_CHROMAKEYED; grMipmap->flags = TF_WRAPXY;
grMipmap->width = pflatsize; grMipmap->width = pflatsize;
grMipmap->height = pflatsize; grMipmap->height = pflatsize;
@ -817,7 +820,7 @@ void HWR_GetRawFlat(lumpnum_t flatlumpnum)
patch = HWR_GetCachedGLPatch(flatlumpnum); patch = HWR_GetCachedGLPatch(flatlumpnum);
grmip = ((GLPatch_t *)Patch_AllocateHardwarePatch(patch))->mipmap; grmip = ((GLPatch_t *)Patch_AllocateHardwarePatch(patch))->mipmap;
if (!grmip->downloaded && !grmip->data) if (!grmip->downloaded && !grmip->data)
HWR_CacheFlat(grmip, flatlumpnum); HWR_CacheRawFlat(grmip, flatlumpnum);
// If hardware does not have the texture, then call pfnSetTexture to upload it // If hardware does not have the texture, then call pfnSetTexture to upload it
if (!grmip->downloaded) if (!grmip->downloaded)
@ -828,7 +831,16 @@ void HWR_GetRawFlat(lumpnum_t flatlumpnum)
Z_ChangeTag(grmip->data, PU_HWRCACHE_UNLOCKED); Z_ChangeTag(grmip->data, PU_HWRCACHE_UNLOCKED);
} }
void HWR_GetLevelFlat(levelflat_t *levelflat) static void MakeLevelFlatMipmap(GLMipmap_t *grMipmap, INT32 texturenum, UINT16 flags)
{
grMipmap->format = GL_TEXFMT_P_8;
grMipmap->flags = flags;
grMipmap->width = (UINT16)textures[texturenum]->width;
grMipmap->height = (UINT16)textures[texturenum]->height;
}
void HWR_GetLevelFlat(levelflat_t *levelflat, boolean chromakeyed)
{ {
if (levelflat->type == LEVELFLAT_NONE || levelflat->texture_id < 0) if (levelflat->type == LEVELFLAT_NONE || levelflat->texture_id < 0)
{ {
@ -839,24 +851,50 @@ void HWR_GetLevelFlat(levelflat_t *levelflat)
INT32 texturenum = texturetranslation[levelflat->texture_id]; INT32 texturenum = texturetranslation[levelflat->texture_id];
GLMapTexture_t *grtex = &gl_flats[texturenum]; GLMapTexture_t *grtex = &gl_flats[texturenum];
GLMipmap_t *grMipmap = &grtex->mipmap; GLMipmap_t *grMipmap = &grtex->mipmap;
GLMipmap_t *originalMipmap = grMipmap;
if (!grMipmap->data && !grMipmap->downloaded) if (!originalMipmap->downloaded)
MakeLevelFlatMipmap(originalMipmap, texturenum, TF_WRAPXY);
if (!originalMipmap->data)
{ {
grMipmap->format = GL_TEXFMT_P_8; size_t size = originalMipmap->width * originalMipmap->height;
grMipmap->flags = TF_WRAPXY|TF_CHROMAKEYED; memcpy(Z_Malloc(size, PU_HWRCACHE, &originalMipmap->data), R_GetFlatForTexture(texturenum), size);
}
grMipmap->width = (UINT16)textures[texturenum]->width; // If chroma-keyed, create or use a different mipmap for the variant
grMipmap->height = (UINT16)textures[texturenum]->height; if (chromakeyed)
{
if (!originalMipmap->data)
{
HWR_SetCurrentTexture(NULL);
return;
}
size_t size = grMipmap->width * grMipmap->height; // Allocate it if it wasn't already
memcpy(Z_Malloc(size, PU_HWRCACHE, &grMipmap->data), R_GetFlatForTexture(texturenum), size); if (!originalMipmap->nextcolormap)
{
GLMipmap_t *newMipmap = calloc(1, sizeof (*grMipmap));
if (newMipmap == NULL)
I_Error("%s: Out of memory", "HWR_GetLevelFlat");
MakeLevelFlatMipmap(newMipmap, texturenum, TF_WRAPXY | TF_CHROMAKEYED);
originalMipmap->nextcolormap = newMipmap;
}
// Upload and bind the variant texture instead of the original one
grMipmap = originalMipmap->nextcolormap;
// Use the original texture's pixel data
// It can just be a pointer to it, since the r_opengl backend deals with the pixels
// that are supposed to be transparent.
grMipmap->data = originalMipmap->data;
} }
if (!grMipmap->downloaded) if (!grMipmap->downloaded)
HWD.pfnSetTexture(&grtex->mipmap); HWD.pfnSetTexture(grMipmap);
HWR_SetCurrentTexture(grMipmap);
HWR_SetCurrentTexture(&grtex->mipmap);
Z_ChangeTag(grMipmap->data, PU_HWRCACHE_UNLOCKED); Z_ChangeTag(grMipmap->data, PU_HWRCACHE_UNLOCKED);
} }

View file

@ -246,7 +246,7 @@ enum ETextureFlags
TF_WRAPX = 0x00000001, // wrap around X TF_WRAPX = 0x00000001, // wrap around X
TF_WRAPY = 0x00000002, // wrap around Y TF_WRAPY = 0x00000002, // wrap around Y
TF_WRAPXY = TF_WRAPY|TF_WRAPX, // very common so use alias is more easy TF_WRAPXY = TF_WRAPY|TF_WRAPX, // very common so use alias is more easy
TF_CHROMAKEYED = 0x00000010, TF_CHROMAKEYED = 0x00000010, // Used only for flats with pixels that have palette index 255
TF_TRANSPARENT = 0x00000040, // texture with some alpha == 0 TF_TRANSPARENT = 0x00000040, // texture with some alpha == 0
}; };

View file

@ -120,8 +120,8 @@ void HWR_GetPatch(patch_t *patch);
void HWR_GetMappedPatch(patch_t *patch, const UINT8 *colormap); void HWR_GetMappedPatch(patch_t *patch, const UINT8 *colormap);
void HWR_GetFadeMask(lumpnum_t fademasklumpnum); void HWR_GetFadeMask(lumpnum_t fademasklumpnum);
GLMapTexture_t *HWR_GetTexture(INT32 tex); GLMapTexture_t *HWR_GetTexture(INT32 tex, boolean chromakeyed);
void HWR_GetLevelFlat(levelflat_t *levelflat); void HWR_GetLevelFlat(levelflat_t *levelflat, boolean chromakeyed);
void HWR_GetRawFlat(lumpnum_t flatlumpnum); void HWR_GetRawFlat(lumpnum_t flatlumpnum);
void HWR_FreeTexture(patch_t *patch); void HWR_FreeTexture(patch_t *patch);

File diff suppressed because it is too large Load diff

View file

@ -571,9 +571,6 @@ void HWR_LoadModels(void)
} }
// Add sprite models. // Add sprite models.
// Must be 4 characters long exactly. Otherwise, it's not a sprite name.
if (len == 4)
{
for (i = 0; i < numsprites; i++) for (i = 0; i < numsprites; i++)
{ {
if (stricmp(name, sprnames[i]) == 0) if (stricmp(name, sprnames[i]) == 0)
@ -585,7 +582,6 @@ void HWR_LoadModels(void)
goto modelfound; goto modelfound;
} }
} }
}
addskinmodel: addskinmodel:
// Add player models. // Add player models.
@ -1078,30 +1074,47 @@ static boolean HWR_CanInterpolateSprite2(modelspr2frames_t *spr2frame)
return spr2frame->interpolate; return spr2frame->interpolate;
} }
// static modelspr2frames_t *HWR_GetModelSprite2Frames(md2_t *md2, UINT16 spr2)
// HWR_GetModelSprite2 (see P_GetSkinSprite2)
// For non-super players, tries each sprite2's immediate predecessor until it finds one with a number of frames or ends up at standing.
// For super players, does the same as above - but tries the super equivalent for each sprite2 before the non-super version.
//
static UINT8 HWR_GetModelSprite2(md2_t *md2, skin_t *skin, UINT8 spr2, player_t *player)
{ {
UINT8 super = 0, i = 0; if (!md2 || !md2->model)
return NULL;
if (!md2 || !md2->model || !md2->model->spr2frames || !skin) boolean is_super = spr2 & SPR2F_SUPER;
spr2 &= SPR2F_MASK;
if (spr2 >= free_spr2)
return NULL;
if (is_super)
{
modelspr2frames_t *frames = md2->model->superspr2frames;
if (frames && md2->model->superspr2frames[spr2].numframes)
return &md2->model->superspr2frames[spr2];
}
if (md2->model->spr2frames[spr2].numframes)
return &md2->model->spr2frames[spr2];
return NULL;
}
static UINT16 HWR_GetModelSprite2Num(md2_t *md2, skin_t *skin, UINT16 spr2, player_t *player)
{
UINT16 super = 0;
UINT8 i = 0;
if (!md2 || !md2->model || !skin)
return 0; return 0;
if ((playersprite_t)(spr2 & ~FF_SPR2SUPER) >= free_spr2) while (!HWR_GetModelSprite2Frames(md2, spr2)
return 0;
while (!md2->model->spr2frames[spr2].numframes
&& spr2 != SPR2_STND && spr2 != SPR2_STND
&& ++i != 32) // recursion limiter && ++i < 32) // recursion limiter
{ {
if (spr2 & FF_SPR2SUPER) if (spr2 & SPR2F_SUPER)
{ {
super = FF_SPR2SUPER; super = SPR2F_SUPER;
spr2 &= ~FF_SPR2SUPER; spr2 &= ~SPR2F_SUPER;
continue; continue;
} }
@ -1130,7 +1143,7 @@ static UINT8 HWR_GetModelSprite2(md2_t *md2, skin_t *skin, UINT8 spr2, player_t
} }
if (i >= 32) // probably an infinite loop... if (i >= 32) // probably an infinite loop...
return 0; spr2 = 0;
return spr2; return spr2;
} }
@ -1141,6 +1154,9 @@ static void adjustTextureCoords(model_t *model, patch_t *patch)
int i; int i;
GLPatch_t *gpatch = ((GLPatch_t *)patch->hardware); GLPatch_t *gpatch = ((GLPatch_t *)patch->hardware);
if (!gpatch)
return;
for (i = 0; i < model->numMeshes; i++) for (i = 0; i < model->numMeshes; i++)
{ {
int j; int j;
@ -1188,7 +1204,7 @@ boolean HWR_DrawModel(gl_vissprite_t *spr)
char filename[64]; char filename[64];
INT32 frame = 0; INT32 frame = 0;
INT32 nextFrame = -1; INT32 nextFrame = -1;
UINT8 spr2 = 0; modelspr2frames_t *spr2frames = NULL;
FTransform p; FTransform p;
FSurfaceInfo Surf; FSurfaceInfo Surf;
@ -1256,6 +1272,7 @@ boolean HWR_DrawModel(gl_vissprite_t *spr)
const UINT8 flip = (UINT8)(!(spr->mobj->eflags & MFE_VERTICALFLIP) != !R_ThingVerticallyFlipped(spr->mobj)); const UINT8 flip = (UINT8)(!(spr->mobj->eflags & MFE_VERTICALFLIP) != !R_ThingVerticallyFlipped(spr->mobj));
const UINT8 hflip = (UINT8)(!(spr->mobj->mirrored) != !R_ThingHorizontallyFlipped(spr->mobj)); const UINT8 hflip = (UINT8)(!(spr->mobj->mirrored) != !R_ThingHorizontallyFlipped(spr->mobj));
spritedef_t *sprdef; spritedef_t *sprdef;
UINT16 spr2 = 0;
spriteframe_t *sprframe; spriteframe_t *sprframe;
INT32 mod; INT32 mod;
interpmobjstate_t interp; interpmobjstate_t interp;
@ -1273,6 +1290,11 @@ boolean HWR_DrawModel(gl_vissprite_t *spr)
//if (tics > durs) //if (tics > durs)
//durs = tics; //durs = tics;
// Make linkdraw objects use their tracer's alpha value
fixed_t newalpha = spr->mobj->alpha;
if ((spr->mobj->flags2 & MF2_LINKDRAW) && spr->mobj->tracer)
newalpha = spr->mobj->tracer->alpha;
INT32 blendmode; INT32 blendmode;
if (spr->mobj->frame & FF_BLENDMASK) if (spr->mobj->frame & FF_BLENDMASK)
blendmode = ((spr->mobj->frame & FF_BLENDMASK) >> FF_BLENDSHIFT) + 1; blendmode = ((spr->mobj->frame & FF_BLENDMASK) >> FF_BLENDSHIFT) + 1;
@ -1287,6 +1309,8 @@ boolean HWR_DrawModel(gl_vissprite_t *spr)
Surf.PolyFlags = HWR_GetBlendModeFlag(blendmode); Surf.PolyFlags = HWR_GetBlendModeFlag(blendmode);
} }
Surf.PolyColor.s.alpha = FixedMul(newalpha, Surf.PolyColor.s.alpha);
// don't forget to enable the depth test because we can't do this // don't forget to enable the depth test because we can't do this
// like before: model polygons are not sorted // like before: model polygons are not sorted
@ -1418,18 +1442,28 @@ boolean HWR_DrawModel(gl_vissprite_t *spr)
tics = (float)spr->mobj->anim_duration; tics = (float)spr->mobj->anim_duration;
} }
if (spr->mobj->skin && spr->mobj->sprite == SPR_PLAY)
sprdef = P_GetSkinSpritedef(spr->mobj->skin, spr->mobj->sprite2);
else
sprdef = &sprites[spr->mobj->sprite];
frame = (spr->mobj->frame & FF_FRAMEMASK); frame = (spr->mobj->frame & FF_FRAMEMASK);
if (spr->mobj->skin && spr->mobj->sprite == SPR_PLAY && md2->model->spr2frames) if (spr->mobj->skin && spr->mobj->sprite == SPR_PLAY)
{ {
spr2 = HWR_GetModelSprite2(md2, spr->mobj->skin, spr->mobj->sprite2, spr->mobj->player); spr2 = HWR_GetModelSprite2Num(md2, spr->mobj->skin, spr->mobj->sprite2, spr->mobj->player);
mod = md2->model->spr2frames[spr2].numframes; spr2frames = HWR_GetModelSprite2Frames(md2, spr2);
}
if (spr2frames)
{
spritedef_t *defaultdef = P_GetSkinSpritedef(spr->mobj->skin, spr2);
mod = spr2frames->numframes;
#ifndef DONTHIDEDIFFANIMLENGTH // by default, different anim length is masked by the mod #ifndef DONTHIDEDIFFANIMLENGTH // by default, different anim length is masked by the mod
if (mod > (INT32)((skin_t *)spr->mobj->skin)->sprites[spr2].numframes) if (mod > (INT32)defaultdef->numframes)
mod = ((skin_t *)spr->mobj->skin)->sprites[spr2].numframes; mod = defaultdef->numframes;
#endif #endif
if (!mod) if (!mod)
mod = 1; mod = 1;
frame = md2->model->spr2frames[spr2].frames[frame%mod]; frame = spr2frames->frames[frame % mod];
} }
else else
{ {
@ -1449,13 +1483,18 @@ boolean HWR_DrawModel(gl_vissprite_t *spr)
if (durs > INTERPOLERATION_LIMIT) if (durs > INTERPOLERATION_LIMIT)
durs = INTERPOLERATION_LIMIT; durs = INTERPOLERATION_LIMIT;
if (spr->mobj->skin && spr->mobj->sprite == SPR_PLAY && md2->model->spr2frames) if (spr2frames)
{ {
if (HWR_CanInterpolateSprite2(&md2->model->spr2frames[spr2]) UINT16 next_spr2 = P_GetStateSprite2(&states[spr->mobj->state->nextstate]);
// Add or remove SPR2F_SUPER based on certain conditions
next_spr2 = P_ApplySuperFlagToSprite2(next_spr2, spr->mobj);
if (HWR_CanInterpolateSprite2(spr2frames)
&& (spr->mobj->frame & FF_ANIMATE && (spr->mobj->frame & FF_ANIMATE
|| (spr->mobj->state->nextstate != S_NULL || (spr->mobj->state->nextstate != S_NULL
&& states[spr->mobj->state->nextstate].sprite == SPR_PLAY && states[spr->mobj->state->nextstate].sprite == SPR_PLAY
&& ((P_GetSkinSprite2(spr->mobj->skin, (((spr->mobj->player && spr->mobj->player->powers[pw_super]) ? FF_SPR2SUPER : 0)|states[spr->mobj->state->nextstate].frame) & FF_FRAMEMASK, spr->mobj->player) == spr->mobj->sprite2))))) && ((P_GetSkinSprite2(spr->mobj->skin, next_spr2, spr->mobj->player) == spr->mobj->sprite2)))))
{ {
nextFrame = (spr->mobj->frame & FF_FRAMEMASK) + 1; nextFrame = (spr->mobj->frame & FF_FRAMEMASK) + 1;
if (nextFrame >= mod) if (nextFrame >= mod)
@ -1466,7 +1505,7 @@ boolean HWR_DrawModel(gl_vissprite_t *spr)
nextFrame = 0; nextFrame = 0;
} }
if (frame || !(spr->mobj->state->frame & FF_SPR2ENDSTATE)) if (frame || !(spr->mobj->state->frame & FF_SPR2ENDSTATE))
nextFrame = md2->model->spr2frames[spr2].frames[nextFrame]; nextFrame = spr2frames->frames[nextFrame];
else else
nextFrame = -1; nextFrame = -1;
} }
@ -1502,11 +1541,6 @@ boolean HWR_DrawModel(gl_vissprite_t *spr)
else else
p.z = FIXED_TO_FLOAT(interp.z); p.z = FIXED_TO_FLOAT(interp.z);
if (spr->mobj->skin && spr->mobj->sprite == SPR_PLAY)
sprdef = &((skin_t *)spr->mobj->skin)->sprites[spr->mobj->sprite2];
else
sprdef = &sprites[spr->mobj->sprite];
sprframe = &sprdef->spriteframes[spr->mobj->frame & FF_FRAMEMASK]; sprframe = &sprdef->spriteframes[spr->mobj->frame & FF_FRAMEMASK];
if (sprframe->rotate || papersprite) if (sprframe->rotate || papersprite)

View file

@ -292,6 +292,7 @@ void LoadModelSprite2(model_t *model)
{ {
INT32 i; INT32 i;
modelspr2frames_t *spr2frames = NULL; modelspr2frames_t *spr2frames = NULL;
modelspr2frames_t *superspr2frames = NULL;
INT32 numframes = model->meshes[0].numFrames; INT32 numframes = model->meshes[0].numFrames;
char *framename = model->frameNames; char *framename = model->frameNames;
@ -335,25 +336,33 @@ void LoadModelSprite2(model_t *model)
spr2idx = 0; spr2idx = 0;
while (spr2idx < free_spr2) while (spr2idx < free_spr2)
{ {
modelspr2frames_t *frames = NULL;
if (!memcmp(spr2names[spr2idx], name, 4)) if (!memcmp(spr2names[spr2idx], name, 4))
{ {
if (!spr2frames) if (!spr2frames)
spr2frames = (modelspr2frames_t*)Z_Calloc(sizeof(modelspr2frames_t)*NUMPLAYERSPRITES*2, PU_STATIC, NULL); spr2frames = (modelspr2frames_t*)Z_Calloc(sizeof(modelspr2frames_t)*NUMPLAYERSPRITES, PU_STATIC, NULL);
frames = spr2frames;
if (super) if (super)
spr2idx |= FF_SPR2SUPER; {
if (!superspr2frames)
superspr2frames = (modelspr2frames_t*)Z_Calloc(sizeof(modelspr2frames_t)*NUMPLAYERSPRITES, PU_STATIC, NULL);
frames = superspr2frames;
}
if (framechars[0]) if (framechars[0])
{ {
frame = atoi(framechars); frame = atoi(framechars);
if (spr2frames[spr2idx].numframes < frame+1) if (frames[spr2idx].numframes < frame+1)
spr2frames[spr2idx].numframes = frame+1; frames[spr2idx].numframes = frame+1;
} }
else else
{ {
frame = spr2frames[spr2idx].numframes; frame = frames[spr2idx].numframes;
spr2frames[spr2idx].numframes++; frames[spr2idx].numframes++;
} }
spr2frames[spr2idx].frames[frame] = i; frames[spr2idx].frames[frame] = i;
spr2frames[spr2idx].interpolate = interpolate; frames[spr2idx].interpolate = interpolate;
break; break;
} }
spr2idx++; spr2idx++;
@ -366,7 +375,10 @@ void LoadModelSprite2(model_t *model)
if (model->spr2frames) if (model->spr2frames)
Z_Free(model->spr2frames); Z_Free(model->spr2frames);
if (model->superspr2frames)
Z_Free(model->superspr2frames);
model->spr2frames = spr2frames; model->spr2frames = spr2frames;
model->superspr2frames = superspr2frames;
} }
// //

View file

@ -101,6 +101,7 @@ typedef struct model_s
char *frameNames; char *frameNames;
boolean interpolate[256]; boolean interpolate[256];
modelspr2frames_t *spr2frames; modelspr2frames_t *spr2frames;
modelspr2frames_t *superspr2frames;
// the max_s and max_t values that the uvs are currently adjusted to // the max_s and max_t values that the uvs are currently adjusted to
// (if a sprite is used as a texture) // (if a sprite is used as a texture)

View file

@ -448,6 +448,101 @@ void HWR_LoadAllCustomShaders(void)
HWR_LoadCustomShadersFromFile(i, W_FileHasFolders(wadfiles[i])); HWR_LoadCustomShadersFromFile(i, W_FileHasFolders(wadfiles[i]));
} }
static const char version_directives[][14] = {
"#version 330\n",
"#version 150\n",
"#version 140\n",
"#version 130\n",
"#version 120\n",
"#version 110\n",
};
static boolean HWR_VersionDirectiveExists(const char* source)
{
return strncmp(source, "#version", 8) == 0;
}
static char* HWR_PrependVersionDirective(const char* source, UINT32 version_index)
{
const UINT32 version_len = sizeof(version_directives[version_index]) - 1;
const UINT32 source_len = strlen(source);
char* result = Z_Malloc(source_len + version_len + 1, PU_STATIC, NULL);
strcpy(result, version_directives[version_index]);
strcpy(result + version_len, source);
return result;
}
static void HWR_ReplaceVersionInplace(char* shader, UINT32 version_index)
{
shader[9] = version_directives[version_index][9];
shader[10] = version_directives[version_index][10];
shader[11] = version_directives[version_index][11];
}
static boolean HWR_CheckVersionDirectives(const char* vert, const char* frag)
{
return HWR_VersionDirectiveExists(vert) && HWR_VersionDirectiveExists(frag);
}
static void HWR_TryToCompileShaderWithImplicitVersion(INT32 shader_index, INT32 shaderxlat_id)
{
char* vert_shader = gl_shaders[shader_index].vertex;
char* frag_shader = gl_shaders[shader_index].fragment;
boolean vert_shader_version_exists = HWR_VersionDirectiveExists(vert_shader);
boolean frag_shader_version_exists = HWR_VersionDirectiveExists(frag_shader);
if(!vert_shader_version_exists) {
CONS_Alert(CONS_WARNING, "HWR_LoadCustomShadersFromFile: vertex shader '%s' is missing a #version directive\n", HWR_GetShaderName(shaderxlat_id));
}
if(!frag_shader_version_exists) {
CONS_Alert(CONS_WARNING, "HWR_LoadCustomShadersFromFile: fragment shader '%s' is missing a #version directive\n", HWR_GetShaderName(shaderxlat_id));
}
// try to compile as is
HWR_CompileShader(shader_index);
if (gl_shaders[shader_index].compiled)
return;
// try each version directive
for(UINT32 i = 0; i < sizeof(version_directives) / sizeof(version_directives[0]); ++i) {
CONS_Alert(CONS_NOTICE, "HWR_TryToCompileShaderWithImplicitVersion: Trying %s\n", version_directives[i]);
if(!vert_shader_version_exists) {
// first time reallocation would have to be made
if(i == 0) {
void* old = (void*)gl_shaders[shader_index].vertex;
vert_shader = gl_shaders[shader_index].vertex = HWR_PrependVersionDirective(vert_shader, i);
Z_Free(old);
} else {
HWR_ReplaceVersionInplace(vert_shader, i);
}
}
if(!frag_shader_version_exists) {
if(i == 0) {
void* old = (void*)gl_shaders[shader_index].fragment;
frag_shader = gl_shaders[shader_index].fragment = HWR_PrependVersionDirective(frag_shader, i);
Z_Free(old);
} else {
HWR_ReplaceVersionInplace(frag_shader, i);
}
}
HWR_CompileShader(shader_index);
if (gl_shaders[shader_index].compiled) {
CONS_Alert(CONS_NOTICE, "HWR_TryToCompileShaderWithImplicitVersion: Compiled with %s\n",
version_directives[i]);
CONS_Alert(CONS_WARNING, "Implicit GLSL version is used. Correct behavior is not guaranteed\n");
return;
}
}
}
void HWR_LoadCustomShadersFromFile(UINT16 wadnum, boolean PK3) void HWR_LoadCustomShadersFromFile(UINT16 wadnum, boolean PK3)
{ {
UINT16 lump; UINT16 lump;
@ -610,7 +705,13 @@ skip_field:
gl_shaders[shader_index].fragment = Z_StrDup(gl_shadersources[i].fragment); gl_shaders[shader_index].fragment = Z_StrDup(gl_shadersources[i].fragment);
if (!gl_shaders[shader_index].vertex) if (!gl_shaders[shader_index].vertex)
gl_shaders[shader_index].vertex = Z_StrDup(gl_shadersources[i].vertex); gl_shaders[shader_index].vertex = Z_StrDup(gl_shadersources[i].vertex);
if(!HWR_CheckVersionDirectives(gl_shaders[shader_index].vertex, gl_shaders[shader_index].fragment)) {
HWR_TryToCompileShaderWithImplicitVersion(shader_index, i);
} else {
HWR_CompileShader(shader_index); HWR_CompileShader(shader_index);
}
if (!gl_shaders[shader_index].compiled) if (!gl_shaders[shader_index].compiled)
CONS_Alert(CONS_ERROR, "HWR_LoadCustomShadersFromFile: A compilation error occured for the %s shader in file %s. See the console messages above for more information.\n", shaderxlat[i].type, wadfiles[wadnum]->filename); CONS_Alert(CONS_ERROR, "HWR_LoadCustomShadersFromFile: A compilation error occured for the %s shader in file %s. See the console messages above for more information.\n", shaderxlat[i].type, wadfiles[wadnum]->filename);
} }

View file

@ -180,7 +180,7 @@ FUNCPRINTF void GL_DBG_Printf(const char *format, ...)
// GL_MSG_Warning : Raises a warning. // GL_MSG_Warning : Raises a warning.
// -----------------+ // -----------------+
static void GL_MSG_Warning(const char *format, ...) FUNCPRINTF static void GL_MSG_Warning(const char *format, ...)
{ {
char str[4096] = ""; char str[4096] = "";
va_list arglist; va_list arglist;
@ -203,7 +203,7 @@ static void GL_MSG_Warning(const char *format, ...)
// GL_MSG_Error : Raises an error. // GL_MSG_Error : Raises an error.
// -----------------+ // -----------------+
static void GL_MSG_Error(const char *format, ...) FUNCPRINTF static void GL_MSG_Error(const char *format, ...)
{ {
char str[4096] = ""; char str[4096] = "";
va_list arglist; va_list arglist;

View file

@ -61,21 +61,22 @@
#define HU_CSAY 2 // Server CECHOes to everyone. #define HU_CSAY 2 // Server CECHOes to everyone.
//------------------------------------------- //-------------------------------------------
// heads up font // Fonts & stuff
//------------------------------------------- //-------------------------------------------
patch_t *hu_font[HU_FONTSIZE]; // Font definitions
patch_t *tny_font[HU_FONTSIZE]; fontdef_t hu_font;
fontdef_t tny_font;
fontdef_t cred_font;
fontdef_t lt_font;
fontdef_t ntb_font;
fontdef_t nto_font;
// Numbers
patch_t *tallnum[10]; // 0-9 patch_t *tallnum[10]; // 0-9
patch_t *nightsnum[10]; // 0-9 patch_t *nightsnum[10]; // 0-9
// Level title and credits fonts
patch_t *lt_font[LT_FONTSIZE];
patch_t *cred_font[CRED_FONTSIZE];
patch_t *ttlnum[10]; // act numbers (0-9) patch_t *ttlnum[10]; // act numbers (0-9)
patch_t *tallminus;
// Name tag fonts patch_t *tallinfin;
patch_t *ntb_font[NT_FONTSIZE];
patch_t *nto_font[NT_FONTSIZE];
static player_t *plr; static player_t *plr;
boolean chat_on; // entering a chat message? boolean chat_on; // entering a chat message?
@ -91,8 +92,6 @@ patch_t *bflagico;
patch_t *rmatcico; patch_t *rmatcico;
patch_t *bmatcico; patch_t *bmatcico;
patch_t *tagico; patch_t *tagico;
patch_t *tallminus;
patch_t *tallinfin;
//------------------------------------------- //-------------------------------------------
// coop hud // coop hud
@ -188,53 +187,26 @@ static void Got_Saycmd(UINT8 **p, INT32 playernum);
void HU_LoadGraphics(void) void HU_LoadGraphics(void)
{ {
char buffer[9]; char buffer[9];
INT32 i, j; INT32 i;
if (dedicated) if (dedicated)
return; return;
j = HU_FONTSTART; // Cache fonts
for (i = 0; i < HU_FONTSIZE; i++, j++) HU_LoadFontCharacters(&hu_font, "STCFN");
{ HU_LoadFontCharacters(&tny_font, "TNYFN");
// cache the heads-up font for entire game execution HU_LoadFontCharacters(&cred_font, "CRFNT");
sprintf(buffer, "STCFN%.3d", j); HU_LoadFontCharacters(&lt_font, "LTFNT");
if (W_CheckNumForName(buffer) == LUMPERROR) HU_LoadFontCharacters(&ntb_font, "NTFNT");
hu_font[i] = NULL; HU_LoadFontCharacters(&nto_font, "NTFNO");
else
hu_font[i] = (patch_t *)W_CachePatchName(buffer, PU_HUDGFX);
// tiny version of the heads-up font // For each font, set kerning, space width, character width and line spacing
sprintf(buffer, "TNYFN%.3d", j); HU_SetFontProperties(&hu_font, 0, 4, 8, 12);
if (W_CheckNumForName(buffer) == LUMPERROR) HU_SetFontProperties(&tny_font, 0, 2, 4, 12);
tny_font[i] = NULL; HU_SetFontProperties(&cred_font, 0, 16, 16, 16);
else HU_SetFontProperties(&lt_font, 0, 16, 20, 20);
tny_font[i] = (patch_t *)W_CachePatchName(buffer, PU_HUDGFX); HU_SetFontProperties(&ntb_font, 2, 4, 20, 21);
} HU_SetFontProperties(&nto_font, 0, 4, 20, 21);
j = LT_FONTSTART;
for (i = 0; i < LT_FONTSIZE; i++)
{
sprintf(buffer, "LTFNT%.3d", j);
j++;
if (W_CheckNumForName(buffer) == LUMPERROR)
lt_font[i] = NULL;
else
lt_font[i] = (patch_t *)W_CachePatchName(buffer, PU_HUDGFX);
}
// cache the credits font for entire game execution (why not?)
j = CRED_FONTSTART;
for (i = 0; i < CRED_FONTSIZE; i++)
{
sprintf(buffer, "CRFNT%.3d", j);
j++;
if (W_CheckNumForName(buffer) == LUMPERROR)
cred_font[i] = NULL;
else
cred_font[i] = (patch_t *)W_CachePatchName(buffer, PU_HUDGFX);
}
//cache numbers too! //cache numbers too!
for (i = 0; i < 10; i++) for (i = 0; i < 10; i++)
@ -243,45 +215,14 @@ void HU_LoadGraphics(void)
tallnum[i] = (patch_t *)W_CachePatchName(buffer, PU_HUDGFX); tallnum[i] = (patch_t *)W_CachePatchName(buffer, PU_HUDGFX);
sprintf(buffer, "NGTNUM%d", i); sprintf(buffer, "NGTNUM%d", i);
nightsnum[i] = (patch_t *) W_CachePatchName(buffer, PU_HUDGFX); nightsnum[i] = (patch_t *) W_CachePatchName(buffer, PU_HUDGFX);
sprintf(buffer, "TTL%.2d", i);
ttlnum[i] = (patch_t *)W_CachePatchName(buffer, PU_HUDGFX);
} }
// minus for negative tallnums // minus for negative tallnums
tallminus = (patch_t *)W_CachePatchName("STTMINUS", PU_HUDGFX); tallminus = (patch_t *)W_CachePatchName("STTMINUS", PU_HUDGFX);
tallinfin = (patch_t *)W_CachePatchName("STTINFIN", PU_HUDGFX); tallinfin = (patch_t *)W_CachePatchName("STTINFIN", PU_HUDGFX);
// cache act numbers for level titles
for (i = 0; i < 10; i++)
{
sprintf(buffer, "TTL%.2d", i);
ttlnum[i] = (patch_t *)W_CachePatchName(buffer, PU_HUDGFX);
}
// cache the base name tag font for entire game execution
j = NT_FONTSTART;
for (i = 0; i < NT_FONTSIZE; i++)
{
sprintf(buffer, "NTFNT%.3d", j);
j++;
if (W_CheckNumForName(buffer) == LUMPERROR)
ntb_font[i] = NULL;
else
ntb_font[i] = (patch_t *)W_CachePatchName(buffer, PU_HUDGFX);
}
// cache the outline name tag font for entire game execution
j = NT_FONTSTART;
for (i = 0; i < NT_FONTSIZE; i++)
{
sprintf(buffer, "NTFNO%.3d", j);
j++;
if (W_CheckNumForName(buffer) == LUMPERROR)
nto_font[i] = NULL;
else
nto_font[i] = (patch_t *)W_CachePatchName(buffer, PU_HUDGFX);
}
// cache the crosshairs, don't bother to know which one is being used, // cache the crosshairs, don't bother to know which one is being used,
// just cache all 3, they're so small anyway. // just cache all 3, they're so small anyway.
for (i = 0; i < HU_CROSSHAIRS; i++) for (i = 0; i < HU_CROSSHAIRS; i++)
@ -323,6 +264,29 @@ void HU_LoadGraphics(void)
//emeraldpics[2][7] = W_CachePatchName("EMBOX8", PU_HUDGFX); -- unused //emeraldpics[2][7] = W_CachePatchName("EMBOX8", PU_HUDGFX); -- unused
} }
void HU_LoadFontCharacters(fontdef_t *font, const char *prefix)
{
char buffer[9];
INT32 i, j = FONTSTART;
for (i = 0; i < FONTSIZE; i++, j++)
{
sprintf(buffer, "%.5s%.3d", prefix, j);
if (W_CheckNumForPatchName(buffer) == LUMPERROR)
font->chars[i] = NULL;
else
font->chars[i] = (patch_t *)W_CachePatchName(buffer, PU_HUDGFX);
}
}
void HU_SetFontProperties(fontdef_t *font, INT32 kerning, UINT32 spacewidth, UINT32 charwidth, UINT32 linespacing)
{
font->kerning = kerning;
font->spacewidth = spacewidth;
font->charwidth = charwidth;
font->linespacing = linespacing;
}
// Initialise Heads up // Initialise Heads up
// once at game startup. // once at game startup.
// //
@ -465,9 +429,12 @@ static void DoSayCommand(SINT8 target, size_t usedargs, UINT8 flags)
numwords = COM_Argc() - usedargs; numwords = COM_Argc() - usedargs;
I_Assert(numwords > 0); I_Assert(numwords > 0);
if (CHAT_MUTE) // TODO: Per Player mute. if (CHAT_MUTE)
{ {
if (cv_mute.value)
HU_AddChatText(va("%s>ERROR: The chat is muted. You can't say anything.", "\x85"), false); HU_AddChatText(va("%s>ERROR: The chat is muted. You can't say anything.", "\x85"), false);
else
HU_AddChatText(va("%s>ERROR: You have been muted. You can't say anything.", "\x85"), false);
return; return;
} }
@ -496,10 +463,10 @@ static void DoSayCommand(SINT8 target, size_t usedargs, UINT8 flags)
// what we're gonna do now is check if the player exists // what we're gonna do now is check if the player exists
// with that logic, characters 4 and 5 are our numbers: // with that logic, characters 4 and 5 are our numbers:
const char *newmsg; const char *newmsg;
char playernum[3]; char playernum[3+1];
INT32 spc = 1; // used if playernum[1] is a space. INT32 spc = 1; // used if playernum[1] is a space.
strncpy(playernum, msg+3, 3); strncpy(playernum, msg+3, sizeof(playernum)-1);
// check for undesirable characters in our "number" // check for undesirable characters in our "number"
if (((playernum[0] < '0') || (playernum[0] > '9')) || ((playernum[1] < '0') || (playernum[1] > '9'))) if (((playernum[0] < '0') || (playernum[0] > '9')) || ((playernum[1] < '0') || (playernum[1] > '9')))
{ {
@ -644,9 +611,9 @@ static void Got_Saycmd(UINT8 **p, INT32 playernum)
msg = (char *)*p; msg = (char *)*p;
SKIPSTRINGL(*p, HU_MAXMSGLEN + 1); SKIPSTRINGL(*p, HU_MAXMSGLEN + 1);
if ((cv_mute.value || flags & (HU_CSAY|HU_SERVER_SAY)) && playernum != serverplayer && !(IsPlayerAdmin(playernum))) if ((cv_mute.value || players[playernum].muted || flags & (HU_CSAY|HU_SERVER_SAY)) && playernum != serverplayer && !(IsPlayerAdmin(playernum)))
{ {
CONS_Alert(CONS_WARNING, cv_mute.value ? CONS_Alert(CONS_WARNING, (cv_mute.value || players[playernum].muted) ?
M_GetText("Illegal say command received from %s while muted\n") : M_GetText("Illegal csay command received from non-admin %s\n"), M_GetText("Illegal say command received from %s while muted\n") : M_GetText("Illegal csay command received from non-admin %s\n"),
player_names[playernum]); player_names[playernum]);
if (server) if (server)
@ -962,14 +929,17 @@ static void HU_sendChatMessage(void)
// last minute mute check // last minute mute check
if (CHAT_MUTE) if (CHAT_MUTE)
{ {
if (cv_mute.value)
HU_AddChatText(va("%s>ERROR: The chat is muted. You can't say anything.", "\x85"), false); HU_AddChatText(va("%s>ERROR: The chat is muted. You can't say anything.", "\x85"), false);
else
HU_AddChatText(va("%s>ERROR: You have been muted. You can't say anything.", "\x85"), false);
return; return;
} }
if (strlen(msg) > 4 && strnicmp(msg, "/pm", 3) == 0) // used /pm if (strlen(msg) > 4 && strnicmp(msg, "/pm", 3) == 0) // used /pm
{ {
INT32 spc = 1; // used if playernum[1] is a space. INT32 spc = 1; // used if playernum[1] is a space.
char playernum[3]; char playernum[3+1];
const char *newmsg; const char *newmsg;
// what we're gonna do now is check if the player exists // what we're gonna do now is check if the player exists
@ -982,7 +952,7 @@ static void HU_sendChatMessage(void)
return; return;
} }
strncpy(playernum, msg+3, 3); strncpy(playernum, msg+3, sizeof(playernum)-1);
// check for undesirable characters in our "number" // check for undesirable characters in our "number"
if (!(isdigit(playernum[0]) && isdigit(playernum[1]))) if (!(isdigit(playernum[0]) && isdigit(playernum[1])))
{ {
@ -1029,6 +999,7 @@ static void HU_sendChatMessage(void)
void HU_clearChatChars(void) void HU_clearChatChars(void)
{ {
memset(w_chat, '\0', sizeof(w_chat)); memset(w_chat, '\0', sizeof(w_chat));
I_SetTextInputMode(false);
chat_on = false; chat_on = false;
c_input = 0; c_input = 0;
@ -1078,6 +1049,7 @@ boolean HU_Responder(event_t *ev)
if ((ev->key == gamecontrol[GC_TALKKEY][0] || ev->key == gamecontrol[GC_TALKKEY][1]) if ((ev->key == gamecontrol[GC_TALKKEY][0] || ev->key == gamecontrol[GC_TALKKEY][1])
&& netgame && !OLD_MUTE) // check for old chat mute, still let the players open the chat incase they want to scroll otherwise. && netgame && !OLD_MUTE) // check for old chat mute, still let the players open the chat incase they want to scroll otherwise.
{ {
I_SetTextInputMode(true);
chat_on = true; chat_on = true;
chat_on_first_event = false; chat_on_first_event = false;
w_chat[0] = 0; w_chat[0] = 0;
@ -1089,6 +1061,7 @@ boolean HU_Responder(event_t *ev)
if ((ev->key == gamecontrol[GC_TEAMKEY][0] || ev->key == gamecontrol[GC_TEAMKEY][1]) if ((ev->key == gamecontrol[GC_TEAMKEY][0] || ev->key == gamecontrol[GC_TEAMKEY][1])
&& netgame && !OLD_MUTE) && netgame && !OLD_MUTE)
{ {
I_SetTextInputMode(true);
chat_on = true; chat_on = true;
chat_on_first_event = false; chat_on_first_event = false;
w_chat[0] = 0; w_chat[0] = 0;
@ -1111,7 +1084,7 @@ boolean HU_Responder(event_t *ev)
if (ev->type == ev_text) if (ev->type == ev_text)
{ {
if ((c < HU_FONTSTART || c > HU_FONTEND || !hu_font[c-HU_FONTSTART]) if ((c < FONTSTART || c > FONTEND || !hu_font.chars[c-FONTSTART])
&& c != ' ') // Allow spaces, of course && c != ' ') // Allow spaces, of course
{ {
return false; return false;
@ -1163,6 +1136,7 @@ boolean HU_Responder(event_t *ev)
if (!CHAT_MUTE) if (!CHAT_MUTE)
HU_sendChatMessage(); HU_sendChatMessage();
I_SetTextInputMode(false);
chat_on = false; chat_on = false;
c_input = 0; // reset input cursor c_input = 0; // reset input cursor
chat_scrollmedown = true; // you hit enter, so you might wanna autoscroll to see what you just sent. :) chat_scrollmedown = true; // you hit enter, so you might wanna autoscroll to see what you just sent. :)
@ -1173,6 +1147,7 @@ boolean HU_Responder(event_t *ev)
|| c == gamecontrol[GC_TEAMKEY][0] || c == gamecontrol[GC_TEAMKEY][1]) || c == gamecontrol[GC_TEAMKEY][0] || c == gamecontrol[GC_TEAMKEY][1])
&& c >= KEY_MOUSE1)) // If it's not a keyboard key, then the chat button is used as a toggle. && c >= KEY_MOUSE1)) // If it's not a keyboard key, then the chat button is used as a toggle.
{ {
I_SetTextInputMode(false);
chat_on = false; chat_on = false;
c_input = 0; // reset input cursor c_input = 0; // reset input cursor
I_UpdateMouseGrab(); I_UpdateMouseGrab();
@ -1230,201 +1205,83 @@ boolean HU_Responder(event_t *ev)
// HEADS UP DRAWING // HEADS UP DRAWING
//====================================================================== //======================================================================
// Precompile a wordwrapped string to any given width.
// This is a muuuch better method than V_WORDWRAP.
// again stolen and modified a bit from video.c, don't mind me, will need to rearrange this one day.
// this one is simplified for the chat drawer.
static char *CHAT_WordWrap(INT32 x, INT32 w, INT32 option, const char *string)
{
INT32 c;
size_t chw, i, lastusablespace = 0;
size_t slen;
char *newstring = Z_StrDup(string);
INT32 spacewidth = (vid.width < 640) ? 8 : 4, charwidth = (vid.width < 640) ? 8 : 4;
slen = strlen(string);
x = 0;
for (i = 0; i < slen; ++i)
{
c = newstring[i];
if ((UINT8)c >= 0x80 && (UINT8)c <= 0x89) //color parsing! -Inuyasha 2.16.09
continue;
if (c == '\n')
{
x = 0;
lastusablespace = 0;
continue;
}
if (!(option & V_ALLOWLOWERCASE))
c = toupper(c);
c -= HU_FONTSTART;
if (c < 0 || c >= HU_FONTSIZE || !hu_font[c])
{
chw = spacewidth;
lastusablespace = i;
}
else
chw = charwidth;
x += chw;
if (lastusablespace != 0 && x > w)
{
//CONS_Printf("Wrap at index %d\n", i);
newstring[lastusablespace] = '\n';
i = lastusablespace+1;
lastusablespace = 0;
x = 0;
}
}
return newstring;
}
// 30/7/18: chaty is now the distance at which the lowest point of the chat will be drawn if that makes any sense. // 30/7/18: chaty is now the distance at which the lowest point of the chat will be drawn if that makes any sense.
INT16 chatx = 13, chaty = 169; // let's use this as our coordinates INT16 chatx = 13, chaty = 169; // let's use this as our coordinates
// chat stuff by VincyTM LOL XD!
// HU_DrawMiniChat // HU_DrawMiniChat
static void HU_drawMiniChat(void) static void HU_drawMiniChat(void)
{ {
INT32 x = chatx+2; INT32 x = chatx+2, y;
INT32 chatheight = 0;
INT32 charwidth = 4, charheight = 6; INT32 charwidth = 4, charheight = 6;
INT32 boxw = cv_chatwidth.value; INT32 boxw = cv_chatwidth.value;
INT32 dx = 0, dy = 0; INT32 dx = 0, dy = 0;
size_t i = chat_nummsg_min;
boolean prev_linereturn = false; // a hack to prevent double \n while I have no idea why they happen in the first place.
INT32 msglines = 0;
// process all messages once without rendering anything or doing anything fancy so that we know how many lines each message has...
INT32 y;
if (!chat_nummsg_min) if (!chat_nummsg_min)
return; // needless to say it's useless to do anything if we don't have anything to draw. return; // needless to say it's useless to do anything if we don't have anything to draw.
/*if (splitscreen > 1) for (size_t i = chat_nummsg_min; i > 0; i--)
boxw = max(64, boxw/2);*/
for (; i>0; i--)
{ {
char *msg = CHAT_WordWrap(x+2, boxw-(charwidth*2), V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_ALLOWLOWERCASE, chat_mini[i-1]); char *msg = V_ChatWordWrap(chatx, boxw-charwidth, V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_ALLOWLOWERCASE, chat_mini[i-1]);
size_t j = 0; for(size_t j = 0; msg[j]; j++) // iterate through msg
INT32 linescount = 0;
while(msg[j]) // iterate through msg
{
if (msg[j] < HU_FONTSTART) // don't draw
{ {
if (msg[j] == '\n') // get back down. if (msg[j] == '\n') // get back down.
{ {
++j; chatheight += charheight;
if (!prev_linereturn)
{
linescount += 1;
dx = 0; dx = 0;
} }
prev_linereturn = true; else if (msg[j] >= FONTSTART)
continue;
}
else if (msg[j] & 0x80) // stolen from video.c, nice.
{ {
++j;
continue;
}
++j;
}
else
{
j++;
}
prev_linereturn = false;
dx += charwidth; dx += charwidth;
if (dx >= boxw) if (dx >= boxw)
{ {
dx = 0; dx = 0;
linescount += 1; chatheight += charheight;
}
} }
} }
dy = 0;
dx = 0; dx = 0;
msglines += linescount+1; chatheight += charheight;
if (msg) if (msg)
Z_Free(msg); Z_Free(msg);
} }
y = chaty - charheight*(msglines+1); y = chaty - (chatheight + charheight);
/*if (splitscreen) for (size_t i = 0; i < chat_nummsg_min; i++) // iterate through our hot messages
{ {
y -= BASEVIDHEIGHT/2;
if (splitscreen > 1)
y += 16;
}*/
dx = 0;
dy = 0;
i = 0;
prev_linereturn = false;
for (; i<=(chat_nummsg_min-1); i++) // iterate through our hot messages
{
INT32 clrflag = 0;
INT32 timer = ((cv_chattime.value*TICRATE)-chat_timers[i]) - cv_chattime.value*TICRATE+9; // see below... INT32 timer = ((cv_chattime.value*TICRATE)-chat_timers[i]) - cv_chattime.value*TICRATE+9; // see below...
INT32 transflag = (timer >= 0 && timer <= 9) ? (timer*V_10TRANS) : 0; // you can make bad jokes out of this one. INT32 transflag = (timer >= 0 && timer <= 9) ? (timer*V_10TRANS) : 0; // you can make bad jokes out of this one.
size_t j = 0; char *msg = V_ChatWordWrap(chatx, boxw-charwidth, V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_ALLOWLOWERCASE, chat_mini[i]); // get the current message, and word wrap it.
char *msg = CHAT_WordWrap(x+2, boxw-(charwidth*2), V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_ALLOWLOWERCASE, chat_mini[i]); // get the current message, and word wrap it.
UINT8 *colormap = NULL; UINT8 *colormap = NULL;
while(msg[j]) // iterate through msg for(size_t j = 0; msg[j]; j++) // iterate through msg
{
if (msg[j] < HU_FONTSTART) // don't draw
{ {
if (msg[j] == '\n') // get back down. if (msg[j] == '\n') // get back down.
{
++j;
if (!prev_linereturn)
{ {
dy += charheight; dy += charheight;
dx = 0; dx = 0;
} }
prev_linereturn = true; else if (msg[j] & 0x80) // get colormap
continue; colormap = V_GetStringColormap(((msg[j] & 0x7f) << V_CHARCOLORSHIFT) & V_CHARCOLORMASK);
} else if (msg[j] >= FONTSTART)
else if (msg[j] & 0x80) // stolen from video.c, nice.
{
clrflag = ((msg[j] & 0x7f) << V_CHARCOLORSHIFT) & V_CHARCOLORMASK;
colormap = V_GetStringColormap(clrflag);
++j;
continue;
}
++j;
}
else
{ {
if (cv_chatbacktint.value) // on request of wolfy if (cv_chatbacktint.value) // on request of wolfy
V_DrawFillConsoleMap(x + dx + 2, y+dy, charwidth, charheight, 239|V_SNAPTOBOTTOM|V_SNAPTOLEFT); V_DrawFillConsoleMap(x + dx + 2, y+dy, charwidth, charheight, 239|V_SNAPTOBOTTOM|V_SNAPTOLEFT);
V_DrawChatCharacter(x + dx + 2, y+dy, msg[j++] |V_SNAPTOBOTTOM|V_SNAPTOLEFT|transflag, true, colormap); V_DrawChatCharacter(x + dx + 2, y+dy, msg[j] |V_SNAPTOBOTTOM|V_SNAPTOLEFT|transflag, true, colormap);
}
dx += charwidth; dx += charwidth;
prev_linereturn = false;
if (dx >= boxw) if (dx >= boxw)
{ {
dx = 0; dx = 0;
dy += charheight; dy += charheight;
} }
} }
}
dy += charheight; dy += charheight;
dx = 0; dx = 0;
@ -1434,7 +1291,6 @@ static void HU_drawMiniChat(void)
// decrement addy and make that shit smooth: // decrement addy and make that shit smooth:
addy /= 2; addy /= 2;
} }
// HU_DrawChatLog // HU_DrawChatLog
@ -1479,46 +1335,30 @@ static void HU_drawChatLog(INT32 offset)
for (i=0; i<chat_nummsg_log; i++) // iterate through our chatlog for (i=0; i<chat_nummsg_log; i++) // iterate through our chatlog
{ {
INT32 clrflag = 0; char *msg = V_ChatWordWrap(chatx, boxw-charwidth, V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_ALLOWLOWERCASE, chat_log[i]); // get the current message, and word wrap it.
INT32 j = 0;
char *msg = CHAT_WordWrap(x+2, boxw-(charwidth*2), V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_ALLOWLOWERCASE, chat_log[i]); // get the current message, and word wrap it.
UINT8 *colormap = NULL; UINT8 *colormap = NULL;
while(msg[j]) // iterate through msg for(size_t j = 0; msg[j]; j++) // iterate through msg
{
if (msg[j] < HU_FONTSTART) // don't draw
{ {
if (msg[j] == '\n') // get back down. if (msg[j] == '\n') // get back down.
{ {
++j;
dy += charheight; dy += charheight;
dx = 0; dx = 0;
continue;
} }
else if (msg[j] & 0x80) // stolen from video.c, nice. else if (msg[j] & 0x80) // get colormap
{ colormap = V_GetStringColormap(((msg[j] & 0x7f) << V_CHARCOLORSHIFT) & V_CHARCOLORMASK);
clrflag = ((msg[j] & 0x7f) << V_CHARCOLORSHIFT) & V_CHARCOLORMASK; else if (msg[j] >= FONTSTART)
colormap = V_GetStringColormap(clrflag);
++j;
continue;
}
++j;
}
else
{ {
if ((y+dy+2 >= chat_topy) && (y+dy < (chat_bottomy))) if ((y+dy+2 >= chat_topy) && (y+dy < (chat_bottomy)))
V_DrawChatCharacter(x + dx + 2, y+dy+2, msg[j++] |V_SNAPTOBOTTOM|V_SNAPTOLEFT, true, colormap); V_DrawChatCharacter(x + dx + 2, y+dy+2, msg[j] |V_SNAPTOBOTTOM|V_SNAPTOLEFT, true, colormap);
else
j++; // don't forget to increment this or we'll get stuck in the limbo.
}
dx += charwidth; dx += charwidth;
if (dx >= boxw-charwidth-2 && i<chat_nummsg_log && msg[j] >= HU_FONTSTART) // end of message shouldn't count, nor should invisible characters!!!! if (dx >= boxw-charwidth-2 && i<chat_nummsg_log) // end of message shouldn't count, nor should invisible characters!!!!
{ {
dx = 0; dx = 0;
dy += charheight; dy += charheight;
} }
} }
}
dy += charheight; dy += charheight;
dx = 0; dx = 0;
@ -1526,30 +1366,25 @@ static void HU_drawChatLog(INT32 offset)
Z_Free(msg); Z_Free(msg);
} }
if (((chat_scroll >= chat_maxscroll) || (chat_scrollmedown)) && !(justscrolleddown || justscrolledup || chat_scrolltime)) // was already at the bottom of the page before new maxscroll calculation and was NOT scrolling. if (((chat_scroll >= chat_maxscroll) || (chat_scrollmedown)) && !(justscrolleddown || justscrolledup || chat_scrolltime)) // was already at the bottom of the page before new maxscroll calculation and was NOT scrolling.
{
atbottom = true; // we should scroll atbottom = true; // we should scroll
}
chat_scrollmedown = false; chat_scrollmedown = false;
// getmaxscroll through a lazy hack. We do all these loops, // getmaxscroll through a lazy hack. We do all these loops, so let's not do more loops that are gonna lag the game more. :P
// so let's not do more loops that are gonna lag the game more. :P
chat_maxscroll = max(dy / charheight - cv_chatheight.value, 0); chat_maxscroll = max(dy / charheight - cv_chatheight.value, 0);
// if we're not bound by the time, autoscroll for next frame: // if we're not bound by the time, autoscroll for next frame:
if (atbottom) if (atbottom)
chat_scroll = chat_maxscroll; chat_scroll = chat_maxscroll;
// draw arrows to indicate that we can (or not) scroll. // draw arrows to indicate that we can (or not) scroll, accounting for Y = -1 offset in tinyfont
// account for Y = -1 offset in tinyfont
if (chat_scroll > 0) if (chat_scroll > 0)
V_DrawThinString(chatx-8, ((justscrolledup) ? (chat_topy-1) : (chat_topy)) - 1, V_SNAPTOBOTTOM | V_SNAPTOLEFT | V_YELLOWMAP, "\x1A"); // up arrow V_DrawThinString(chatx-8, ((justscrolledup) ? (chat_topy-1) : (chat_topy)) - 1, V_SNAPTOBOTTOM | V_SNAPTOLEFT | V_YELLOWMAP, "\x1A"); // up arrow
if (chat_scroll < chat_maxscroll) if (chat_scroll < chat_maxscroll)
V_DrawThinString(chatx-8, chat_bottomy-((justscrolleddown) ? 5 : 6) - 1, V_SNAPTOBOTTOM | V_SNAPTOLEFT | V_YELLOWMAP, "\x1B"); // down arrow V_DrawThinString(chatx-8, chat_bottomy-((justscrolleddown) ? 5 : 6) - 1, V_SNAPTOBOTTOM | V_SNAPTOLEFT | V_YELLOWMAP, "\x1B"); // down arrow
justscrolleddown = false; justscrolleddown = justscrolledup = false;
justscrolledup = false;
} }
// //
@ -1567,7 +1402,6 @@ static void HU_DrawChat(void)
INT32 cflag = 0; INT32 cflag = 0;
const char *ntalk = "Say: ", *ttalk = "Team: "; const char *ntalk = "Say: ", *ttalk = "Team: ";
const char *talk = ntalk; const char *talk = ntalk;
const char *mute = "Chat has been muted.";
#ifdef NETSPLITSCREEN #ifdef NETSPLITSCREEN
if (splitscreen) if (splitscreen)
@ -1582,35 +1416,24 @@ static void HU_DrawChat(void)
#endif #endif
if (teamtalk) if (teamtalk)
{
talk = ttalk; talk = ttalk;
#if 0
if (players[consoleplayer].ctfteam == 1)
t = 0x500; // Red
else if (players[consoleplayer].ctfteam == 2)
t = 0x400; // Blue
#endif
}
if (CHAT_MUTE) if (CHAT_MUTE)
{ {
talk = mute; if (cv_mute.value)
talk = "Chat has been muted.";
else
talk = "You have been muted.";
typelines = 1; typelines = 1;
cflag = V_GRAYMAP; // set text in gray if chat is muted. cflag = V_GRAYMAP; // set text in gray if chat is muted.
} }
V_DrawFillConsoleMap(chatx, y-1, boxw, (typelines*charheight), 239 | V_SNAPTOBOTTOM | V_SNAPTOLEFT); V_DrawFillConsoleMap(chatx, y-1, boxw, (typelines*charheight), 239 | V_SNAPTOBOTTOM | V_SNAPTOLEFT);
while (talk[i]) for (i = 0; talk[i]; i++)
{
if (talk[i] < HU_FONTSTART)
++i;
else
{ {
if (talk[i] >= FONTSTART)
V_DrawChatCharacter(chatx + c + 2, y, talk[i] |V_SNAPTOBOTTOM|V_SNAPTOLEFT|cflag, true, V_GetStringColormap(talk[i]|cflag)); V_DrawChatCharacter(chatx + c + 2, y, talk[i] |V_SNAPTOBOTTOM|V_SNAPTOLEFT|cflag, true, V_GetStringColormap(talk[i]|cflag));
i++;
}
c += charwidth; c += charwidth;
} }
@ -1621,13 +1444,12 @@ static void HU_DrawChat(void)
return; return;
} }
i = 0;
typelines = 1; typelines = 1;
if ((strlen(w_chat) == 0 || c_input == 0) && hu_tick < 4) if ((strlen(w_chat) == 0 || c_input == 0) && hu_tick < 4)
V_DrawChatCharacter(chatx + 2 + c, y+1, '_' |V_SNAPTOBOTTOM|V_SNAPTOLEFT|t, true, NULL); V_DrawChatCharacter(chatx + 2 + c, y+1, '_' |V_SNAPTOBOTTOM|V_SNAPTOLEFT|t, true, NULL);
while (w_chat[i]) for (i = 0; w_chat[i]; i++)
{ {
boolean skippedline = false; boolean skippedline = false;
if (c_input == (i+1)) if (c_input == (i+1))
@ -1644,14 +1466,11 @@ static void HU_DrawChat(void)
} }
} }
//Hurdler: isn't it better like that? if (w_chat[i] >= FONTSTART)
if (w_chat[i] < HU_FONTSTART) V_DrawChatCharacter(chatx + c + 2, y, w_chat[i] | V_SNAPTOBOTTOM|V_SNAPTOLEFT | t, true, NULL);
++i;
else
V_DrawChatCharacter(chatx + c + 2, y, w_chat[i++] | V_SNAPTOBOTTOM|V_SNAPTOLEFT | t, true, NULL);
c += charwidth; c += charwidth;
if (c > boxw-(charwidth*2) && !skippedline) if (c > boxw-charwidth && !skippedline)
{ {
c = 0; c = 0;
y += charheight; y += charheight;
@ -1673,47 +1492,31 @@ static void HU_DrawChat(void)
} }
#endif #endif
i = 0; for(i=0; i<MAXPLAYERS; i++)
for(i=0; (i<MAXPLAYERS); i++)
{ {
// filter: (code needs optimization pls help I'm bad with C) // filter: (code needs optimization pls help I'm bad with C)
if (w_chat[3]) if (w_chat[3])
{ {
char playernum[3]; char playernum[3+1];
UINT32 n; UINT32 n;
// right, that's half important: (w_chat[4] may be a space since /pm0 msg is perfectly acceptable!) // right, that's half important: (w_chat[4] may be a space since /pm0 msg is perfectly acceptable!)
if ( ( ((w_chat[3] != 0) && ((w_chat[3] < '0') || (w_chat[3] > '9'))) || ((w_chat[4] != 0) && (((w_chat[4] < '0') || (w_chat[4] > '9'))))) && (w_chat[4] != ' ')) if ( ( ((w_chat[3] != 0) && ((w_chat[3] < '0') || (w_chat[3] > '9'))) || ((w_chat[4] != 0) && (((w_chat[4] < '0') || (w_chat[4] > '9'))))) && (w_chat[4] != ' '))
break; break;
strncpy(playernum, w_chat+3, 3); strncpy(playernum, w_chat+3, sizeof(playernum)-1);
playernum[3] = 0;
n = atoi(playernum); // turn that into a number n = atoi(playernum); // turn that into a number
// special cases: // special cases:
if ((n == 0) && !(w_chat[4] == '0') && (!(i<10)))
if ((n == 0) && !(w_chat[4] == '0'))
{
if (!(i<10))
continue; continue;
} else if ((n == 1) && !(w_chat[3] == '0') && (!((i == 1) || ((i >= 10) && (i <= 19)))))
else if ((n == 1) && !(w_chat[3] == '0'))
{
if (!((i == 1) || ((i >= 10) && (i <= 19))))
continue; continue;
} else if ((n == 2) && !(w_chat[3] == '0') && (!((i == 2) || ((i >= 20) && (i <= 29)))))
else if ((n == 2) && !(w_chat[3] == '0'))
{
if (!((i == 2) || ((i >= 20) && (i <= 29))))
continue; continue;
} else if ((n == 3) && !(w_chat[3] == '0') && (!((i == 3) || ((i >= 30) && (i <= 31)))))
else if ((n == 3) && !(w_chat[3] == '0'))
{
if (!((i == 3) || ((i >= 30) && (i <= 31))))
continue; continue;
}
else // general case. else // general case.
{ if (i != n) continue;
if (i != n)
continue;
}
} }
if (playeringame[i]) if (playeringame[i])
@ -1744,41 +1547,22 @@ static void HU_DrawChat_Old(void)
size_t i = 0; size_t i = 0;
const char *ntalk = "Say: ", *ttalk = "Say-Team: "; const char *ntalk = "Say: ", *ttalk = "Say-Team: ";
const char *talk = ntalk; const char *talk = ntalk;
INT32 charwidth = 8 * con_scalefactor; //(hu_font['A'-HU_FONTSTART]->width) * con_scalefactor; INT32 charwidth = 8 * con_scalefactor, charheight = 8 * con_scalefactor;
INT32 charheight = 8 * con_scalefactor; //(hu_font['A'-HU_FONTSTART]->height) * con_scalefactor;
if (teamtalk) if (teamtalk)
{
talk = ttalk; talk = ttalk;
#if 0
if (players[consoleplayer].ctfteam == 1)
t = 0x500; // Red
else if (players[consoleplayer].ctfteam == 2)
t = 0x400; // Blue
#endif
}
while (talk[i]) for (i = 0; talk[i]; i++)
{ {
if (talk[i] < HU_FONTSTART) if (talk[i] >= FONTSTART)
{ V_DrawCharacter(HU_INPUTX + c, y, talk[i] | cv_constextsize.value | V_NOSCALESTART, true);
++i;
//charwidth = 4 * con_scalefactor;
}
else
{
//charwidth = (hu_font[talk[i]-HU_FONTSTART]->width) * con_scalefactor;
V_DrawCharacter(HU_INPUTX + c, y, talk[i++] | cv_constextsize.value | V_NOSCALESTART, true);
}
c += charwidth; c += charwidth;
} }
if ((strlen(w_chat) == 0 || c_input == 0) && hu_tick < 4) if ((strlen(w_chat) == 0 || c_input == 0) && hu_tick < 4)
V_DrawCharacter(HU_INPUTX+c, y+2*con_scalefactor, '_' |cv_constextsize.value | V_NOSCALESTART|t, true); V_DrawCharacter(HU_INPUTX+c, y+2*con_scalefactor, '_' |cv_constextsize.value | V_NOSCALESTART|t, true);
i = 0; for (i = 0; w_chat[i]; i++)
while (w_chat[i])
{ {
if (c_input == (i+1) && hu_tick < 4) if (c_input == (i+1) && hu_tick < 4)
{ {
INT32 cursorx = (HU_INPUTX+c+charwidth < vid.width) ? (HU_INPUTX + c + charwidth) : (HU_INPUTX); // we may have to go down. INT32 cursorx = (HU_INPUTX+c+charwidth < vid.width) ? (HU_INPUTX + c + charwidth) : (HU_INPUTX); // we may have to go down.
@ -1786,17 +1570,8 @@ static void HU_DrawChat_Old(void)
V_DrawCharacter(cursorx, cursory+2*con_scalefactor, '_' |cv_constextsize.value | V_NOSCALESTART|t, true); V_DrawCharacter(cursorx, cursory+2*con_scalefactor, '_' |cv_constextsize.value | V_NOSCALESTART|t, true);
} }
//Hurdler: isn't it better like that? if (w_chat[i] >= FONTSTART)
if (w_chat[i] < HU_FONTSTART) V_DrawCharacter(HU_INPUTX + c, y, w_chat[i] | cv_constextsize.value | V_NOSCALESTART | t, true);
{
++i;
//charwidth = 4 * con_scalefactor;
}
else
{
//charwidth = (hu_font[w_chat[i]-HU_FONTSTART]->width) * con_scalefactor;
V_DrawCharacter(HU_INPUTX + c, y, w_chat[i++] | cv_constextsize.value | V_NOSCALESTART | t, true);
}
c += charwidth; c += charwidth;
if (c >= vid.width) if (c >= vid.width)
@ -1805,9 +1580,6 @@ static void HU_DrawChat_Old(void)
y += charheight; y += charheight;
} }
} }
if (hu_tick < 4)
V_DrawCharacter(HU_INPUTX + c, y, '_' | cv_constextsize.value |V_NOSCALESTART|t, true);
} }
// Draw crosshairs at the exact center of the view. // Draw crosshairs at the exact center of the view.
@ -1893,21 +1665,6 @@ static void HU_DrawCEcho(void)
} }
} }
static void HU_drawGametype(void)
{
const char *strvalue = NULL;
if (gametype < 0 || gametype >= gametypecount)
return; // not a valid gametype???
strvalue = Gametype_Names[gametype];
if (splitscreen)
V_DrawString(4, 184, 0, strvalue);
else
V_DrawString(4, 192, 0, strvalue);
}
// //
// demo info stuff // demo info stuff
// //
@ -2258,13 +2015,13 @@ static void HU_Draw32TeamTabRankings(playersort_t *tab, INT32 whiteplayer)
greycheck = greycheckdef; greycheck = greycheckdef;
supercheck = supercheckdef; supercheck = supercheckdef;
if (tab[i].color == skincolor_redteam) //red if (players[tab[i].num].ctfteam == 1) //red
{ {
redplayers++; redplayers++;
x = 14 + (BASEVIDWIDTH/2); x = 14 + (BASEVIDWIDTH/2);
y = (redplayers * 9) + 20; y = (redplayers * 9) + 20;
} }
else if (tab[i].color == skincolor_blueteam) //blue else if (players[tab[i].num].ctfteam == 2) //blue
{ {
blueplayers++; blueplayers++;
x = 14; x = 14;
@ -2346,7 +2103,7 @@ void HU_DrawTeamTabRankings(playersort_t *tab, INT32 whiteplayer)
if (players[tab[i].num].spectator) if (players[tab[i].num].spectator)
continue; //ignore them. continue; //ignore them.
if (tab[i].color == skincolor_redteam) //red if (players[tab[i].num].ctfteam == 1) //red
{ {
if (redplayers++ > 8) if (redplayers++ > 8)
{ {
@ -2354,7 +2111,7 @@ void HU_DrawTeamTabRankings(playersort_t *tab, INT32 whiteplayer)
break; // don't make more loops than we need to. break; // don't make more loops than we need to.
} }
} }
else if (tab[i].color == skincolor_blueteam) //blue else if (players[tab[i].num].ctfteam == 2) //blue
{ {
if (blueplayers++ > 8) if (blueplayers++ > 8)
{ {
@ -2385,14 +2142,14 @@ void HU_DrawTeamTabRankings(playersort_t *tab, INT32 whiteplayer)
if (players[tab[i].num].spectator) if (players[tab[i].num].spectator)
continue; //ignore them. continue; //ignore them.
if (tab[i].color == skincolor_redteam) //red if (players[tab[i].num].ctfteam == 1) //red
{ {
if (redplayers++ > 8) if (redplayers++ > 8)
continue; continue;
x = 32 + (BASEVIDWIDTH/2); x = 32 + (BASEVIDWIDTH/2);
y = (redplayers * 16) + 16; y = (redplayers * 16) + 16;
} }
else if (tab[i].color == skincolor_blueteam) //blue else if (players[tab[i].num].ctfteam == 2) //blue
{ {
if (blueplayers++ > 8) if (blueplayers++ > 8)
continue; continue;
@ -2706,53 +2463,20 @@ static inline void HU_DrawSpectatorTicker(void)
{ {
int i; int i;
int length = 0, height = 174; int length = 0, height = 174;
int totallength = 0, templength = 0; int totallength = 0;
for (i = 0; i < MAXPLAYERS; i++) for (i = 0; i < MAXPLAYERS; i++)
if (playeringame[i] && players[i].spectator) if (playeringame[i] && players[i].spectator)
totallength += (signed)strlen(player_names[i]) * 8 + 16; totallength += (signed)strlen(player_names[i]) * 8 + 16;
length -= (leveltime % (totallength + BASEVIDWIDTH)); length -= (leveltime % (totallength + (vid.width / vid.dup)));
length += BASEVIDWIDTH; length += (vid.width / vid.dup);
for (i = 0; i < MAXPLAYERS; i++) for (i = 0; i < MAXPLAYERS; i++)
if (playeringame[i] && players[i].spectator) if (playeringame[i] && players[i].spectator)
{ {
char *pos; if (length >= -((signed)strlen(player_names[i]) * 8 + 16) && length <= (vid.width / vid.dup))
char initial[MAXPLAYERNAME+1]; V_DrawString(length, height + 8, V_TRANSLUCENT|V_ALLOWLOWERCASE|V_SNAPTOLEFT, player_names[i]);
char current[MAXPLAYERNAME+1];
strcpy(initial, player_names[i]);
pos = initial;
if (length >= -((signed)strlen(player_names[i]) * 8 + 16) && length <= BASEVIDWIDTH)
{
if (length < 0)
{
UINT8 eatenchars = (UINT8)(abs(length) / 8 + 1);
if (eatenchars <= strlen(initial))
{
// Eat one letter off the left side,
// then compensate the drawing position.
pos += eatenchars;
strcpy(current, pos);
templength = length % 8 + 8;
}
else
{
strcpy(current, " ");
templength = length;
}
}
else
{
strcpy(current, initial);
templength = length;
}
V_DrawString(templength, height + 8, V_TRANSLUCENT|V_ALLOWLOWERCASE, current);
}
length += (signed)strlen(player_names[i]) * 8 + 16; length += (signed)strlen(player_names[i]) * 8 + 16;
} }
@ -2769,7 +2493,8 @@ static void HU_DrawRankings(void)
UINT32 whiteplayer; UINT32 whiteplayer;
// draw the current gametype in the lower right // draw the current gametype in the lower right
HU_drawGametype(); if (gametype >= 0 && gametype < gametypecount)
V_DrawString(4, splitscreen ? 184 : 192, 0, Gametype_Names[gametype]);
if (gametyperules & (GTR_TIMELIMIT|GTR_POINTLIMIT)) if (gametyperules & (GTR_TIMELIMIT|GTR_POINTLIMIT))
{ {
@ -2982,7 +2707,7 @@ void HU_DoCEcho(const char *msg)
{ {
I_OutputMsg("%s\n", msg); // print to log I_OutputMsg("%s\n", msg); // print to log
strncpy(cechotext, msg, sizeof(cechotext)); strncpy(cechotext, msg, sizeof(cechotext)-1);
strncat(cechotext, "\\", sizeof(cechotext) - strlen(cechotext) - 1); strncat(cechotext, "\\", sizeof(cechotext) - strlen(cechotext) - 1);
cechotext[sizeof(cechotext) - 1] = '\0'; cechotext[sizeof(cechotext) - 1] = '\0';
cechotimer = cechoduration; cechotimer = cechoduration;

View file

@ -19,33 +19,34 @@
#include "r_defs.h" #include "r_defs.h"
//------------------------------------ //------------------------------------
// heads up font // Fonts & stuff
//------------------------------------ //------------------------------------
#define HU_FONTSTART '\x16' // the first font character #define FONTSTART '\x16' // the first font character
#define HU_FONTEND '~' #define FONTEND '~'
#define FONTSIZE (FONTEND - FONTSTART + 1)
#define HU_FONTSIZE (HU_FONTEND - HU_FONTSTART + 1)
// Level title font
#define LT_FONTSTART '!' // the first font characters
#define LT_FONTEND 'z' // the last font characters
#define LT_FONTSIZE (LT_FONTEND - LT_FONTSTART + 1)
#define CRED_FONTSTART '!' // the first font character
#define CRED_FONTEND 'Z' // the last font character
#define CRED_FONTSIZE (CRED_FONTEND - CRED_FONTSTART + 1)
// Name tag font
// Used by base and outline font set
#define NT_FONTSTART '!' // the first font character
#define NT_FONTEND 'Z' // the last font character
#define NT_FONTSIZE (NT_FONTEND - NT_FONTSTART + 1)
#define HU_CROSSHAIRS 3 // maximum of 9 - see HU_Init(); #define HU_CROSSHAIRS 3 // maximum of 9 - see HU_Init();
extern char *shiftxform; // english translation shift table extern char *shiftxform; // english translation shift table
extern char english_shiftxform[]; extern char english_shiftxform[];
typedef struct
{
patch_t *chars[FONTSIZE];
INT32 kerning;
UINT32 spacewidth;
UINT32 charwidth;
UINT32 linespacing;
} fontdef_t;
extern fontdef_t hu_font, tny_font, cred_font, lt_font;
extern fontdef_t ntb_font, nto_font;
extern patch_t *tallnum[10];
extern patch_t *nightsnum[10];
extern patch_t *ttlnum[10];
extern patch_t *tallminus;
extern patch_t *tallinfin;
//------------------------------------ //------------------------------------
// sorted player lines // sorted player lines
//------------------------------------ //------------------------------------
@ -69,8 +70,8 @@ typedef struct
#else #else
#define OLDCHAT (cv_consolechat.value == 1 || dedicated || vid.width < 640 || splitscreen) #define OLDCHAT (cv_consolechat.value == 1 || dedicated || vid.width < 640 || splitscreen)
#endif #endif
#define CHAT_MUTE (cv_mute.value && !(server || IsPlayerAdmin(consoleplayer))) // this still allows to open the chat but not to type. That's used for scrolling and whatnot. #define CHAT_MUTE ((cv_mute.value || players[consoleplayer].muted) && !(server || IsPlayerAdmin(consoleplayer))) // this still allows to open the chat but not to type. That's used for scrolling and whatnot.
#define OLD_MUTE (OLDCHAT && cv_mute.value && !(server || IsPlayerAdmin(consoleplayer))) // this is used to prevent oldchat from opening when muted. #define OLD_MUTE (OLDCHAT && (cv_mute.value || players[consoleplayer].muted) && !(server || IsPlayerAdmin(consoleplayer))) // this is used to prevent oldchat from opening when muted.
// some functions // some functions
void HU_AddChatText(const char *text, boolean playsound); void HU_AddChatText(const char *text, boolean playsound);
@ -78,22 +79,12 @@ void HU_AddChatText(const char *text, boolean playsound);
// set true when entering a chat message // set true when entering a chat message
extern boolean chat_on; extern boolean chat_on;
extern patch_t *hu_font[HU_FONTSIZE], *tny_font[HU_FONTSIZE];
extern patch_t *tallnum[10];
extern patch_t *nightsnum[10];
extern patch_t *lt_font[LT_FONTSIZE];
extern patch_t *cred_font[CRED_FONTSIZE];
extern patch_t *ntb_font[NT_FONTSIZE];
extern patch_t *nto_font[NT_FONTSIZE];
extern patch_t *ttlnum[10];
extern patch_t *emeraldpics[3][8]; extern patch_t *emeraldpics[3][8];
extern patch_t *rflagico; extern patch_t *rflagico;
extern patch_t *bflagico; extern patch_t *bflagico;
extern patch_t *rmatcico; extern patch_t *rmatcico;
extern patch_t *bmatcico; extern patch_t *bmatcico;
extern patch_t *tagico; extern patch_t *tagico;
extern patch_t *tallminus;
extern patch_t *tallinfin;
extern patch_t *tokenicon; extern patch_t *tokenicon;
// set true whenever the tab rankings are being shown for any reason // set true whenever the tab rankings are being shown for any reason
@ -103,6 +94,8 @@ extern boolean hu_showscores;
void HU_Init(void); void HU_Init(void);
void HU_LoadGraphics(void); void HU_LoadGraphics(void);
void HU_LoadFontCharacters(fontdef_t *font, const char *prefix);
void HU_SetFontProperties(fontdef_t *font, INT32 kerning, UINT32 spacewidth, UINT32 charwidth, UINT32 linespacing);
// reset heads up when consoleplayer respawns. // reset heads up when consoleplayer respawns.
void HU_Start(void); void HU_Start(void);

View file

@ -339,4 +339,12 @@ void I_SetMouseGrab(boolean grab);
*/ */
const char *I_GetSysName(void); const char *I_GetSysName(void);
/** \brief Sets text input mode. When enabled, keyboard inputs will respect dead keys.
*/
void I_SetTextInputMode(boolean active);
/** \brief Retrieves current text input mode.
*/
boolean I_GetTextInputMode(void);
#endif #endif

5299
src/info.c

File diff suppressed because it is too large Load diff

View file

@ -298,276 +298,278 @@ enum actionnum
NUMACTIONS NUMACTIONS
}; };
struct mobj_s;
// IMPORTANT NOTE: If you add/remove from this list of action // IMPORTANT NOTE: If you add/remove from this list of action
// functions, don't forget to update them in deh_tables.c! // functions, don't forget to update them in deh_tables.c!
void A_Explode(); void A_Explode(struct mobj_s *actor);
void A_Pain(); void A_Pain(struct mobj_s *actor);
void A_Fall(); void A_Fall(struct mobj_s *actor);
void A_MonitorPop(); void A_MonitorPop(struct mobj_s *actor);
void A_GoldMonitorPop(); void A_GoldMonitorPop(struct mobj_s *actor);
void A_GoldMonitorRestore(); void A_GoldMonitorRestore(struct mobj_s *actor);
void A_GoldMonitorSparkle(); void A_GoldMonitorSparkle(struct mobj_s *actor);
void A_Look(); void A_Look(struct mobj_s *actor);
void A_Chase(); void A_Chase(struct mobj_s *actor);
void A_FaceStabChase(); void A_FaceStabChase(struct mobj_s *actor);
void A_FaceStabRev(); void A_FaceStabRev(struct mobj_s *actor);
void A_FaceStabHurl(); void A_FaceStabHurl(struct mobj_s *actor);
void A_FaceStabMiss(); void A_FaceStabMiss(struct mobj_s *actor);
void A_StatueBurst(); void A_StatueBurst(struct mobj_s *actor);
void A_FaceTarget(); void A_FaceTarget(struct mobj_s *actor);
void A_FaceTracer(); void A_FaceTracer(struct mobj_s *actor);
void A_Scream(); void A_Scream(struct mobj_s *actor);
void A_BossDeath(); void A_BossDeath(struct mobj_s *actor);
void A_SetShadowScale(); void A_SetShadowScale(struct mobj_s *actor);
void A_ShadowScream(); // MARIA!!!!!! void A_ShadowScream(struct mobj_s *actor); // MARIA!!!!!!
void A_CustomPower(); // Use this for a custom power void A_CustomPower(struct mobj_s *actor); // Use this for a custom power
void A_GiveWeapon(); // Gives the player weapon(s) void A_GiveWeapon(struct mobj_s *actor); // Gives the player weapon(s)
void A_RingBox(); // Obtained Ring Box Tails void A_RingBox(struct mobj_s *actor); // Obtained Ring Box Tails
void A_Invincibility(); // Obtained Invincibility Box void A_Invincibility(struct mobj_s *actor); // Obtained Invincibility Box
void A_SuperSneakers(); // Obtained Super Sneakers Box void A_SuperSneakers(struct mobj_s *actor); // Obtained Super Sneakers Box
void A_BunnyHop(); // have bunny hop tails void A_BunnyHop(struct mobj_s *actor); // have bunny hop tails
void A_BubbleSpawn(); // Randomly spawn bubbles void A_BubbleSpawn(struct mobj_s *actor); // Randomly spawn bubbles
void A_FanBubbleSpawn(); void A_FanBubbleSpawn(struct mobj_s *actor);
void A_BubbleRise(); // Bubbles float to surface void A_BubbleRise(struct mobj_s *actor); // Bubbles float to surface
void A_BubbleCheck(); // Don't draw if not underwater void A_BubbleCheck(struct mobj_s *actor); // Don't draw if not underwater
void A_AwardScore(); void A_AwardScore(struct mobj_s *actor);
void A_ExtraLife(); // Extra Life void A_ExtraLife(struct mobj_s *actor); // Extra Life
void A_GiveShield(); // Obtained Shield void A_GiveShield(struct mobj_s *actor); // Obtained Shield
void A_GravityBox(); void A_GravityBox(struct mobj_s *actor);
void A_ScoreRise(); // Rise the score logo void A_ScoreRise(struct mobj_s *actor); // Rise the score logo
void A_AttractChase(); // Ring Chase void A_AttractChase(struct mobj_s *actor); // Ring Chase
void A_DropMine(); // Drop Mine from Skim or Jetty-Syn Bomber void A_DropMine(struct mobj_s *actor); // Drop Mine from Skim or Jetty-Syn Bomber
void A_FishJump(); // Fish Jump void A_FishJump(struct mobj_s *actor); // Fish Jump
void A_ThrownRing(); // Sparkle trail for red ring void A_ThrownRing(struct mobj_s *actor); // Sparkle trail for red ring
void A_SetSolidSteam(); void A_SetSolidSteam(struct mobj_s *actor);
void A_UnsetSolidSteam(); void A_UnsetSolidSteam(struct mobj_s *actor);
void A_SignSpin(); void A_SignSpin(struct mobj_s *actor);
void A_SignPlayer(); void A_SignPlayer(struct mobj_s *actor);
void A_OverlayThink(); void A_OverlayThink(struct mobj_s *actor);
void A_JetChase(); void A_JetChase(struct mobj_s *actor);
void A_JetbThink(); // Jetty-Syn Bomber Thinker void A_JetbThink(struct mobj_s *actor); // Jetty-Syn Bomber Thinker
void A_JetgThink(); // Jetty-Syn Gunner Thinker void A_JetgThink(struct mobj_s *actor); // Jetty-Syn Gunner Thinker
void A_JetgShoot(); // Jetty-Syn Shoot Function void A_JetgShoot(struct mobj_s *actor); // Jetty-Syn Shoot Function
void A_ShootBullet(); // JetgShoot without reactiontime setting void A_ShootBullet(struct mobj_s *actor); // JetgShoot without reactiontime setting
void A_MinusDigging(); void A_MinusDigging(struct mobj_s *actor);
void A_MinusPopup(); void A_MinusPopup(struct mobj_s *actor);
void A_MinusCheck(); void A_MinusCheck(struct mobj_s *actor);
void A_ChickenCheck(); void A_ChickenCheck(struct mobj_s *actor);
void A_MouseThink(); // Mouse Thinker void A_MouseThink(struct mobj_s *actor); // Mouse Thinker
void A_DetonChase(); // Deton Chaser void A_DetonChase(struct mobj_s *actor); // Deton Chaser
void A_CapeChase(); // Fake little Super Sonic cape void A_CapeChase(struct mobj_s *actor); // Fake little Super Sonic cape
void A_RotateSpikeBall(); // Spike ball rotation void A_RotateSpikeBall(struct mobj_s *actor); // Spike ball rotation
void A_SlingAppear(); void A_SlingAppear(struct mobj_s *actor);
void A_UnidusBall(); void A_UnidusBall(struct mobj_s *actor);
void A_RockSpawn(); void A_RockSpawn(struct mobj_s *actor);
void A_SetFuse(); void A_SetFuse(struct mobj_s *actor);
void A_CrawlaCommanderThink(); // Crawla Commander void A_CrawlaCommanderThink(struct mobj_s *actor); // Crawla Commander
void A_SmokeTrailer(); void A_SmokeTrailer(struct mobj_s *actor);
void A_RingExplode(); void A_RingExplode(struct mobj_s *actor);
void A_OldRingExplode(); void A_OldRingExplode(struct mobj_s *actor);
void A_MixUp(); void A_MixUp(struct mobj_s *actor);
void A_RecyclePowers(); void A_RecyclePowers(struct mobj_s *actor);
void A_BossScream(); void A_BossScream(struct mobj_s *actor);
void A_Boss2TakeDamage(); void A_Boss2TakeDamage(struct mobj_s *actor);
void A_GoopSplat(); void A_GoopSplat(struct mobj_s *actor);
void A_Boss2PogoSFX(); void A_Boss2PogoSFX(struct mobj_s *actor);
void A_Boss2PogoTarget(); void A_Boss2PogoTarget(struct mobj_s *actor);
void A_EggmanBox(); void A_EggmanBox(struct mobj_s *actor);
void A_TurretFire(); void A_TurretFire(struct mobj_s *actor);
void A_SuperTurretFire(); void A_SuperTurretFire(struct mobj_s *actor);
void A_TurretStop(); void A_TurretStop(struct mobj_s *actor);
void A_JetJawRoam(); void A_JetJawRoam(struct mobj_s *actor);
void A_JetJawChomp(); void A_JetJawChomp(struct mobj_s *actor);
void A_PointyThink(); void A_PointyThink(struct mobj_s *actor);
void A_CheckBuddy(); void A_CheckBuddy(struct mobj_s *actor);
void A_HoodFire(); void A_HoodFire(struct mobj_s *actor);
void A_HoodThink(); void A_HoodThink(struct mobj_s *actor);
void A_HoodFall(); void A_HoodFall(struct mobj_s *actor);
void A_ArrowBonks(); void A_ArrowBonks(struct mobj_s *actor);
void A_SnailerThink(); void A_SnailerThink(struct mobj_s *actor);
void A_SharpChase(); void A_SharpChase(struct mobj_s *actor);
void A_SharpSpin(); void A_SharpSpin(struct mobj_s *actor);
void A_SharpDecel(); void A_SharpDecel(struct mobj_s *actor);
void A_CrushstaceanWalk(); void A_CrushstaceanWalk(struct mobj_s *actor);
void A_CrushstaceanPunch(); void A_CrushstaceanPunch(struct mobj_s *actor);
void A_CrushclawAim(); void A_CrushclawAim(struct mobj_s *actor);
void A_CrushclawLaunch(); void A_CrushclawLaunch(struct mobj_s *actor);
void A_VultureVtol(); void A_VultureVtol(struct mobj_s *actor);
void A_VultureCheck(); void A_VultureCheck(struct mobj_s *actor);
void A_VultureHover(); void A_VultureHover(struct mobj_s *actor);
void A_VultureBlast(); void A_VultureBlast(struct mobj_s *actor);
void A_VultureFly(); void A_VultureFly(struct mobj_s *actor);
void A_SkimChase(); void A_SkimChase(struct mobj_s *actor);
void A_SkullAttack(); void A_SkullAttack(struct mobj_s *actor);
void A_LobShot(); void A_LobShot(struct mobj_s *actor);
void A_FireShot(); void A_FireShot(struct mobj_s *actor);
void A_SuperFireShot(); void A_SuperFireShot(struct mobj_s *actor);
void A_BossFireShot(); void A_BossFireShot(struct mobj_s *actor);
void A_Boss7FireMissiles(); void A_Boss7FireMissiles(struct mobj_s *actor);
void A_Boss1Laser(); void A_Boss1Laser(struct mobj_s *actor);
void A_FocusTarget(); void A_FocusTarget(struct mobj_s *actor);
void A_Boss4Reverse(); void A_Boss4Reverse(struct mobj_s *actor);
void A_Boss4SpeedUp(); void A_Boss4SpeedUp(struct mobj_s *actor);
void A_Boss4Raise(); void A_Boss4Raise(struct mobj_s *actor);
void A_SparkFollow(); void A_SparkFollow(struct mobj_s *actor);
void A_BuzzFly(); void A_BuzzFly(struct mobj_s *actor);
void A_GuardChase(); void A_GuardChase(struct mobj_s *actor);
void A_EggShield(); void A_EggShield(struct mobj_s *actor);
void A_SetReactionTime(); void A_SetReactionTime(struct mobj_s *actor);
void A_Boss1Spikeballs(); void A_Boss1Spikeballs(struct mobj_s *actor);
void A_Boss3TakeDamage(); void A_Boss3TakeDamage(struct mobj_s *actor);
void A_Boss3Path(); void A_Boss3Path(struct mobj_s *actor);
void A_Boss3ShockThink(); void A_Boss3ShockThink(struct mobj_s *actor);
void A_Shockwave(); void A_Shockwave(struct mobj_s *actor);
void A_LinedefExecute(); void A_LinedefExecute(struct mobj_s *actor);
void A_LinedefExecuteFromArg(); void A_LinedefExecuteFromArg(struct mobj_s *actor);
void A_PlaySeeSound(); void A_PlaySeeSound(struct mobj_s *actor);
void A_PlayAttackSound(); void A_PlayAttackSound(struct mobj_s *actor);
void A_PlayActiveSound(); void A_PlayActiveSound(struct mobj_s *actor);
void A_1upThinker(); void A_1upThinker(struct mobj_s *actor);
void A_BossZoom(); //Unused void A_BossZoom(struct mobj_s *actor); //Unused
void A_Boss1Chase(); void A_Boss1Chase(struct mobj_s *actor);
void A_Boss2Chase(); void A_Boss2Chase(struct mobj_s *actor);
void A_Boss2Pogo(); void A_Boss2Pogo(struct mobj_s *actor);
void A_Boss7Chase(); void A_Boss7Chase(struct mobj_s *actor);
void A_BossJetFume(); void A_BossJetFume(struct mobj_s *actor);
void A_SpawnObjectAbsolute(); void A_SpawnObjectAbsolute(struct mobj_s *actor);
void A_SpawnObjectRelative(); void A_SpawnObjectRelative(struct mobj_s *actor);
void A_ChangeAngleRelative(); void A_ChangeAngleRelative(struct mobj_s *actor);
void A_ChangeAngleAbsolute(); void A_ChangeAngleAbsolute(struct mobj_s *actor);
void A_RollAngle(); void A_RollAngle(struct mobj_s *actor);
void A_ChangeRollAngleRelative(); void A_ChangeRollAngleRelative(struct mobj_s *actor);
void A_ChangeRollAngleAbsolute(); void A_ChangeRollAngleAbsolute(struct mobj_s *actor);
void A_PlaySound(); void A_PlaySound(struct mobj_s *actor);
void A_FindTarget(); void A_FindTarget(struct mobj_s *actor);
void A_FindTracer(); void A_FindTracer(struct mobj_s *actor);
void A_SetTics(); void A_SetTics(struct mobj_s *actor);
void A_SetRandomTics(); void A_SetRandomTics(struct mobj_s *actor);
void A_ChangeColorRelative(); void A_ChangeColorRelative(struct mobj_s *actor);
void A_ChangeColorAbsolute(); void A_ChangeColorAbsolute(struct mobj_s *actor);
void A_Dye(); void A_Dye(struct mobj_s *actor);
void A_SetTranslation(); void A_SetTranslation(struct mobj_s *actor);
void A_MoveRelative(); void A_MoveRelative(struct mobj_s *actor);
void A_MoveAbsolute(); void A_MoveAbsolute(struct mobj_s *actor);
void A_Thrust(); void A_Thrust(struct mobj_s *actor);
void A_ZThrust(); void A_ZThrust(struct mobj_s *actor);
void A_SetTargetsTarget(); void A_SetTargetsTarget(struct mobj_s *actor);
void A_SetObjectFlags(); void A_SetObjectFlags(struct mobj_s *actor);
void A_SetObjectFlags2(); void A_SetObjectFlags2(struct mobj_s *actor);
void A_RandomState(); void A_RandomState(struct mobj_s *actor);
void A_RandomStateRange(); void A_RandomStateRange(struct mobj_s *actor);
void A_StateRangeByAngle(); void A_StateRangeByAngle(struct mobj_s *actor);
void A_StateRangeByParameter(); void A_StateRangeByParameter(struct mobj_s *actor);
void A_DualAction(); void A_DualAction(struct mobj_s *actor);
void A_RemoteAction(); void A_RemoteAction(struct mobj_s *actor);
void A_ToggleFlameJet(); void A_ToggleFlameJet(struct mobj_s *actor);
void A_OrbitNights(); void A_OrbitNights(struct mobj_s *actor);
void A_GhostMe(); void A_GhostMe(struct mobj_s *actor);
void A_SetObjectState(); void A_SetObjectState(struct mobj_s *actor);
void A_SetObjectTypeState(); void A_SetObjectTypeState(struct mobj_s *actor);
void A_KnockBack(); void A_KnockBack(struct mobj_s *actor);
void A_PushAway(); void A_PushAway(struct mobj_s *actor);
void A_RingDrain(); void A_RingDrain(struct mobj_s *actor);
void A_SplitShot(); void A_SplitShot(struct mobj_s *actor);
void A_MissileSplit(); void A_MissileSplit(struct mobj_s *actor);
void A_MultiShot(); void A_MultiShot(struct mobj_s *actor);
void A_InstaLoop(); void A_InstaLoop(struct mobj_s *actor);
void A_Custom3DRotate(); void A_Custom3DRotate(struct mobj_s *actor);
void A_SearchForPlayers(); void A_SearchForPlayers(struct mobj_s *actor);
void A_CheckRandom(); void A_CheckRandom(struct mobj_s *actor);
void A_CheckTargetRings(); void A_CheckTargetRings(struct mobj_s *actor);
void A_CheckRings(); void A_CheckRings(struct mobj_s *actor);
void A_CheckTotalRings(); void A_CheckTotalRings(struct mobj_s *actor);
void A_CheckHealth(); void A_CheckHealth(struct mobj_s *actor);
void A_CheckRange(); void A_CheckRange(struct mobj_s *actor);
void A_CheckHeight(); void A_CheckHeight(struct mobj_s *actor);
void A_CheckTrueRange(); void A_CheckTrueRange(struct mobj_s *actor);
void A_CheckThingCount(); void A_CheckThingCount(struct mobj_s *actor);
void A_CheckAmbush(); void A_CheckAmbush(struct mobj_s *actor);
void A_CheckCustomValue(); void A_CheckCustomValue(struct mobj_s *actor);
void A_CheckCusValMemo(); void A_CheckCusValMemo(struct mobj_s *actor);
void A_SetCustomValue(); void A_SetCustomValue(struct mobj_s *actor);
void A_UseCusValMemo(); void A_UseCusValMemo(struct mobj_s *actor);
void A_RelayCustomValue(); void A_RelayCustomValue(struct mobj_s *actor);
void A_CusValAction(); void A_CusValAction(struct mobj_s *actor);
void A_ForceStop(); void A_ForceStop(struct mobj_s *actor);
void A_ForceWin(); void A_ForceWin(struct mobj_s *actor);
void A_SpikeRetract(); void A_SpikeRetract(struct mobj_s *actor);
void A_InfoState(); void A_InfoState(struct mobj_s *actor);
void A_Repeat(); void A_Repeat(struct mobj_s *actor);
void A_SetScale(); void A_SetScale(struct mobj_s *actor);
void A_RemoteDamage(); void A_RemoteDamage(struct mobj_s *actor);
void A_HomingChase(); void A_HomingChase(struct mobj_s *actor);
void A_TrapShot(); void A_TrapShot(struct mobj_s *actor);
void A_VileTarget(); void A_VileTarget(struct mobj_s *actor);
void A_VileAttack(); void A_VileAttack(struct mobj_s *actor);
void A_VileFire(); void A_VileFire(struct mobj_s *actor);
void A_BrakChase(); void A_BrakChase(struct mobj_s *actor);
void A_BrakFireShot(); void A_BrakFireShot(struct mobj_s *actor);
void A_BrakLobShot(); void A_BrakLobShot(struct mobj_s *actor);
void A_NapalmScatter(); void A_NapalmScatter(struct mobj_s *actor);
void A_SpawnFreshCopy(); void A_SpawnFreshCopy(struct mobj_s *actor);
void A_FlickySpawn(); void A_FlickySpawn(struct mobj_s *actor);
void A_FlickyCenter(); void A_FlickyCenter(struct mobj_s *actor);
void A_FlickyAim(); void A_FlickyAim(struct mobj_s *actor);
void A_FlickyFly(); void A_FlickyFly(struct mobj_s *actor);
void A_FlickySoar(); void A_FlickySoar(struct mobj_s *actor);
void A_FlickyCoast(); void A_FlickyCoast(struct mobj_s *actor);
void A_FlickyHop(); void A_FlickyHop(struct mobj_s *actor);
void A_FlickyFlounder(); void A_FlickyFlounder(struct mobj_s *actor);
void A_FlickyCheck(); void A_FlickyCheck(struct mobj_s *actor);
void A_FlickyHeightCheck(); void A_FlickyHeightCheck(struct mobj_s *actor);
void A_FlickyFlutter(); void A_FlickyFlutter(struct mobj_s *actor);
void A_FlameParticle(); void A_FlameParticle(struct mobj_s *actor);
void A_FadeOverlay(); void A_FadeOverlay(struct mobj_s *actor);
void A_Boss5Jump(); void A_Boss5Jump(struct mobj_s *actor);
void A_LightBeamReset(); void A_LightBeamReset(struct mobj_s *actor);
void A_MineExplode(); void A_MineExplode(struct mobj_s *actor);
void A_MineRange(); void A_MineRange(struct mobj_s *actor);
void A_ConnectToGround(); void A_ConnectToGround(struct mobj_s *actor);
void A_SpawnParticleRelative(); void A_SpawnParticleRelative(struct mobj_s *actor);
void A_MultiShotDist(); void A_MultiShotDist(struct mobj_s *actor);
void A_WhoCaresIfYourSonIsABee(); void A_WhoCaresIfYourSonIsABee(struct mobj_s *actor);
void A_ParentTriesToSleep(); void A_ParentTriesToSleep(struct mobj_s *actor);
void A_CryingToMomma(); void A_CryingToMomma(struct mobj_s *actor);
void A_CheckFlags2(); void A_CheckFlags2(struct mobj_s *actor);
void A_Boss5FindWaypoint(); void A_Boss5FindWaypoint(struct mobj_s *actor);
void A_DoNPCSkid(); void A_DoNPCSkid(struct mobj_s *actor);
void A_DoNPCPain(); void A_DoNPCPain(struct mobj_s *actor);
void A_PrepareRepeat(); void A_PrepareRepeat(struct mobj_s *actor);
void A_Boss5ExtraRepeat(); void A_Boss5ExtraRepeat(struct mobj_s *actor);
void A_Boss5Calm(); void A_Boss5Calm(struct mobj_s *actor);
void A_Boss5CheckOnGround(); void A_Boss5CheckOnGround(struct mobj_s *actor);
void A_Boss5CheckFalling(); void A_Boss5CheckFalling(struct mobj_s *actor);
void A_Boss5PinchShot(); void A_Boss5PinchShot(struct mobj_s *actor);
void A_Boss5MakeItRain(); void A_Boss5MakeItRain(struct mobj_s *actor);
void A_Boss5MakeJunk(); void A_Boss5MakeJunk(struct mobj_s *actor);
void A_LookForBetter(); void A_LookForBetter(struct mobj_s *actor);
void A_Boss5BombExplode(); void A_Boss5BombExplode(struct mobj_s *actor);
void A_DustDevilThink(); void A_DustDevilThink(struct mobj_s *actor);
void A_TNTExplode(); void A_TNTExplode(struct mobj_s *actor);
void A_DebrisRandom(); void A_DebrisRandom(struct mobj_s *actor);
void A_TrainCameo(); void A_TrainCameo(struct mobj_s *actor);
void A_TrainCameo2(); void A_TrainCameo2(struct mobj_s *actor);
void A_CanarivoreGas(); void A_CanarivoreGas(struct mobj_s *actor);
void A_KillSegments(); void A_KillSegments(struct mobj_s *actor);
void A_SnapperSpawn(); void A_SnapperSpawn(struct mobj_s *actor);
void A_SnapperThinker(); void A_SnapperThinker(struct mobj_s *actor);
void A_SaloonDoorSpawn(); void A_SaloonDoorSpawn(struct mobj_s *actor);
void A_MinecartSparkThink(); void A_MinecartSparkThink(struct mobj_s *actor);
void A_ModuloToState(); void A_ModuloToState(struct mobj_s *actor);
void A_LavafallRocks(); void A_LavafallRocks(struct mobj_s *actor);
void A_LavafallLava(); void A_LavafallLava(struct mobj_s *actor);
void A_FallingLavaCheck(); void A_FallingLavaCheck(struct mobj_s *actor);
void A_FireShrink(); void A_FireShrink(struct mobj_s *actor);
void A_SpawnPterabytes(); void A_SpawnPterabytes(struct mobj_s *actor);
void A_PterabyteHover(); void A_PterabyteHover(struct mobj_s *actor);
void A_RolloutSpawn(); void A_RolloutSpawn(struct mobj_s *actor);
void A_RolloutRock(); void A_RolloutRock(struct mobj_s *actor);
void A_DragonbomberSpawn(); void A_DragonbomberSpawn(struct mobj_s *actor);
void A_DragonWing(); void A_DragonWing(struct mobj_s *actor);
void A_DragonSegment(); void A_DragonSegment(struct mobj_s *actor);
void A_ChangeHeight(); void A_ChangeHeight(struct mobj_s *actor);
extern int actionsoverridden[NUMACTIONS][MAX_ACTION_RECURSION]; extern int actionsoverridden[NUMACTIONS][MAX_ACTION_RECURSION];
@ -575,6 +577,7 @@ extern int actionsoverridden[NUMACTIONS][MAX_ACTION_RECURSION];
#define NUMMOBJFREESLOTS 1024 #define NUMMOBJFREESLOTS 1024
#define NUMSPRITEFREESLOTS NUMMOBJFREESLOTS #define NUMSPRITEFREESLOTS NUMMOBJFREESLOTS
#define NUMSTATEFREESLOTS (NUMMOBJFREESLOTS*8) #define NUMSTATEFREESLOTS (NUMMOBJFREESLOTS*8)
#define MAXSPRITENAME 64
// Hey, moron! If you change this table, don't forget about sprnames in info.c and the sprite lights in hw_light.c! // Hey, moron! If you change this table, don't forget about sprnames in info.c and the sprite lights in hw_light.c!
typedef enum sprite typedef enum sprite
@ -1078,9 +1081,6 @@ typedef enum sprite
NUMSPRITES NUMSPRITES
} spritenum_t; } spritenum_t;
// Make sure to be conscious of FF_FRAMEMASK and the fact sprite2 is stored as a UINT8 whenever you change this table.
// Currently, FF_FRAMEMASK is 0xff, or 255 - but the second half is used by FF_SPR2SUPER, so the limitation is 0x7f.
// Since this is zero-based, there can be at most 128 different SPR2_'s without changing that.
typedef enum playersprite typedef enum playersprite
{ {
SPR2_STND = 0, SPR2_STND = 0,
@ -1160,15 +1160,17 @@ typedef enum playersprite
SPR2_XTRA, // stuff that isn't in-map - "would this ever need an md2 or variable length animation?" SPR2_XTRA, // stuff that isn't in-map - "would this ever need an md2 or variable length animation?"
SPR2_FIRSTFREESLOT, SPR2_FIRSTFREESLOT,
SPR2_LASTFREESLOT = 0x7f, SPR2_LASTFREESLOT = 1024, // Do not make higher than SPR2F_MASK (currently 0x3FF) plus one
NUMPLAYERSPRITES NUMPLAYERSPRITES
} playersprite_t; } playersprite_t;
// SPR2_XTRA enum
#define XTRA_LIFEPIC 0 // Life icon patch {
#define XTRA_CHARSEL 1 // Character select picture XTRA_LIFEPIC,
#define XTRA_CONTINUE 2 // Continue icon XTRA_CHARSEL,
#define XTRA_ENDING 3 // Ending finale patches XTRA_CONTINUE,
XTRA_ENDING
};
typedef enum state typedef enum state
{ {
@ -4380,11 +4382,12 @@ typedef struct
INT32 var1; INT32 var1;
INT32 var2; INT32 var2;
statenum_t nextstate; statenum_t nextstate;
UINT16 sprite2;
} state_t; } state_t;
extern state_t states[NUMSTATES]; extern state_t states[NUMSTATES];
extern char sprnames[NUMSPRITES + 1][5]; extern char sprnames[NUMSPRITES + 1][MAXSPRITENAME + 1];
extern char spr2names[NUMPLAYERSPRITES][5]; extern char spr2names[NUMPLAYERSPRITES][MAXSPRITENAME + 1];
extern playersprite_t spr2defaults[NUMPLAYERSPRITES]; extern playersprite_t spr2defaults[NUMPLAYERSPRITES];
extern state_t *astate; extern state_t *astate;
extern playersprite_t free_spr2; extern playersprite_t free_spr2;

View file

@ -44,6 +44,21 @@ return luaL_error(L, "HUD rendering code should not call this function!");\
else if (hook_cmd_running)\ else if (hook_cmd_running)\
return luaL_error(L, "CMD building code should not call this function!"); return luaL_error(L, "CMD building code should not call this function!");
#define NOSPAWNNULL if (type >= NUMMOBJTYPES)\
return luaL_error(L, "mobj type %d out of range (0 - %d)", type, NUMMOBJTYPES-1);\
else if (type == MT_NULL)\
{\
if (!nospawnnull_seen) {\
nospawnnull_seen = true;\
CONS_Alert(CONS_WARNING,"Spawning an \"MT_NULL\" mobj is deprecated and will be removed.\nUse \"MT_RAY\" instead.\n");\
}\
type = MT_RAY;\
}
static boolean nospawnnull_seen = false; // TODO: 2.3: Delete
// TODO: 2.3: Use the below NOSPAWNNULL define instead. P_SpawnMobj used to say "if MT_NULL, use MT_RAY instead", so the above define maintains Lua script compatibility until v2.3
/*#define NOSPAWNNULL if (type <= MT_NULL || type >= NUMMOBJTYPES)\
return luaL_error(L, "mobj type %d out of range (1 - %d)", type, NUMMOBJTYPES-1);*/
boolean luaL_checkboolean(lua_State *L, int narg) { boolean luaL_checkboolean(lua_State *L, int narg) {
luaL_checktype(L, narg, LUA_TBOOLEAN); luaL_checktype(L, narg, LUA_TBOOLEAN);
return lua_toboolean(L, narg); return lua_toboolean(L, narg);
@ -169,8 +184,10 @@ static const struct {
{META_SKIN, "skin_t"}, {META_SKIN, "skin_t"},
{META_POWERS, "player_t.powers"}, {META_POWERS, "player_t.powers"},
{META_SOUNDSID, "skin_t.soundsid"}, {META_SOUNDSID, "skin_t.soundsid"},
{META_SKINSPRITES, "skin_t.sprites"},
{META_SKINSPRITESLIST, "skin_t.sprites[]"}, {META_SKINSPRITES, "skin_t.skinsprites"},
{META_SKINSPRITESLIST, "skin_t.skinsprites[]"},
{META_SKINSPRITESCOMPAT, "skin_t.sprites"}, // TODO: 2.3: Delete
{META_VERTEX, "vertex_t"}, {META_VERTEX, "vertex_t"},
{META_LINE, "line_t"}, {META_LINE, "line_t"},
@ -330,6 +347,18 @@ static int lib_reserveLuabanks(lua_State *L)
return 1; return 1;
} }
static int lib_tofixed(lua_State *L)
{
const char *arg = luaL_checkstring(L, 1);
char *end;
float f = strtof(arg, &end);
if (*end != '\0')
lua_pushnil(L);
else
lua_pushnumber(L, FLOAT_TO_FIXED(f));
return 1;
}
// M_MENU // M_MENU
////////////// //////////////
@ -625,9 +654,8 @@ static int lib_pSpawnMobj(lua_State *L)
mobjtype_t type = luaL_checkinteger(L, 4); mobjtype_t type = luaL_checkinteger(L, 4);
NOHUD NOHUD
INLEVEL INLEVEL
if (type >= NUMMOBJTYPES) NOSPAWNNULL
return luaL_error(L, "mobj type %d out of range (0 - %d)", type, NUMMOBJTYPES-1); LUA_PushUserdata(L, P_SpawnMobj(x, y, z, type, NULL), META_MOBJ);
LUA_PushUserdata(L, P_SpawnMobj(x, y, z, type), META_MOBJ);
return 1; return 1;
} }
@ -640,10 +668,9 @@ static int lib_pSpawnMobjFromMobj(lua_State *L)
mobjtype_t type = luaL_checkinteger(L, 5); mobjtype_t type = luaL_checkinteger(L, 5);
NOHUD NOHUD
INLEVEL INLEVEL
NOSPAWNNULL
if (!actor) if (!actor)
return LUA_ErrInvalid(L, "mobj_t"); return LUA_ErrInvalid(L, "mobj_t");
if (type >= NUMMOBJTYPES)
return luaL_error(L, "mobj type %d out of range (0 - %d)", type, NUMMOBJTYPES-1);
LUA_PushUserdata(L, P_SpawnMobjFromMobj(actor, x, y, z, type), META_MOBJ); LUA_PushUserdata(L, P_SpawnMobjFromMobj(actor, x, y, z, type), META_MOBJ);
return 1; return 1;
} }
@ -661,17 +688,15 @@ static int lib_pRemoveMobj(lua_State *L)
return 0; return 0;
} }
// P_IsValidSprite2 technically doesn't exist, and probably never should... but too much would need to be exposed to allow this to be checked by other methods.
static int lib_pIsValidSprite2(lua_State *L) static int lib_pIsValidSprite2(lua_State *L)
{ {
mobj_t *mobj = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); mobj_t *mobj = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
UINT8 spr2 = (UINT8)luaL_checkinteger(L, 2); UINT16 spr2 = (UINT16)luaL_checkinteger(L, 2);
//HUDSAFE //HUDSAFE
INLEVEL INLEVEL
if (!mobj) if (!mobj)
return LUA_ErrInvalid(L, "mobj_t"); return LUA_ErrInvalid(L, "mobj_t");
lua_pushboolean(L, (mobj->skin && (((skin_t *)mobj->skin)->sprites[spr2].numframes))); lua_pushboolean(L, mobj->skin && P_IsValidSprite2(mobj->skin, spr2));
return 1; return 1;
} }
@ -708,10 +733,9 @@ static int lib_pSpawnMissile(lua_State *L)
mobjtype_t type = luaL_checkinteger(L, 3); mobjtype_t type = luaL_checkinteger(L, 3);
NOHUD NOHUD
INLEVEL INLEVEL
NOSPAWNNULL
if (!source || !dest) if (!source || !dest)
return LUA_ErrInvalid(L, "mobj_t"); return LUA_ErrInvalid(L, "mobj_t");
if (type >= NUMMOBJTYPES)
return luaL_error(L, "mobj type %d out of range (0 - %d)", type, NUMMOBJTYPES-1);
LUA_PushUserdata(L, P_SpawnMissile(source, dest, type), META_MOBJ); LUA_PushUserdata(L, P_SpawnMissile(source, dest, type), META_MOBJ);
return 1; return 1;
} }
@ -726,10 +750,9 @@ static int lib_pSpawnXYZMissile(lua_State *L)
fixed_t z = luaL_checkfixed(L, 6); fixed_t z = luaL_checkfixed(L, 6);
NOHUD NOHUD
INLEVEL INLEVEL
NOSPAWNNULL
if (!source || !dest) if (!source || !dest)
return LUA_ErrInvalid(L, "mobj_t"); return LUA_ErrInvalid(L, "mobj_t");
if (type >= NUMMOBJTYPES)
return luaL_error(L, "mobj type %d out of range (0 - %d)", type, NUMMOBJTYPES-1);
LUA_PushUserdata(L, P_SpawnXYZMissile(source, dest, type, x, y, z), META_MOBJ); LUA_PushUserdata(L, P_SpawnXYZMissile(source, dest, type, x, y, z), META_MOBJ);
return 1; return 1;
} }
@ -746,10 +769,9 @@ static int lib_pSpawnPointMissile(lua_State *L)
fixed_t z = luaL_checkfixed(L, 8); fixed_t z = luaL_checkfixed(L, 8);
NOHUD NOHUD
INLEVEL INLEVEL
NOSPAWNNULL
if (!source) if (!source)
return LUA_ErrInvalid(L, "mobj_t"); return LUA_ErrInvalid(L, "mobj_t");
if (type >= NUMMOBJTYPES)
return luaL_error(L, "mobj type %d out of range (0 - %d)", type, NUMMOBJTYPES-1);
LUA_PushUserdata(L, P_SpawnPointMissile(source, xa, ya, za, type, x, y, z), META_MOBJ); LUA_PushUserdata(L, P_SpawnPointMissile(source, xa, ya, za, type, x, y, z), META_MOBJ);
return 1; return 1;
} }
@ -764,10 +786,9 @@ static int lib_pSpawnAlteredDirectionMissile(lua_State *L)
INT32 shiftingAngle = (INT32)luaL_checkinteger(L, 5); INT32 shiftingAngle = (INT32)luaL_checkinteger(L, 5);
NOHUD NOHUD
INLEVEL INLEVEL
NOSPAWNNULL
if (!source) if (!source)
return LUA_ErrInvalid(L, "mobj_t"); return LUA_ErrInvalid(L, "mobj_t");
if (type >= NUMMOBJTYPES)
return luaL_error(L, "mobj type %d out of range (0 - %d)", type, NUMMOBJTYPES-1);
LUA_PushUserdata(L, P_SpawnAlteredDirectionMissile(source, type, x, y, z, shiftingAngle), META_MOBJ); LUA_PushUserdata(L, P_SpawnAlteredDirectionMissile(source, type, x, y, z, shiftingAngle), META_MOBJ);
return 1; return 1;
} }
@ -795,10 +816,9 @@ static int lib_pSPMAngle(lua_State *L)
UINT32 flags2 = (UINT32)luaL_optinteger(L, 5, 0); UINT32 flags2 = (UINT32)luaL_optinteger(L, 5, 0);
NOHUD NOHUD
INLEVEL INLEVEL
NOSPAWNNULL
if (!source) if (!source)
return LUA_ErrInvalid(L, "mobj_t"); return LUA_ErrInvalid(L, "mobj_t");
if (type >= NUMMOBJTYPES)
return luaL_error(L, "mobj type %d out of range (0 - %d)", type, NUMMOBJTYPES-1);
LUA_PushUserdata(L, P_SPMAngle(source, type, angle, allowaim, flags2), META_MOBJ); LUA_PushUserdata(L, P_SPMAngle(source, type, angle, allowaim, flags2), META_MOBJ);
return 1; return 1;
} }
@ -810,10 +830,9 @@ static int lib_pSpawnPlayerMissile(lua_State *L)
UINT32 flags2 = (UINT32)luaL_optinteger(L, 3, 0); UINT32 flags2 = (UINT32)luaL_optinteger(L, 3, 0);
NOHUD NOHUD
INLEVEL INLEVEL
NOSPAWNNULL
if (!source) if (!source)
return LUA_ErrInvalid(L, "mobj_t"); return LUA_ErrInvalid(L, "mobj_t");
if (type >= NUMMOBJTYPES)
return luaL_error(L, "mobj type %d out of range (0 - %d)", type, NUMMOBJTYPES-1);
LUA_PushUserdata(L, P_SpawnPlayerMissile(source, type, flags2), META_MOBJ); LUA_PushUserdata(L, P_SpawnPlayerMissile(source, type, flags2), META_MOBJ);
return 1; return 1;
} }
@ -844,8 +863,7 @@ static int lib_pWeaponOrPanel(lua_State *L)
{ {
mobjtype_t type = luaL_checkinteger(L, 1); mobjtype_t type = luaL_checkinteger(L, 1);
//HUDSAFE //HUDSAFE
if (type >= NUMMOBJTYPES) NOSPAWNNULL
return luaL_error(L, "mobj type %d out of range (0 - %d)", type, NUMMOBJTYPES-1);
lua_pushboolean(L, P_WeaponOrPanel(type)); lua_pushboolean(L, P_WeaponOrPanel(type));
return 1; return 1;
} }
@ -888,8 +906,7 @@ static int lib_pSpawnParaloop(lua_State *L)
boolean spawncenter = lua_optboolean(L, 9); boolean spawncenter = lua_optboolean(L, 9);
NOHUD NOHUD
INLEVEL INLEVEL
if (type >= NUMMOBJTYPES) NOSPAWNNULL
return luaL_error(L, "mobj type %d out of range (0 - %d)", type, NUMMOBJTYPES-1);
if (nstate >= NUMSTATES) if (nstate >= NUMSTATES)
return luaL_error(L, "state %d out of range (0 - %d)", nstate, NUMSTATES-1); return luaL_error(L, "state %d out of range (0 - %d)", nstate, NUMSTATES-1);
P_SpawnParaloop(x, y, z, radius, number, type, nstate, rotangle, spawncenter); P_SpawnParaloop(x, y, z, radius, number, type, nstate, rotangle, spawncenter);
@ -924,13 +941,14 @@ static int lib_pSetScale(lua_State *L)
{ {
mobj_t *mobj = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); mobj_t *mobj = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
fixed_t newscale = luaL_checkfixed(L, 2); fixed_t newscale = luaL_checkfixed(L, 2);
boolean instant = lua_optboolean(L, 3);
NOHUD NOHUD
INLEVEL INLEVEL
if (!mobj) if (!mobj)
return LUA_ErrInvalid(L, "mobj_t"); return LUA_ErrInvalid(L, "mobj_t");
if (newscale < FRACUNIT/100) if (newscale < FRACUNIT/100)
newscale = FRACUNIT/100; newscale = FRACUNIT/100;
P_SetScale(mobj, newscale); P_SetScale(mobj, newscale, instant);
return 0; return 0;
} }
@ -1762,10 +1780,9 @@ static int lib_pSpawnSpinMobj(lua_State *L)
mobjtype_t type = luaL_checkinteger(L, 2); mobjtype_t type = luaL_checkinteger(L, 2);
NOHUD NOHUD
INLEVEL INLEVEL
NOSPAWNNULL
if (!player) if (!player)
return LUA_ErrInvalid(L, "player_t"); return LUA_ErrInvalid(L, "player_t");
if (type >= NUMMOBJTYPES)
return luaL_error(L, "mobj type %d out of range (0 - %d)", type, NUMMOBJTYPES-1);
P_SpawnSpinMobj(player, type); P_SpawnSpinMobj(player, type);
return 0; return 0;
} }
@ -2497,6 +2514,17 @@ static int lib_pDoSuperTransformation(lua_State *L)
return 0; return 0;
} }
static int lib_pDoSuperDetransformation(lua_State *L)
{
player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
NOHUD
INLEVEL
if (!player)
return LUA_ErrInvalid(L, "player_t");
P_DoSuperDetransformation(player);
return 0;
}
static int lib_pExplodeMissile(lua_State *L) static int lib_pExplodeMissile(lua_State *L)
{ {
mobj_t *mo = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); mobj_t *mo = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
@ -2711,12 +2739,11 @@ static int lib_pFadeLight(lua_State *L)
static int lib_pIsFlagAtBase(lua_State *L) static int lib_pIsFlagAtBase(lua_State *L)
{ {
mobjtype_t flag = luaL_checkinteger(L, 1); mobjtype_t type = luaL_checkinteger(L, 1);
//HUDSAFE //HUDSAFE
INLEVEL INLEVEL
if (flag >= NUMMOBJTYPES) NOSPAWNNULL
return luaL_error(L, "mobj type %d out of range (0 - %d)", flag, NUMMOBJTYPES-1); lua_pushboolean(L, P_IsFlagAtBase(type));
lua_pushboolean(L, P_IsFlagAtBase(flag));
return 1; return 1;
} }
@ -3017,6 +3044,9 @@ static int lib_rFrame2Char(lua_State *L)
//HUDSAFE //HUDSAFE
c[0] = R_Frame2Char(ch); c[0] = R_Frame2Char(ch);
if (c[0] == '\xFF')
return luaL_error(L, "frame %u cannot be represented by a character", ch);
c[1] = 0; c[1] = 0;
lua_pushstring(L, c); lua_pushstring(L, c);
@ -3024,6 +3054,9 @@ static int lib_rFrame2Char(lua_State *L)
return 2; return 2;
} }
// R_SKINS
////////////
// R_SetPlayerSkin technically doesn't exist either, although it's basically just SetPlayerSkin and SetPlayerSkinByNum handled in one place for convenience // R_SetPlayerSkin technically doesn't exist either, although it's basically just SetPlayerSkin and SetPlayerSkinByNum handled in one place for convenience
static int lib_rSetPlayerSkin(lua_State *L) static int lib_rSetPlayerSkin(lua_State *L)
{ {
@ -3086,6 +3119,47 @@ static int lib_rSkinUsable(lua_State *L)
return 1; return 1;
} }
static int lib_pGetStateSprite2(lua_State *L)
{
int statenum = luaL_checkinteger(L, 1);
if (statenum < 0 || statenum >= NUMSTATES)
return luaL_error(L, "state %d out of range (0 - %d)", statenum, NUMSTATES-1);
lua_pushinteger(L, P_GetStateSprite2(&states[statenum]));
return 1;
}
static int lib_pGetSprite2StateFrame(lua_State *L)
{
int statenum = luaL_checkinteger(L, 1);
if (statenum < 0 || statenum >= NUMSTATES)
return luaL_error(L, "state %d out of range (0 - %d)", statenum, NUMSTATES-1);
lua_pushinteger(L, P_GetSprite2StateFrame(&states[statenum]));
return 1;
}
static int lib_pIsStateSprite2Super(lua_State *L)
{
int statenum = luaL_checkinteger(L, 1);
if (statenum < 0 || statenum >= NUMSTATES)
return luaL_error(L, "state %d out of range (0 - %d)", statenum, NUMSTATES-1);
lua_pushboolean(L, P_IsStateSprite2Super(&states[statenum]));
return 1;
}
// Not a real function. Who cares? I know I don't.
static int lib_pGetSuperSprite2(lua_State *L)
{
int animID = luaL_checkinteger(L, 1) & SPR2F_MASK;
if (animID < 0 || animID >= NUMPLAYERSPRITES)
return luaL_error(L, "sprite2 %d out of range (0 - %d)", animID, NUMPLAYERSPRITES-1);
lua_pushinteger(L, animID | SPR2F_SUPER);
return 1;
}
// R_DATA // R_DATA
//////////// ////////////
@ -3804,7 +3878,7 @@ static int lib_gAddPlayer(lua_State *L)
player_t *newplayer; player_t *newplayer;
SINT8 skinnum = 0, bot; SINT8 skinnum = 0, bot;
for (i = 0; i < MAXPLAYERS; i++) for (i = 1; i < MAXPLAYERS; i++)
{ {
if (!playeringame[i]) if (!playeringame[i])
break; break;
@ -4273,6 +4347,7 @@ static luaL_Reg lib[] = {
{"userdataMetatable", lib_userdataMetatable}, {"userdataMetatable", lib_userdataMetatable},
{"IsPlayerAdmin", lib_isPlayerAdmin}, {"IsPlayerAdmin", lib_isPlayerAdmin},
{"reserveLuabanks", lib_reserveLuabanks}, {"reserveLuabanks", lib_reserveLuabanks},
{"tofixed", lib_tofixed},
// m_menu // m_menu
{"M_MoveColorAfter",lib_pMoveColorAfter}, {"M_MoveColorAfter",lib_pMoveColorAfter},
@ -4450,6 +4525,7 @@ static luaL_Reg lib[] = {
{"P_VectorInstaThrust",lib_pVectorInstaThrust}, {"P_VectorInstaThrust",lib_pVectorInstaThrust},
{"P_SetMobjStateNF",lib_pSetMobjStateNF}, {"P_SetMobjStateNF",lib_pSetMobjStateNF},
{"P_DoSuperTransformation",lib_pDoSuperTransformation}, {"P_DoSuperTransformation",lib_pDoSuperTransformation},
{"P_DoSuperDetransformation",lib_pDoSuperDetransformation},
{"P_ExplodeMissile",lib_pExplodeMissile}, {"P_ExplodeMissile",lib_pExplodeMissile},
{"P_MobjTouchingSectorSpecial",lib_pMobjTouchingSectorSpecial}, {"P_MobjTouchingSectorSpecial",lib_pMobjTouchingSectorSpecial},
{"P_ThingOnSpecial3DFloor",lib_pThingOnSpecial3DFloor}, {"P_ThingOnSpecial3DFloor",lib_pThingOnSpecial3DFloor},
@ -4490,7 +4566,13 @@ static luaL_Reg lib[] = {
{"R_Char2Frame",lib_rChar2Frame}, {"R_Char2Frame",lib_rChar2Frame},
{"R_Frame2Char",lib_rFrame2Char}, {"R_Frame2Char",lib_rFrame2Char},
{"R_SetPlayerSkin",lib_rSetPlayerSkin}, {"R_SetPlayerSkin",lib_rSetPlayerSkin},
// r_skins
{"R_SkinUsable",lib_rSkinUsable}, {"R_SkinUsable",lib_rSkinUsable},
{"P_GetStateSprite2",lib_pGetStateSprite2},
{"P_GetSprite2StateFrame",lib_pGetSprite2StateFrame},
{"P_IsStateSprite2Super",lib_pIsStateSprite2Super},
{"P_GetSuperSprite2",lib_pGetSuperSprite2},
// r_data // r_data
{"R_CheckTextureNumForName",lib_rCheckTextureNumForName}, {"R_CheckTextureNumForName",lib_rCheckTextureNumForName},

View file

@ -86,6 +86,8 @@ automatically.
X (title),/* titlescreen */\ X (title),/* titlescreen */\
X (titlecard),\ X (titlecard),\
X (intermission),\ X (intermission),\
X (continue),\
X (playersetup),\
/* /*
I chose to access the hook enums through a macro as well. This could provide I chose to access the hook enums through a macro as well. This could provide
@ -117,6 +119,13 @@ extern boolean hook_cmd_running;
void LUA_HookVoid(int hook); void LUA_HookVoid(int hook);
void LUA_HookHUD(int hook, huddrawlist_h drawlist); void LUA_HookHUD(int hook, huddrawlist_h drawlist);
int LUA_HookCharacterHUD
(
int hook, huddrawlist_h drawlist, player_t *player,
fixed_t x, fixed_t y, fixed_t scale,
INT32 skinIndex, UINT8 sprite2, UINT8 frame, UINT8 rotation, skincolornum_t color,
INT32 ticker, boolean mode
);
int LUA_HookMobj(mobj_t *, int hook); int LUA_HookMobj(mobj_t *, int hook);
int LUA_Hook2Mobj(mobj_t *, mobj_t *, int hook); int LUA_Hook2Mobj(mobj_t *, mobj_t *, int hook);

View file

@ -375,6 +375,17 @@ static boolean prepare_string_hook
return false; return false;
} }
static boolean prepare_hud_hook
(
Hook_State * hook,
int default_status,
int hook_type
){
return init_hook_type(hook, default_status,
hook_type, 0, NULL,
hudHookIds[hook_type].numHooks);
}
static void init_hook_call static void init_hook_call
( (
Hook_State * hook, Hook_State * hook,
@ -490,6 +501,21 @@ static int call_mobj_type_hooks(Hook_State *hook, mobjtype_t mobj_type)
return call_mapped(hook, &mobjHookIds[mobj_type][hook->hook_type]); return call_mapped(hook, &mobjHookIds[mobj_type][hook->hook_type]);
} }
static void call_hud_hooks
(
Hook_State * hook,
int results,
Hook_Callback results_handler
){
hud_running = true; // local hook
init_hook_call(hook, results, results_handler);
call_mapped(hook, &hudHookIds[hook->hook_type]);
hud_running = false;
lua_pushnil(gL);
lua_setfield(gL, LUA_REGISTRYINDEX, "HUD_DRAW_LIST");
}
static int call_hooks static int call_hooks
( (
Hook_State * hook, Hook_State * hook,
@ -648,25 +674,41 @@ int LUA_HookKey(event_t *event, int hook_type)
void LUA_HookHUD(int hook_type, huddrawlist_h list) void LUA_HookHUD(int hook_type, huddrawlist_h list)
{ {
const hook_t * map = &hudHookIds[hook_type];
Hook_State hook; Hook_State hook;
if (map->numHooks > 0) if (prepare_hud_hook(&hook, 0, hook_type))
{ {
start_hook_stack();
begin_hook_values(&hook);
LUA_SetHudHook(hook_type, list); LUA_SetHudHook(hook_type, list);
call_hud_hooks(&hook, 0, res_none);
hud_running = true; // local hook
init_hook_call(&hook, 0, res_none);
call_mapped(&hook, map);
hud_running = false;
lua_pushnil(gL);
lua_setfield(gL, LUA_REGISTRYINDEX, "HUD_DRAW_LIST");
} }
} }
int LUA_HookCharacterHUD
(
int hook_type, huddrawlist_h list, player_t *player,
fixed_t x, fixed_t y, fixed_t scale,
INT32 skinIndex, UINT8 sprite2, UINT8 frame, UINT8 rotation, skincolornum_t color,
INT32 ticker, boolean mode
){
Hook_State hook;
if (prepare_hud_hook(&hook, false, hook_type))
{
LUA_SetHudHook(hook_type, list);
LUA_PushUserdata(gL, player, META_PLAYER);
lua_pushfixed(gL, x);
lua_pushfixed(gL, y);
lua_pushfixed(gL, scale);
lua_pushstring(gL, skins[skinIndex]->name);
lua_pushinteger(gL, sprite2);
lua_pushinteger(gL, frame);
lua_pushinteger(gL, rotation);
lua_pushinteger(gL, color);
lua_pushinteger(gL, ticker);
lua_pushboolean(gL, mode);
call_hud_hooks(&hook, 1, res_true);
}
return hook.status;
}
/* ========================================================================= /* =========================================================================
SPECIALIZED HOOKS SPECIALIZED HOOKS
========================================================================= */ ========================================================================= */

View file

@ -19,6 +19,7 @@ enum hud {
hud_stagetitle = 0, hud_stagetitle = 0,
hud_textspectator, hud_textspectator,
hud_crosshair, hud_crosshair,
hud_powerups,
// Singleplayer / Co-op // Singleplayer / Co-op
hud_score, hud_score,
hud_time, hud_time,

View file

@ -41,11 +41,13 @@ static const char *const hud_disable_options[] = {
"stagetitle", "stagetitle",
"textspectator", "textspectator",
"crosshair", "crosshair",
"powerups",
"score", "score",
"time", "time",
"rings", "rings",
"lives", "lives",
"input",
"weaponrings", "weaponrings",
"powerstones", "powerstones",
@ -69,6 +71,10 @@ static const char *const hud_disable_options[] = {
"intermissionemeralds", "intermissionemeralds",
NULL}; NULL};
// you know, let's actually make sure that the table is synced.
// because fuck knows how many times this has happened at this point. :v
I_StaticAssert(sizeof(hud_disable_options) / sizeof(*hud_disable_options) == hud_MAX+1);
enum hudinfo { enum hudinfo {
hudinfo_x = 0, hudinfo_x = 0,
hudinfo_y, hudinfo_y,
@ -486,9 +492,7 @@ static int libd_getSpritePatch(lua_State *L)
else if (lua_isstring(L, 1)) // sprite prefix name given, e.g. "THOK" else if (lua_isstring(L, 1)) // sprite prefix name given, e.g. "THOK"
{ {
const char *name = lua_tostring(L, 1); const char *name = lua_tostring(L, 1);
for (i = 0; i < NUMSPRITES; i++) i = R_GetSpriteNumByName(name);
if (fastcmp(name, sprnames[i]))
break;
if (i >= NUMSPRITES) if (i >= NUMSPRITES)
return 0; return 0;
} }
@ -550,7 +554,7 @@ static int libd_getSprite2Patch(lua_State *L)
UINT8 angle = 0; UINT8 angle = 0;
spritedef_t *sprdef; spritedef_t *sprdef;
spriteframe_t *sprframe; spriteframe_t *sprframe;
boolean super = false; // add FF_SPR2SUPER to sprite2 if true boolean super = false; // add SPR2F_SUPER to sprite2 if true
HUDONLY HUDONLY
// get skin first! // get skin first!
@ -577,11 +581,12 @@ static int libd_getSprite2Patch(lua_State *L)
if (lua_isnumber(L, 1)) // sprite number given, e.g. SPR2_STND if (lua_isnumber(L, 1)) // sprite number given, e.g. SPR2_STND
{ {
j = lua_tonumber(L, 1); j = lua_tonumber(L, 1);
if (j & FF_SPR2SUPER) // e.g. SPR2_STND|FF_SPR2SUPER if (j & SPR2F_SUPER) // e.g. SPR2_STND|SPR2F_SUPER
{ {
super = true; super = true;
j &= ~FF_SPR2SUPER; // remove flag so the next check doesn't fail j &= ~SPR2F_SUPER; // remove flag so the next check doesn't fail
} }
if (j >= free_spr2) if (j >= free_spr2)
return 0; return 0;
} }
@ -600,17 +605,15 @@ static int libd_getSprite2Patch(lua_State *L)
if (lua_isboolean(L, 2)) // optional boolean for superness if (lua_isboolean(L, 2)) // optional boolean for superness
{ {
super = lua_toboolean(L, 2); // note: this can override FF_SPR2SUPER from sprite number super = lua_toboolean(L, 2); // note: this can override SPR2F_SUPER from sprite number
lua_remove(L, 2); // remove lua_remove(L, 2); // remove
} }
// if it's not boolean then just assume it's the frame number // if it's not boolean then just assume it's the frame number
if (super) if (super)
j |= FF_SPR2SUPER; j |= SPR2F_SUPER;
j = P_GetSkinSprite2(skins[i], j, NULL); // feed skin and current sprite2 through to change sprite2 used if necessary sprdef = P_GetSkinSpritedef(skins[i], j);
sprdef = &skins[i]->sprites[j];
// set frame number // set frame number
frame = luaL_optinteger(L, 2, 0); frame = luaL_optinteger(L, 2, 0);
@ -638,7 +641,7 @@ static int libd_getSprite2Patch(lua_State *L)
INT32 rot = R_GetRollAngle(rollangle); INT32 rot = R_GetRollAngle(rollangle);
if (rot) { if (rot) {
patch_t *rotsprite = Patch_GetRotatedSprite(sprframe, frame, angle, sprframe->flip & (1<<angle), &skins[i]->sprinfo[j], rot); patch_t *rotsprite = Patch_GetRotatedSprite(sprframe, frame, angle, sprframe->flip & (1<<angle), P_GetSkinSpriteInfo(skins[i], j), rot);
LUA_PushUserdata(L, rotsprite, META_PATCH); LUA_PushUserdata(L, rotsprite, META_PATCH);
lua_pushboolean(L, false); lua_pushboolean(L, false);
lua_pushboolean(L, true); lua_pushboolean(L, true);

View file

@ -180,7 +180,8 @@ static const char *CopyString(huddrawlist_h list, const char* str)
const char *old_offset = list->strbuf; const char *old_offset = list->strbuf;
size_t i; size_t i;
if (list->strbuf_capacity == 0) list->strbuf_capacity = 256; if (list->strbuf_capacity == 0) list->strbuf_capacity = 256;
else list->strbuf_capacity *= 2; while (list->strbuf_capacity <= list->strbuf_len + lenstr + 1)
list->strbuf_capacity *= 2;
list->strbuf = (char*) Z_Realloc(list->strbuf, sizeof(char) * list->strbuf_capacity, PU_STATIC, NULL); list->strbuf = (char*) Z_Realloc(list->strbuf, sizeof(char) * list->strbuf_capacity, PU_STATIC, NULL);
// align the string pointers to make sure old pointers don't point towards invalid addresses // align the string pointers to make sure old pointers don't point towards invalid addresses

View file

@ -88,8 +88,8 @@ static int lib_getSprname(lua_State *L)
else if (lua_isstring(L, 1)) else if (lua_isstring(L, 1))
{ {
const char *name = lua_tostring(L, 1); const char *name = lua_tostring(L, 1);
for (i = 0; i < NUMSPRITES; i++) i = R_GetSpriteNumByName(name);
if (fastcmp(name, sprnames[i])) if (i != NUMSPRITES)
{ {
lua_pushinteger(L, i); lua_pushinteger(L, i);
return 1; return 1;
@ -165,7 +165,7 @@ static int lib_getSpr2default(lua_State *L)
static int lib_setSpr2default(lua_State *L) static int lib_setSpr2default(lua_State *L)
{ {
playersprite_t i; playersprite_t i;
UINT8 j = 0; UINT16 j = 0;
if (hud_running) if (hud_running)
return luaL_error(L, "Do not alter spr2defaults[] in HUD rendering code!"); return luaL_error(L, "Do not alter spr2defaults[] in HUD rendering code!");
@ -242,25 +242,13 @@ static int lib_getSpriteInfo(lua_State *L)
UINT32 i = NUMSPRITES; UINT32 i = NUMSPRITES;
lua_remove(L, 1); lua_remove(L, 1);
if (lua_isstring(L, 1)) if (lua_type(L, 1) == LUA_TSTRING)
{ {
const char *name = lua_tostring(L, 1); const char *name = lua_tostring(L, 1);
INT32 spr; INT32 spr = R_GetSpriteNumByName(name);
for (spr = 0; spr < NUMSPRITES; spr++) if (spr == NUMSPRITES)
{
if (fastcmp(name, sprnames[spr]))
{
i = spr;
break;
}
}
if (i == NUMSPRITES)
{
char *check;
i = strtol(name, &check, 10);
if (check == name || *check != '\0')
return luaL_error(L, "unknown sprite name %s", name); return luaL_error(L, "unknown sprite name %s", name);
} i = spr;
} }
else else
i = luaL_checkinteger(L, 1); i = luaL_checkinteger(L, 1);
@ -359,8 +347,8 @@ static int PopPivotTable(spriteinfo_t *info, lua_State *L, int stk)
default: default:
TYPEERROR("pivot frame", LUA_TNUMBER, lua_type(L, stk+1)); TYPEERROR("pivot frame", LUA_TNUMBER, lua_type(L, stk+1));
} }
if ((idx < 0) || (idx >= 64)) if ((idx < 0) || (idx >= MAXFRAMENUM))
return luaL_error(L, "pivot frame %d out of range (0 - %d)", idx, 63); return luaL_error(L, "pivot frame %d out of range (0 - %d)", idx, MAXFRAMENUM - 1);
// the values in pivot[] are also tables // the values in pivot[] are also tables
if (PopPivotSubTable(info->pivot, L, stk+2, idx)) if (PopPivotSubTable(info->pivot, L, stk+2, idx))
info->available = true; info->available = true;
@ -555,7 +543,7 @@ static int pivotlist_set(lua_State *L)
static int pivotlist_num(lua_State *L) static int pivotlist_num(lua_State *L)
{ {
lua_pushinteger(L, 64); lua_pushinteger(L, MAXFRAMENUM);
return 1; return 1;
} }
@ -1747,7 +1735,7 @@ static int lib_setSkinColor(lua_State *L)
else if (i == 6 || (str && fastcmp(str,"accessible"))) { else if (i == 6 || (str && fastcmp(str,"accessible"))) {
boolean v = lua_toboolean(L, 3); boolean v = lua_toboolean(L, 3);
if (cnum < FIRSTSUPERCOLOR && v != skincolors[cnum].accessible) if (cnum < FIRSTSUPERCOLOR && v != skincolors[cnum].accessible)
CONS_Alert(CONS_WARNING, "skincolors[] index %d is a standard color; accessibility changes are prohibited.", cnum); CONS_Alert(CONS_WARNING, "skincolors[] index %d is a standard color; accessibility changes are prohibited.\n", cnum);
else else
info->accessible = v; info->accessible = v;
} }
@ -1842,7 +1830,7 @@ static int skincolor_set(lua_State *L)
else if (fastcmp(field,"accessible")) { else if (fastcmp(field,"accessible")) {
boolean v = lua_toboolean(L, 3); boolean v = lua_toboolean(L, 3);
if (cnum < FIRSTSUPERCOLOR && v != skincolors[cnum].accessible) if (cnum < FIRSTSUPERCOLOR && v != skincolors[cnum].accessible)
CONS_Alert(CONS_WARNING, "skincolors[] index %d is a standard color; accessibility changes are prohibited.", cnum); CONS_Alert(CONS_WARNING, "skincolors[] index %d is a standard color; accessibility changes are prohibited.\n", cnum);
else else
info->accessible = v; info->accessible = v;
} else } else

View file

@ -42,8 +42,9 @@ extern boolean ignoregameinputs;
#define META_SKIN "SKIN_T*" #define META_SKIN "SKIN_T*"
#define META_POWERS "PLAYER_T*POWERS" #define META_POWERS "PLAYER_T*POWERS"
#define META_SOUNDSID "SKIN_T*SOUNDSID" #define META_SOUNDSID "SKIN_T*SOUNDSID"
#define META_SKINSPRITES "SKIN_T*SPRITES" #define META_SKINSPRITES "SKIN_T*SKINSPRITES"
#define META_SKINSPRITESLIST "SKIN_T*SPRITES[]" #define META_SKINSPRITESLIST "SKIN_T*SKINSPRITES[]"
#define META_SKINSPRITESCOMPAT "SKIN_T*SPRITES" // TODO: 2.3: Delete
#define META_VERTEX "VERTEX_T*" #define META_VERTEX "VERTEX_T*"
#define META_LINE "LINE_T*" #define META_LINE "LINE_T*"

View file

@ -69,6 +69,7 @@ enum mobj_e {
mobj_color, mobj_color,
mobj_translation, mobj_translation,
mobj_blendmode, mobj_blendmode,
mobj_alpha,
mobj_bnext, mobj_bnext,
mobj_bprev, mobj_bprev,
mobj_hnext, mobj_hnext,
@ -150,6 +151,7 @@ static const char *const mobj_opt[] = {
"color", "color",
"translation", "translation",
"blendmode", "blendmode",
"alpha",
"bnext", "bnext",
"bprev", "bprev",
"hnext", "hnext",
@ -354,6 +356,9 @@ static int mobj_get(lua_State *L)
case mobj_blendmode: case mobj_blendmode:
lua_pushinteger(L, mo->blendmode); lua_pushinteger(L, mo->blendmode);
break; break;
case mobj_alpha:
lua_pushfixed(L, mo->alpha);
break;
case mobj_bnext: case mobj_bnext:
if (mo->blocknode && mo->blocknode->bnext) { if (mo->blocknode && mo->blocknode->bnext) {
LUA_PushUserdata(L, mo->blocknode->bnext->mobj, META_MOBJ); LUA_PushUserdata(L, mo->blocknode->bnext->mobj, META_MOBJ);
@ -564,7 +569,7 @@ static int mobj_set(lua_State *L)
mo->frame = (UINT32)luaL_checkinteger(L, 3); mo->frame = (UINT32)luaL_checkinteger(L, 3);
break; break;
case mobj_sprite2: case mobj_sprite2:
mo->sprite2 = P_GetSkinSprite2(((skin_t *)mo->skin), (UINT8)luaL_checkinteger(L, 3), mo->player); mo->sprite2 = P_GetSkinSprite2(((skin_t *)mo->skin), (UINT16)luaL_checkinteger(L, 3), mo->player);
break; break;
case mobj_anim_duration: case mobj_anim_duration:
mo->anim_duration = (UINT16)luaL_checkinteger(L, 3); mo->anim_duration = (UINT16)luaL_checkinteger(L, 3);
@ -733,6 +738,16 @@ static int mobj_set(lua_State *L)
mo->blendmode = blendmode; mo->blendmode = blendmode;
break; break;
} }
case mobj_alpha:
{
fixed_t alpha = luaL_checkfixed(L, 3);
if (alpha < 0)
alpha = 0;
else if (alpha > FRACUNIT)
alpha = FRACUNIT;
mo->alpha = alpha;
break;
}
case mobj_bnext: case mobj_bnext:
return NOSETPOS; return NOSETPOS;
case mobj_bprev: case mobj_bprev:
@ -762,7 +777,7 @@ static int mobj_set(lua_State *L)
return luaL_error(L, "mobj.type %d out of range (0 - %d).", newtype, NUMMOBJTYPES-1); return luaL_error(L, "mobj.type %d out of range (0 - %d).", newtype, NUMMOBJTYPES-1);
mo->type = newtype; mo->type = newtype;
mo->info = &mobjinfo[newtype]; mo->info = &mobjinfo[newtype];
P_SetScale(mo, mo->scale); P_SetScale(mo, mo->scale, false);
break; break;
} }
case mobj_info: case mobj_info:
@ -836,9 +851,7 @@ static int mobj_set(lua_State *L)
fixed_t scale = luaL_checkfixed(L, 3); fixed_t scale = luaL_checkfixed(L, 3);
if (scale < FRACUNIT/100) if (scale < FRACUNIT/100)
scale = FRACUNIT/100; scale = FRACUNIT/100;
mo->destscale = scale; P_SetScale(mo, scale, true);
P_SetScale(mo, scale);
mo->old_scale = scale;
break; break;
} }
case mobj_destscale: case mobj_destscale:

View file

@ -190,6 +190,7 @@ enum player_e
player_marelap, player_marelap,
player_marebonuslap, player_marebonuslap,
player_marebegunat, player_marebegunat,
player_lastmaretime,
player_startedtime, player_startedtime,
player_finishedtime, player_finishedtime,
player_lapbegunat, player_lapbegunat,
@ -337,6 +338,7 @@ static const char *const player_opt[] = {
"marelap", "marelap",
"marebonuslap", "marebonuslap",
"marebegunat", "marebegunat",
"lastmaretime",
"startedtime", "startedtime",
"finishedtime", "finishedtime",
"lapbegunat", "lapbegunat",
@ -725,6 +727,9 @@ static int player_get(lua_State *L)
case player_marebegunat: case player_marebegunat:
lua_pushinteger(L, plr->marebegunat); lua_pushinteger(L, plr->marebegunat);
break; break;
case player_lastmaretime:
lua_pushinteger(L, plr->lastmaretime);
break;
case player_startedtime: case player_startedtime:
lua_pushinteger(L, plr->startedtime); lua_pushinteger(L, plr->startedtime);
break; break;
@ -1219,6 +1224,9 @@ static int player_set(lua_State *L)
case player_marebegunat: case player_marebegunat:
plr->marebegunat = (tic_t)luaL_checkinteger(L, 3); plr->marebegunat = (tic_t)luaL_checkinteger(L, 3);
break; break;
case player_lastmaretime:
plr->lastmaretime = (tic_t)luaL_checkinteger(L, 3);
break;
case player_startedtime: case player_startedtime:
plr->startedtime = (tic_t)luaL_checkinteger(L, 3); plr->startedtime = (tic_t)luaL_checkinteger(L, 3);
break; break;

View file

@ -622,9 +622,6 @@ static inline boolean LUA_LoadFile(MYFILE *f, char *name)
if (!gL) // Lua needs to be initialized if (!gL) // Lua needs to be initialized
LUA_ClearState(); LUA_ClearState();
lua_pushinteger(gL, f->wad);
lua_setfield(gL, LUA_REGISTRYINDEX, "WAD");
lua_pushcfunction(gL, LUA_GetErrorMessage); lua_pushcfunction(gL, LUA_GetErrorMessage);
errorhandlerindex = lua_gettop(gL); errorhandlerindex = lua_gettop(gL);

View file

@ -54,7 +54,9 @@ enum skin {
skin_contspeed, skin_contspeed,
skin_contangle, skin_contangle,
skin_soundsid, skin_soundsid,
skin_sprites, skin_sprites, // TODO: 2.3: Delete
skin_skinsprites,
skin_supersprites,
skin_natkcolor skin_natkcolor
}; };
@ -94,7 +96,9 @@ static const char *const skin_opt[] = {
"contspeed", "contspeed",
"contangle", "contangle",
"soundsid", "soundsid",
"sprites", "sprites", // TODO: 2.3: Delete
"skinsprites",
"supersprites",
"natkcolor", "natkcolor",
NULL}; NULL};
@ -217,9 +221,15 @@ static int skin_get(lua_State *L)
case skin_soundsid: case skin_soundsid:
LUA_PushUserdata(L, skin->soundsid, META_SOUNDSID); LUA_PushUserdata(L, skin->soundsid, META_SOUNDSID);
break; break;
case skin_sprites: case skin_sprites: // TODO: 2.3: Delete
LUA_PushUserdata(L, skin->sprites_compat, META_SKINSPRITESCOMPAT);
break;
case skin_skinsprites:
LUA_PushUserdata(L, skin->sprites, META_SKINSPRITES); LUA_PushUserdata(L, skin->sprites, META_SKINSPRITES);
break; break;
case skin_supersprites:
LUA_PushUserdata(L, skin->super.sprites, META_SKINSPRITES);
break;
case skin_natkcolor: case skin_natkcolor:
lua_pushinteger(L, skin->natkcolor); lua_pushinteger(L, skin->natkcolor);
break; break;
@ -333,6 +343,48 @@ static int soundsid_num(lua_State *L)
return 1; return 1;
} }
// skin.skinsprites[i] -> sprites[i]
static int lib_getSkinSprite(lua_State *L)
{
spritedef_t *sksprites = *(spritedef_t **)luaL_checkudata(L, 1, META_SKINSPRITES);
playersprite_t i = luaL_checkinteger(L, 2);
if (i < 0 || i >= NUMPLAYERSPRITES)
return luaL_error(L, "skin sprites index %d out of range (0 - %d)", i, NUMPLAYERSPRITES-1);
LUA_PushUserdata(L, &sksprites[i], META_SKINSPRITESLIST);
return 1;
}
// #skin.skinsprites -> NUMPLAYERSPRITES
static int lib_numSkinsSprites(lua_State *L)
{
lua_pushinteger(L, NUMPLAYERSPRITES);
return 1;
}
// TODO: 2.3: Delete
// skin.sprites[i] -> sprites[i]
static int lib_getSkinSpriteCompat(lua_State *L)
{
spritedef_t *sksprites = *(spritedef_t **)luaL_checkudata(L, 1, META_SKINSPRITESCOMPAT);
playersprite_t i = luaL_checkinteger(L, 2);
if (i < 0 || i >= NUMPLAYERSPRITES*2)
return luaL_error(L, "skin sprites index %d out of range (0 - %d)", i, (NUMPLAYERSPRITES*2)-1);
LUA_PushUserdata(L, &sksprites[i], META_SKINSPRITESLIST);
return 1;
}
// TODO: 2.3: Delete
// #skin.sprites -> NUMPLAYERSPRITES*2
static int lib_numSkinsSpritesCompat(lua_State *L)
{
lua_pushinteger(L, NUMPLAYERSPRITES*2);
return 1;
}
enum spritesopt { enum spritesopt {
numframes = 0 numframes = 0
}; };
@ -341,26 +393,6 @@ static const char *const sprites_opt[] = {
"numframes", "numframes",
NULL}; NULL};
// skin.sprites[i] -> sprites[i]
static int lib_getSkinSprite(lua_State *L)
{
spritedef_t *sksprites = *(spritedef_t **)luaL_checkudata(L, 1, META_SKINSPRITES);
playersprite_t i = luaL_checkinteger(L, 2);
if (i < 0 || i >= NUMPLAYERSPRITES*2)
return luaL_error(L, LUA_QL("skin_t") " field 'sprites' index %d out of range (0 - %d)", i, (NUMPLAYERSPRITES*2)-1);
LUA_PushUserdata(L, &sksprites[i], META_SKINSPRITESLIST);
return 1;
}
// #skin.sprites -> NUMPLAYERSPRITES*2
static int lib_numSkinsSprites(lua_State *L)
{
lua_pushinteger(L, NUMPLAYERSPRITES*2);
return 1;
}
static int sprite_get(lua_State *L) static int sprite_get(lua_State *L)
{ {
spritedef_t *sprite = *(spritedef_t **)luaL_checkudata(L, 1, META_SKINSPRITESLIST); spritedef_t *sprite = *(spritedef_t **)luaL_checkudata(L, 1, META_SKINSPRITESLIST);
@ -382,6 +414,7 @@ int LUA_SkinLib(lua_State *L)
LUA_RegisterUserdataMetatable(L, META_SOUNDSID, soundsid_get, NULL, soundsid_num); LUA_RegisterUserdataMetatable(L, META_SOUNDSID, soundsid_get, NULL, soundsid_num);
LUA_RegisterUserdataMetatable(L, META_SKINSPRITES, lib_getSkinSprite, NULL, lib_numSkinsSprites); LUA_RegisterUserdataMetatable(L, META_SKINSPRITES, lib_getSkinSprite, NULL, lib_numSkinsSprites);
LUA_RegisterUserdataMetatable(L, META_SKINSPRITESLIST, sprite_get, NULL, NULL); LUA_RegisterUserdataMetatable(L, META_SKINSPRITESLIST, sprite_get, NULL, NULL);
LUA_RegisterUserdataMetatable(L, META_SKINSPRITESCOMPAT, lib_getSkinSpriteCompat, NULL, lib_numSkinsSpritesCompat); // TODO: 2.3: Delete
skin_fields_ref = Lua_CreateFieldTable(L, skin_opt); skin_fields_ref = Lua_CreateFieldTable(L, skin_opt);

File diff suppressed because it is too large Load diff

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