Merge branch 'master' into gametype-refactor

This commit is contained in:
Alam Ed Arias 2023-10-28 20:21:13 -04:00
commit 3e4efcf8dc
72 changed files with 1934 additions and 986 deletions

View file

@ -1,9 +1,9 @@
version: 2 version: 2
jobs: jobs:
build: build:
working_directory: /root/SRB2 working_directory: /home/circleci/SRB2
docker: docker:
- image: debian:stretch - image: cimg/base:current
environment: environment:
CC: ccache gcc -m32 CC: ccache gcc -m32
PKG_CONFIG_LIBDIR: /usr/lib/i386-linux-gnu/pkgconfig PKG_CONFIG_LIBDIR: /usr/lib/i386-linux-gnu/pkgconfig
@ -11,7 +11,7 @@ jobs:
LIBGME_LDFLAGS: -lgme LIBGME_LDFLAGS: -lgme
CCACHE_COMPRESS: true CCACHE_COMPRESS: true
WFLAGS: -Wno-unsuffixed-float-constants WFLAGS: -Wno-unsuffixed-float-constants
GCC49: true GCC81: true
#- image: ubuntu:trusty #- image: ubuntu:trusty
# environment: # environment:
# CC: ccache gcc -m32 # CC: ccache gcc -m32
@ -25,39 +25,42 @@ jobs:
steps: steps:
- run: - run:
name: Add i386 arch name: Add i386 arch
command: dpkg --add-architecture i386 command: sudo dpkg --add-architecture i386
- run: - run:
name: Add STJr PPA name: Add STJr PPA
command: | command: |
apt-get -qq update sudo apt-get -qq update
apt-get -qq -y install dirmngr sudo apt-get -qq -y install dirmngr
apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 0B1702D71499D9C25F986507F240F4449D3B0EC6 sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 0B1702D71499D9C25F986507F240F4449D3B0EC6
echo "deb http://ppa.launchpad.net/stjr/srb2/ubuntu trusty main" >> /etc/apt/sources.list echo "deb http://ppa.launchpad.net/stjr/srb2/ubuntu trusty main" | sudo tee -a /etc/apt/sources.list
- run: - run:
name: Make APT cache folder name: Make APT cache folder
command: mkdir -p /root/.cache/apt/archives/partial command: mkdir -p /home/circleci/.cache/apt/archives/partial
- run: - run:
name: Make APT cache usage by _apt name: Make APT cache usage by _apt
command: chown -Rv _apt:root /root/.cache/apt/archives/partial command: sudo chown -Rv _apt:root /home/circleci/.cache/apt/archives/partial
- run: - run:
name: Update APT listing name: Update APT listing
command: apt-get -qq update command: sudo apt-get -qq update
- run: - run:
name: Support S3 upload name: Support S3 upload
command: apt-get -qq -y install ca-certificates command: sudo apt-get -qq -y install ca-certificates
- restore_cache: - restore_cache:
keys: keys:
- v1-SRB2-APT - v1-SRB2-APT
- run: - run:
name: Install SDK name: Uninstall amd64 SDK
command: apt-get -o Dir::Cache="/root/.cache/apt" -qq -y --no-install-recommends install git build-essential libpng-dev:i386 libsdl2-mixer-dev:i386 libgme-dev:i386 libcurl4-openssl-dev:i386 libopenmpt-dev:i386 gettext ccache wget gcc-multilib upx openssh-client command: sudo apt-get -o Dir::Cache="/home/circleci/.cache/apt" -qq -y --no-install-recommends remove libcurl4-openssl-dev:amd64
- run:
name: Install i386 SDK
command: sudo apt-get -o Dir::Cache="/home/circleci/.cache/apt" -qq -y --no-install-recommends install git build-essential libpng-dev:i386 libsdl2-mixer-dev:i386 libgme-dev:i386 libcurl4-openssl-dev:i386 libopenmpt-dev:i386 gettext ccache wget gcc-multilib upx openssh-client
- run: - run:
name: make md5sum name: make md5sum
command: find /root/.cache/apt/archives -type f -print0 | sort -z | xargs -r0 md5sum > /root/.cache/apt_archives.md5 command: sudo find /home/circleci/.cache/apt/archives -type f -print0 | sort -z | sudo xargs -r0 md5sum > /home/circleci/.cache/apt_archives.md5
- save_cache: - save_cache:
key: v1-SRB2-APT-{{ checksum "/root/.cache/apt_archives.md5" }} key: v1-SRB2-APT-{{ checksum "/home/circleci/.cache/apt_archives.md5" }}
paths: paths:
- /root/.cache/apt - /home/circleci/.cache/apt
- checkout - checkout
- run: - run:
name: Compile without network support name: Compile without network support
@ -78,9 +81,9 @@ jobs:
name: Compile name: Compile
command: make -C src LINUX=1 ERRORMODE=1 -k -j4 command: make -C src LINUX=1 ERRORMODE=1 -k -j4
- store_artifacts: - store_artifacts:
path: /root/SRB2/bin/ path: /home/circleci/SRB2/bin/
destination: bin destination: bin
- save_cache: - save_cache:
key: v1-SRB2-{{ .Branch }}-{{ checksum "make/linux/SDL.deps" }} key: v1-SRB2-{{ .Branch }}-{{ checksum "make/linux/SDL.deps" }}
paths: paths:
- /root/.ccache - /home/circleci/.ccache

4
.gitattributes vendored
View file

@ -1,15 +1,17 @@
#Source code #Source code
/Makefile text=auto
/src/*.c text=auto /src/*.c text=auto
/src/*.h text=auto /src/*.h text=auto
/src/*.s text=auto /src/*.s text=auto
/src/*.m text=auto /src/*.m text=auto
/src/*.xpm text=auto /src/*.xpm text=auto
/src/Makefile text=auto /src/Makefile text=auto
/tools/Makefile text=auto
/src/Make*.cfg text=auto /src/Make*.cfg text=auto
/src/CMakeLists.txt text=auto /src/CMakeLists.txt text=auto
*.mk -whitespace text=auto
# Windows EOL # Windows EOL
*.cs -crlf -whitespace *.cs -crlf -whitespace
*.mk -crlf -whitespace
*.bat -crlf -whitespace *.bat -crlf -whitespace
*.dev -crlf -whitespace *.dev -crlf -whitespace
*.dsp -crlf -whitespace *.dsp -crlf -whitespace

1
.gitignore vendored
View file

@ -23,3 +23,4 @@ Win32_LIB_ASM_Release
/bin /bin
/build /build
/build/* /build/*
/CMakeUserPresets.json

434
.gitlab-ci.yml Normal file
View file

@ -0,0 +1,434 @@
variables:
GIT_STRATEGY: clone
GIT_CLONE_PATH: $CI_BUILDS_DIR/$CI_CONCURRENT_ID/$CI_PROJECT_PATH
default:
image: debian:stable-slim
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
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
- |
# 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 --verbose
- ccache --show-log-stats --verbose
- |
# ccahe_stats
echo -e "\e[0Ksection_end:`date +%s`:ccache_stats\r\e[0K"
stages:
- build
Debian testing GCC:
stage: build
image: debian:testing-slim
allow_failure: true
artifacts:
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
- |
# 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
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
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
- |
# 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 stable:i386:
stage: build
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
- |
# 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
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
- |
# 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 || make --directory=src --keep-going CCACHE=1 ERRORMODE=1 LINUX64=1 NONX86=1
- |
# make
echo -e "\e[0Ksection_end:`date +%s`:make\r\e[0K"
Windows x64:
stage: build
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
allow_failure: true
artifacts:
name: "$CI_PROJECT_PATH_SLUG-$CI_COMMIT_REF_SLUG-$CI_COMMIT_SHORT_SHA-clang"
variables:
CC: clang
WFLAGS: -Wno-cast-align
CFLAGS: -Wno-cast-align
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
- |
# 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"
Debian testing Clang:
extends: Debian stable Clang
image: debian:testing-slim
artifacts:
name: "$CI_PROJECT_PATH_SLUG-$CI_COMMIT_REF_SLUG-$CI_COMMIT_SHORT_SHA-testing-clang"
variables:
CC: clang
WFLAGS: -Wno-cast-align -Wno-deprecated-non-prototype
CFLAGS: -Wno-cast-align -Wno-deprecated-non-prototype
LDFLAGS: -Wl,-fuse-ld=gold

View file

@ -1,4 +1,4 @@
version: 2.2.11.{branch}-{build} version: 2.2.13.{branch}-{build}
os: MinGW os: MinGW
environment: environment:

View file

@ -3,12 +3,12 @@ ifdef ComSpec
COMSPEC=$(ComSpec) COMSPEC=$(ComSpec)
endif endif
ifdef COMSPEC ifdef COMSPEC
OBJCOPY=objcopy.exe OBJCOPY?=objcopy.exe
OBJDUMP=objdump.exe OBJDUMP?=objdump.exe
GZIP?=gzip.exe GZIP?=gzip.exe
else else
OBJCOPY=objcopy OBJCOPY?=objcopy
OBJDUMP=objdump OBJDUMP?=objdump
GZIP?=gzip GZIP?=gzip
endif endif
DBGNAME=$(BIN).debug DBGNAME=$(BIN).debug

View file

@ -4367,7 +4367,6 @@ thingtypes
{ {
color = 14; // Yellow color = 14; // Yellow
title = "Rings and Weapon Panels"; title = "Rings and Weapon Panels";
width = 24;
height = 24; height = 24;
flags8height = 24; flags8height = 24;
flags8text = "[8] Float"; flags8text = "[8] Float";
@ -4377,7 +4376,6 @@ thingtypes
{ {
title = "Ring"; title = "Ring";
sprite = "RINGA0"; sprite = "RINGA0";
width = 16;
} }
301 301
{ {
@ -4393,6 +4391,7 @@ thingtypes
{ {
title = "Infinity Ring"; title = "Infinity Ring";
sprite = "RNGIA0"; sprite = "RNGIA0";
width = 24;
} }
304 304
{ {
@ -4418,43 +4417,53 @@ thingtypes
{ {
title = "CTF Team Ring (Red)"; title = "CTF Team Ring (Red)";
sprite = "internal:TRNGA0R"; sprite = "internal:TRNGA0R";
width = 16;
} }
309 309
{ {
title = "CTF Team Ring (Blue)"; title = "CTF Team Ring (Blue)";
sprite = "internal:TRNGA0B"; sprite = "internal:TRNGA0B";
width = 16;
} }
330 330
{ {
title = "Bounce Ring Panel"; title = "Bounce Ring Panel";
sprite = "PIKBA0"; sprite = "PIKBA0";
width = 24;
height = 40;
} }
331 331
{ {
title = "Rail Ring Panel"; title = "Rail Ring Panel";
sprite = "PIKRA0"; sprite = "PIKRA0";
width = 24;
height = 40;
} }
332 332
{ {
title = "Automatic Ring Panel"; title = "Automatic Ring Panel";
sprite = "PIKAA0"; sprite = "PIKAA0";
width = 24;
height = 40;
} }
333 333
{ {
title = "Explosion Ring Panel"; title = "Explosion Ring Panel";
sprite = "PIKEA0"; sprite = "PIKEA0";
width = 24;
height = 40;
} }
334 334
{ {
title = "Scatter Ring Panel"; title = "Scatter Ring Panel";
sprite = "PIKSA0"; sprite = "PIKSA0";
width = 24;
height = 40;
} }
335 335
{ {
title = "Grenade Ring Panel"; title = "Grenade Ring Panel";
sprite = "PIKGA0"; sprite = "PIKGA0";
width = 24;
height = 40;
} }
} }
@ -4463,7 +4472,7 @@ thingtypes
color = 10; // Light Green color = 10; // Light Green
title = "Other Collectibles"; title = "Other Collectibles";
width = 16; width = 16;
height = 32; height = 24;
sort = 1; sort = 1;
sprite = "CEMGA0"; sprite = "CEMGA0";
@ -4529,6 +4538,7 @@ thingtypes
{ {
title = "Emerald Hunt Location"; title = "Emerald Hunt Location";
sprite = "SHRDA0"; sprite = "SHRDA0";
height = 32;
flags8height = 24; flags8height = 24;
flags8text = "[8] Float"; flags8text = "[8] Float";
} }

View file

@ -1185,7 +1185,7 @@ udmf
{ {
color = 14; // Yellow color = 14; // Yellow
title = "Rings and Weapon Panels"; title = "Rings and Weapon Panels";
width = 24; width = 16;
height = 24; height = 24;
sprite = "RINGA0"; sprite = "RINGA0";
@ -1193,7 +1193,6 @@ udmf
{ {
title = "Ring"; title = "Ring";
sprite = "RINGA0"; sprite = "RINGA0";
width = 16;
arg0 arg0
{ {
title = "Float?"; title = "Float?";
@ -1227,6 +1226,7 @@ udmf
{ {
title = "Infinity Ring"; title = "Infinity Ring";
sprite = "RNGIA0"; sprite = "RNGIA0";
width = 24;
arg0 arg0
{ {
title = "Float?"; title = "Float?";
@ -1282,7 +1282,6 @@ udmf
{ {
title = "CTF Team Ring (Red)"; title = "CTF Team Ring (Red)";
sprite = "internal:TRNGA0R"; sprite = "internal:TRNGA0R";
width = 16;
arg0 arg0
{ {
title = "Float?"; title = "Float?";
@ -1294,7 +1293,6 @@ udmf
{ {
title = "CTF Team Ring (Blue)"; title = "CTF Team Ring (Blue)";
sprite = "internal:TRNGA0B"; sprite = "internal:TRNGA0B";
width = 16;
arg0 arg0
{ {
title = "Float?"; title = "Float?";
@ -1306,6 +1304,8 @@ udmf
{ {
title = "Bounce Ring Panel"; title = "Bounce Ring Panel";
sprite = "PIKBA0"; sprite = "PIKBA0";
width = 24;
height = 40;
arg0 arg0
{ {
title = "Float?"; title = "Float?";
@ -1317,6 +1317,8 @@ udmf
{ {
title = "Rail Ring Panel"; title = "Rail Ring Panel";
sprite = "PIKRA0"; sprite = "PIKRA0";
width = 24;
height = 40;
arg0 arg0
{ {
title = "Float?"; title = "Float?";
@ -1328,6 +1330,8 @@ udmf
{ {
title = "Automatic Ring Panel"; title = "Automatic Ring Panel";
sprite = "PIKAA0"; sprite = "PIKAA0";
width = 24;
height = 40;
arg0 arg0
{ {
title = "Float?"; title = "Float?";
@ -1339,6 +1343,8 @@ udmf
{ {
title = "Explosion Ring Panel"; title = "Explosion Ring Panel";
sprite = "PIKEA0"; sprite = "PIKEA0";
width = 24;
height = 40;
arg0 arg0
{ {
title = "Float?"; title = "Float?";
@ -1350,6 +1356,8 @@ udmf
{ {
title = "Scatter Ring Panel"; title = "Scatter Ring Panel";
sprite = "PIKSA0"; sprite = "PIKSA0";
width = 24;
height = 40;
arg0 arg0
{ {
title = "Float?"; title = "Float?";
@ -1361,6 +1369,8 @@ udmf
{ {
title = "Grenade Ring Panel"; title = "Grenade Ring Panel";
sprite = "PIKGA0"; sprite = "PIKGA0";
width = 24;
height = 40;
arg0 arg0
{ {
title = "Float?"; title = "Float?";
@ -1375,7 +1385,7 @@ udmf
color = 10; // Light_Green color = 10; // Light_Green
title = "Other Collectibles"; title = "Other Collectibles";
width = 16; width = 16;
height = 32; height = 24;
sort = 1; sort = 1;
sprite = "CEMGA0"; sprite = "CEMGA0";
@ -1445,6 +1455,7 @@ udmf
{ {
title = "Emerald Hunt Location"; title = "Emerald Hunt Location";
sprite = "SHRDA0"; sprite = "SHRDA0";
height = 32;
arg0 arg0
{ {
title = "Float?"; title = "Float?";

View file

@ -141,9 +141,9 @@ endif
OBJDUMP_OPTS?=--wide --source --line-numbers OBJDUMP_OPTS?=--wide --source --line-numbers
OBJCOPY:=$(call Prefix,objcopy) OBJCOPY?=$(call Prefix,objcopy)
OBJDUMP:=$(call Prefix,objdump) OBJDUMP?=$(call Prefix,objdump)
WINDRES:=$(call Prefix,windres) WINDRES?=$(call Prefix,windres)
GZIP?=gzip GZIP?=gzip
GZIP_OPTS?=-9 -f -n GZIP_OPTS?=-9 -f -n
@ -392,4 +392,4 @@ else
@: @:
endif endif
$(warning The handwritten GNU Makefile for SRB2 is deprecated, and may be removed in the future. Please consider switching to CMake.) #$(warning The handwritten GNU Makefile for SRB2 is deprecated, and may be removed in the future. Please consider switching to CMake.)

View file

@ -56,15 +56,18 @@ endif
# This must have high to low order. # This must have high to low order.
gcc_versions:=\ gcc_versions:=\
102 101\ 132 131 130\
93 92 91\ 123 122 121 120\
84 83 82 81\ 114 113 112 111 110\
75 74 73 72 71\ 105 104 103 102 101 100\
64 63 62 61\ 95 94 93 92 91 90\
55 54 53 52 51\ 85 84 83 82 81 80\
75 74 73 72 71 70\
64 63 62 61 60\
55 54 53 52 51 50\
49 48 47 46 45 44 43 42 41 40 49 48 47 46 45 44 43 42 41 40
latest_gcc_version:=10.2 latest_gcc_version:=13.2
# Automatically set version flag, but not if one was # Automatically set version flag, but not if one was
# manually set. And don't bother if this is a clean only # manually set. And don't bother if this is a clean only
@ -74,13 +77,18 @@ ifeq (,$(call Wildvar,GCC% destructive))
# can't use $(CC) --version here since that uses argv[0] to display the name # can't use $(CC) --version here since that uses argv[0] to display the name
# also gcc outputs the information to stderr, so I had to do 2>&1 # also gcc outputs the information to stderr, so I had to do 2>&1
# this program really doesn't like identifying itself # this program really doesn't like identifying itself
version:=$(shell $(CC) -v 2>&1) shellversion:=$(shell $(CC) -v 2>&1)
# Try to remove "-win32"
version:=$(subst -win32,.0,$(shellversion))
# check if this is in fact GCC # check if this is in fact GCC
ifneq (,$(findstring gcc version,$(version))) ifneq (,$(findstring gcc version,$(version)))
# in stark contrast to the name, gcc will give me a nicely formatted version number for free # in stark contrast to the name, gcc will give me a nicely formatted version number for free
version:=$(shell $(CC) -dumpfullversion) shellversion:=$(shell $(CC) -dumpfullversion)
# Try to remove "-win32"
version:=$(subst -win32,.0,$(shellversion))
# Turn version into words of major, minor # Turn version into words of major, minor
v:=$(subst ., ,$(version)) v:=$(subst ., ,$(version))

View file

@ -18,6 +18,10 @@ opts+=-DHWRENDER
sources+=$(call List,hardware/Sourcefile) sources+=$(call List,hardware/Sourcefile)
endif endif
ifdef NONET
NOCURL=1
endif
ifndef NOMD5 ifndef NOMD5
sources+=md5.c sources+=md5.c
endif endif

View file

@ -25,7 +25,7 @@ endif
# Tested by Steel, as of release 2.2.8. # Tested by Steel, as of release 2.2.8.
ifdef FREEBSD ifdef FREEBSD
opts+=-I/usr/X11R6/include -DLINUX -DFREEBSD opts+=-I/usr/X11R6/include -DLINUX -DFREEBSD
libs+=-L/usr/X11R6/lib -lipx -lkvm libs+=-L/usr/X11R6/lib -lkvm -lexecinfo
endif endif
# FIXME: UNTESTED # FIXME: UNTESTED

View file

@ -38,12 +38,14 @@
* Last updated 2021 / 05 / 06 - v2.2.9 - patch.pk3 & zones.pk3 * Last updated 2021 / 05 / 06 - v2.2.9 - patch.pk3 & zones.pk3
* Last updated 2022 / 03 / 06 - v2.2.10 - main assets * Last updated 2022 / 03 / 06 - v2.2.10 - main assets
* Last updated 2023 / 05 / 02 - v2.2.11 - patch.pk3 & zones.pk3 * Last updated 2023 / 05 / 02 - v2.2.11 - patch.pk3 & zones.pk3
* Last updated 2023 / 09 / 06 - v2.2.12 - patch.pk3
* Last updated 2023 / 09 / 09 - v2.2.13 - none
*/ */
#define ASSET_HASH_SRB2_PK3 "ad911f29a28a18968ee5b2d11c2acb39" #define ASSET_HASH_SRB2_PK3 "ad911f29a28a18968ee5b2d11c2acb39"
#define ASSET_HASH_ZONES_PK3 "1c8adf8d079ecb87d00081f158acf3c7" #define ASSET_HASH_ZONES_PK3 "1c8adf8d079ecb87d00081f158acf3c7"
#define ASSET_HASH_PLAYER_DTA "2e7aaae8a6b1b77d90ffe7606ceadb6c" #define ASSET_HASH_PLAYER_DTA "2e7aaae8a6b1b77d90ffe7606ceadb6c"
#ifdef USE_PATCH_DTA #ifdef USE_PATCH_DTA
#define ASSET_HASH_PATCH_PK3 "2e69558bce3b9610624549a75e29e19b" #define ASSET_HASH_PATCH_PK3 "3c7b73f34af7e9a7bceb2d5260f76172"
#endif #endif
#endif #endif

View file

@ -2743,7 +2743,6 @@ static void Command_ClearBans(void)
static void Ban_Load_File(boolean warning) static void Ban_Load_File(boolean warning)
{ {
FILE *f; FILE *f;
size_t i;
const char *address, *mask; const char *address, *mask;
char buffer[MAX_WADPATH]; char buffer[MAX_WADPATH];
@ -2761,7 +2760,7 @@ static void Ban_Load_File(boolean warning)
Ban_Clear(); Ban_Clear();
for (i=0; fgets(buffer, (int)sizeof(buffer), f); i++) for (; fgets(buffer, (int)sizeof(buffer), f);)
{ {
address = strtok(buffer, " \t\r\n"); address = strtok(buffer, " \t\r\n");
mask = strtok(NULL, " \t\r\n"); mask = strtok(NULL, " \t\r\n");

View file

@ -1739,14 +1739,15 @@ void D_SRB2Main(void)
// Prevent warping to nonexistent levels // Prevent warping to nonexistent levels
if (W_CheckNumForName(G_BuildMapName(pstartmap)) == LUMPERROR) if (W_CheckNumForName(G_BuildMapName(pstartmap)) == LUMPERROR)
I_Error("Could not warp to %s (map not found)\n", G_BuildMapName(pstartmap)); I_Error("Could not warp to %s (map not found)\n", G_BuildMapName(pstartmap));
// Prevent warping to locked levels
// ... unless you're in a dedicated server. Yes, technically this means you can view any level by
// running a dedicated server and joining it yourself, but that's better than making dedicated server's
// lives hell.
else if (!dedicated && M_MapLocked(pstartmap, serverGamedata))
I_Error("You need to unlock this level before you can warp to it!\n");
else else
{ {
if (M_CampaignWarpIsCheat(gametype, pstartmap, serverGamedata))
{
// If you're warping via command line, you know what you're doing.
// No need to I_Error over this.
G_SetUsedCheats(false);
}
D_MapChange(pstartmap, gametype, ultimatemode, true, 0, false, false); D_MapChange(pstartmap, gametype, ultimatemode, true, 0, false, false);
} }
} }

View file

@ -764,6 +764,8 @@ void D_RegisterClientCommands(void)
CV_RegisterVar(&cv_showfocuslost); CV_RegisterVar(&cv_showfocuslost);
CV_RegisterVar(&cv_pauseifunfocused); CV_RegisterVar(&cv_pauseifunfocused);
CV_RegisterVar(&cv_instantretry);
// g_input.c // g_input.c
CV_RegisterVar(&cv_sideaxis); CV_RegisterVar(&cv_sideaxis);
CV_RegisterVar(&cv_sideaxis2); CV_RegisterVar(&cv_sideaxis2);
@ -1863,8 +1865,8 @@ static void Command_Map_f(void)
size_t option_gametype; size_t option_gametype;
const char *gametypename; const char *gametypename;
boolean newresetplayers; boolean newresetplayers;
boolean prevent_cheat;
boolean wouldSetCheats; boolean set_cheated;
INT32 newmapnum; INT32 newmapnum;
@ -1885,22 +1887,35 @@ static void Command_Map_f(void)
option_gametype = COM_CheckPartialParm("-g"); option_gametype = COM_CheckPartialParm("-g");
newresetplayers = ! COM_CheckParm("-noresetplayers"); newresetplayers = ! COM_CheckParm("-noresetplayers");
wouldSetCheats = prevent_cheat = !( usedCheats ) && !( option_force || cv_debug );
!( netgame || multiplayer ) && set_cheated = false;
!( usedCheats );
if (wouldSetCheats && !option_force) if (!( netgame || multiplayer ))
{
if (prevent_cheat)
{ {
/* May want to be more descriptive? */ /* May want to be more descriptive? */
CONS_Printf(M_GetText("Sorry, level change disabled in single player.\n")); CONS_Printf(M_GetText("Cheats must be enabled to level change in single player.\n"));
return; return;
} }
else
if (!newresetplayers && !cv_debug)
{ {
CONS_Printf(M_GetText("DEVMODE must be enabled.\n")); set_cheated = true;
}
}
if (!newresetplayers)
{
if (prevent_cheat)
{
CONS_Printf(M_GetText("Cheats must be enabled to use -noresetplayers.\n"));
return; return;
} }
else
{
set_cheated = true;
}
}
if (option_gametype) if (option_gametype)
{ {
@ -1920,7 +1935,9 @@ static void Command_Map_f(void)
} }
if (!( first_option = COM_FirstOption() )) if (!( first_option = COM_FirstOption() ))
{
first_option = COM_Argc(); first_option = COM_Argc();
}
if (first_option < 2) if (first_option < 2)
{ {
@ -1943,11 +1960,6 @@ static void Command_Map_f(void)
return; return;
} }
if (wouldSetCheats && option_force)
{
G_SetUsedCheats(false);
}
// new gametype value // new gametype value
// use current one by default // use current one by default
if (option_gametype) if (option_gametype)
@ -1989,15 +2001,13 @@ static void Command_Map_f(void)
} }
// don't use a gametype the map doesn't support // don't use a gametype the map doesn't support
if (cv_debug || option_force || cv_skipmapcheck.value)
fromlevelselect = false; // The player wants us to trek on anyway. Do so.
// G_TOLFlag handles both multiplayer gametype and ignores it for !multiplayer // G_TOLFlag handles both multiplayer gametype and ignores it for !multiplayer
else
{
if (!( if (!(
mapheaderinfo[newmapnum-1] && mapheaderinfo[newmapnum-1] &&
mapheaderinfo[newmapnum-1]->typeoflevel & G_TOLFlag(newgametype) mapheaderinfo[newmapnum-1]->typeoflevel & G_TOLFlag(newgametype)
)) ))
{
if (prevent_cheat && !cv_skipmapcheck.value)
{ {
CONS_Alert(CONS_WARNING, M_GetText("%s (%s) doesn't support %s mode!\n(Use -force to override)\n"), realmapname, G_BuildMapName(newmapnum), CONS_Alert(CONS_WARNING, M_GetText("%s (%s) doesn't support %s mode!\n(Use -force to override)\n"), realmapname, G_BuildMapName(newmapnum),
(multiplayer ? gametype_cons_t[newgametype].strvalue : "Single Player")); (multiplayer ? gametype_cons_t[newgametype].strvalue : "Single Player"));
@ -2006,25 +2016,35 @@ static void Command_Map_f(void)
return; return;
} }
else else
{
// The player wants us to trek on anyway. Do so.
fromlevelselect = false;
set_cheated = ((gametypes[newgametype].rules & GTR_CAMPAIGN) == GTR_CAMPAIGN);
}
}
else
{ {
fromlevelselect = fromlevelselect =
( netgame || multiplayer ) && ( netgame || multiplayer ) &&
newgametype == gametype && newgametype == gametype &&
gametypes[newgametype].rules & GTR_CAMPAIGN; (gametypes[newgametype].rules & GTR_CAMPAIGN);
}
} }
// Prevent warping to locked levels // Prevent warping to locked levels
// ... unless you're in a dedicated server. Yes, technically this means you can view any level by if (M_CampaignWarpIsCheat(newgametype, newmapnum, serverGamedata))
// running a dedicated server and joining it yourself, but that's better than making dedicated server's
// lives hell.
if (!dedicated && M_MapLocked(newmapnum, serverGamedata))
{ {
CONS_Alert(CONS_NOTICE, M_GetText("You need to unlock this level before you can warp to it!\n")); if (prevent_cheat)
{
CONS_Alert(CONS_NOTICE, M_GetText("Cheats must be enabled to warp to a locked level!\n"));
Z_Free(realmapname); Z_Free(realmapname);
Z_Free(mapname); Z_Free(mapname);
return; return;
} }
else
{
set_cheated = true;
}
}
// Ultimate Mode only in SP via menu // Ultimate Mode only in SP via menu
if (netgame || multiplayer) if (netgame || multiplayer)
@ -2040,6 +2060,11 @@ static void Command_Map_f(void)
} }
tutorialmode = false; // warping takes us out of tutorial mode tutorialmode = false; // warping takes us out of tutorial mode
if (set_cheated && !usedCheats)
{
G_SetUsedCheats(false);
}
D_MapChange(newmapnum, newgametype, false, newresetplayers, 0, false, fromlevelselect); D_MapChange(newmapnum, newgametype, false, newresetplayers, 0, false, fromlevelselect);
Z_Free(realmapname); Z_Free(realmapname);
@ -4236,7 +4261,6 @@ void D_GameTypeChanged(INT32 lastgametype)
else if (!multiplayer && !netgame) else if (!multiplayer && !netgame)
{ {
// Allow setting gametypes other than Co-Op in singleplayer // Allow setting gametypes other than Co-Op in singleplayer
// G_SetGametype(GT_COOP);
} }
// reset timelimit and pointlimit in race/coop, prevent stupid cheats // reset timelimit and pointlimit in race/coop, prevent stupid cheats
@ -4538,25 +4562,37 @@ static void Command_Mapmd5_f(void)
CONS_Printf(M_GetText("You must be in a level to use this.\n")); CONS_Printf(M_GetText("You must be in a level to use this.\n"));
} }
void D_SendExitLevel(boolean cheat)
{
UINT8 buf[8];
UINT8 *buf_p = buf;
WRITEUINT8(buf_p, cheat);
SendNetXCmd(XD_EXITLEVEL, &buf, buf_p - buf);
}
static void Command_ExitLevel_f(void) static void Command_ExitLevel_f(void)
{ {
if (!(netgame || (multiplayer && gametype != GT_COOP)) && !cv_debug) if (!(server || (IsPlayerAdmin(consoleplayer))))
CONS_Printf(M_GetText("This only works in a netgame.\n"));
else if (!(server || (IsPlayerAdmin(consoleplayer))))
CONS_Printf(M_GetText("Only the server or a remote admin can use this.\n")); CONS_Printf(M_GetText("Only the server or a remote admin can use this.\n"));
else if (( gamestate != GS_LEVEL && gamestate != GS_CREDITS ) || demoplayback) else if (( gamestate != GS_LEVEL && gamestate != GS_CREDITS ) || demoplayback)
CONS_Printf(M_GetText("You must be in a level to use this.\n")); CONS_Printf(M_GetText("You must be in a level to use this.\n"));
else else
SendNetXCmd(XD_EXITLEVEL, NULL, 0); D_SendExitLevel(true);
} }
static void Got_ExitLevelcmd(UINT8 **cp, INT32 playernum) static void Got_ExitLevelcmd(UINT8 **cp, INT32 playernum)
{ {
(void)cp; boolean cheat = false;
cheat = (boolean)READUINT8(*cp);
// Ignore duplicate XD_EXITLEVEL commands. // Ignore duplicate XD_EXITLEVEL commands.
if (gameaction == ga_completed) if (gameaction == ga_completed)
{
return; return;
}
if (playernum != serverplayer && !IsPlayerAdmin(playernum)) if (playernum != serverplayer && !IsPlayerAdmin(playernum))
{ {
@ -4566,6 +4602,11 @@ static void Got_ExitLevelcmd(UINT8 **cp, INT32 playernum)
return; return;
} }
if (G_CoopGametype() && cheat)
{
G_SetUsedCheats(false);
}
G_ExitLevel(); G_ExitLevel();
} }

View file

@ -201,6 +201,7 @@ void D_SendPlayerConfig(void);
void Command_ExitGame_f(void); void Command_ExitGame_f(void);
void Command_Retry_f(void); void Command_Retry_f(void);
void D_GameTypeChanged(INT32 lastgametype); // not a real _OnChange function anymore void D_GameTypeChanged(INT32 lastgametype); // not a real _OnChange function anymore
void D_SendExitLevel(boolean cheat);
void D_MapChange(INT32 pmapnum, INT32 pgametype, boolean pultmode, boolean presetplayers, INT32 pdelay, boolean pskipprecutscene, boolean pfromlevelselect); void D_MapChange(INT32 pmapnum, INT32 pgametype, boolean pultmode, boolean presetplayers, INT32 pdelay, boolean pskipprecutscene, boolean pfromlevelselect);
boolean IsPlayerAdmin(INT32 playernum); boolean IsPlayerAdmin(INT32 playernum);
void SetAdminPlayer(INT32 playernum); void SetAdminPlayer(INT32 playernum);

View file

@ -287,8 +287,8 @@ static int ScanConstants(lua_State *L, boolean mathlib, const char *word)
} }
else if (fastncmp("MTF_", word, 4)) { else if (fastncmp("MTF_", word, 4)) {
p = word+4; p = word+4;
for (i = 0; i < 4; i++) for (i = 0; MAPTHINGFLAG_LIST[i]; i++)
if (MAPTHINGFLAG_LIST[i] && fastcmp(p, MAPTHINGFLAG_LIST[i])) { if (fastcmp(p, MAPTHINGFLAG_LIST[i])) {
CacheAndPushConstant(L, word, ((lua_Integer)1<<i)); CacheAndPushConstant(L, word, ((lua_Integer)1<<i));
return 1; return 1;
} }

View file

@ -4412,11 +4412,12 @@ const char *const MOBJEFLAG_LIST[] = {
NULL NULL
}; };
const char *const MAPTHINGFLAG_LIST[4] = { const char *const MAPTHINGFLAG_LIST[] = {
"EXTRA", // Extra flag for objects. "EXTRA", // Extra flag for objects.
"OBJECTFLIP", // Reverse gravity flag for objects. "OBJECTFLIP", // Reverse gravity flag for objects.
"OBJECTSPECIAL", // Special flag used with certain objects. "OBJECTSPECIAL", // Special flag used with certain objects.
"AMBUSH" // Deaf monsters/do not react to sound. "AMBUSH", // Deaf monsters/do not react to sound.
"ABSOLUTEZ" // Absolute spawn height flag for objects.
}; };
const char *const PLAYERFLAG_LIST[] = { const char *const PLAYERFLAG_LIST[] = {
@ -4615,8 +4616,7 @@ const char *COLOR_ENUMS[] = {
// Desaturated // Desaturated
"AETHER", // SKINCOLOR_AETHER, "AETHER", // SKINCOLOR_AETHER,
"SLATE", // SKINCOLOR_SLATE, "SLATE", // SKINCOLOR_SLATE,
"METEORITE", // SKINCOLOR_METEORITE, "MOONSTONE", // SKINCOLOR_MOONSTONE,
"MERCURY", // SKINCOLOR_MERCURY,
"BLUEBELL", // SKINCOLOR_BLUEBELL, "BLUEBELL", // SKINCOLOR_BLUEBELL,
"PINK", // SKINCOLOR_PINK, "PINK", // SKINCOLOR_PINK,
"ROSEWOOD", // SKINCOLOR_ROSEWOOD, "ROSEWOOD", // SKINCOLOR_ROSEWOOD,
@ -4653,10 +4653,10 @@ const char *COLOR_ENUMS[] = {
"COPPER", // SKINCOLOR_COPPER, "COPPER", // SKINCOLOR_COPPER,
"APRICOT", // SKINCOLOR_APRICOT, "APRICOT", // SKINCOLOR_APRICOT,
"ORANGE", // SKINCOLOR_ORANGE, "ORANGE", // SKINCOLOR_ORANGE,
"PUMPKIN", // SKINCOLOR_PUMPKIN,
"RUST", // SKINCOLOR_RUST, "RUST", // SKINCOLOR_RUST,
"GOLD", // SKINCOLOR_GOLD, "TANGERINE", // SKINCOLOR_TANGERINE,
"TOPAZ", // SKINCOLOR_TOPAZ, "TOPAZ", // SKINCOLOR_TOPAZ,
"GOLD", // SKINCOLOR_GOLD,
"SANDY", // SKINCOLOR_SANDY, "SANDY", // SKINCOLOR_SANDY,
"GOLDENROD", // SKINCOLOR_GOLDENROD, "GOLDENROD", // SKINCOLOR_GOLDENROD,
"YELLOW", // SKINCOLOR_YELLOW, "YELLOW", // SKINCOLOR_YELLOW,
@ -4666,20 +4666,21 @@ const char *COLOR_ENUMS[] = {
"LIME", // SKINCOLOR_LIME, "LIME", // SKINCOLOR_LIME,
"PERIDOT", // SKINCOLOR_PERIDOT, "PERIDOT", // SKINCOLOR_PERIDOT,
"APPLE", // SKINCOLOR_APPLE, "APPLE", // SKINCOLOR_APPLE,
"HEADLIGHT", // SKINCOLOR_HEADLIGHT,
"CHARTREUSE", // SKINCOLOR_CHARTREUSE, "CHARTREUSE", // SKINCOLOR_CHARTREUSE,
"GREEN", // SKINCOLOR_GREEN, "GREEN", // SKINCOLOR_GREEN,
"FOREST", // SKINCOLOR_FOREST, "FOREST", // SKINCOLOR_FOREST,
"SHAMROCK", // SKINCOLOR_SHAMROCK, "SHAMROCK", // SKINCOLOR_SHAMROCK,
"JADE", // SKINCOLOR_JADE, "JADE", // SKINCOLOR_JADE,
"HEADLIGHT", // SKINCOLOR_HEADLIGHT,
"MINT", // SKINCOLOR_MINT, "MINT", // SKINCOLOR_MINT,
"MASTER", // SKINCOLOR_MASTER, "MASTER", // SKINCOLOR_MASTER,
"EMERALD", // SKINCOLOR_EMERALD, "EMERALD", // SKINCOLOR_EMERALD,
"BOTTLE", // SKINCOLOR_BOTTLE,
"SEAFOAM", // SKINCOLOR_SEAFOAM, "SEAFOAM", // SKINCOLOR_SEAFOAM,
"ISLAND", // SKINCOLOR_ISLAND, "ISLAND", // SKINCOLOR_ISLAND,
"BOTTLE", // SKINCOLOR_BOTTLE,
"AQUA", // SKINCOLOR_AQUA, "AQUA", // SKINCOLOR_AQUA,
"TEAL", // SKINCOLOR_TEAL, "TEAL", // SKINCOLOR_TEAL,
"OCEAN", // SKINCOLOR_OCEAN,
"WAVE", // SKINCOLOR_WAVE, "WAVE", // SKINCOLOR_WAVE,
"CYAN", // SKINCOLOR_CYAN, "CYAN", // SKINCOLOR_CYAN,
"TURQUOISE", // SKINCOLOR_TURQUOISE, "TURQUOISE", // SKINCOLOR_TURQUOISE,
@ -4705,7 +4706,7 @@ const char *COLOR_ENUMS[] = {
"NOBLE", // SKINCOLOR_NOBLE, "NOBLE", // SKINCOLOR_NOBLE,
"FUCHSIA", // SKINCOLOR_FUCHSIA, "FUCHSIA", // SKINCOLOR_FUCHSIA,
"BUBBLEGUM", // SKINCOLOR_BUBBLEGUM, "BUBBLEGUM", // SKINCOLOR_BUBBLEGUM,
"CRYSTAL", // SKINCOLOR_CRYSTAL, "SIBERITE", // SKINCOLOR_SIBERITE,
"MAGENTA", // SKINCOLOR_MAGENTA, "MAGENTA", // SKINCOLOR_MAGENTA,
"NEON", // SKINCOLOR_NEON, "NEON", // SKINCOLOR_NEON,
"VIOLET", // SKINCOLOR_VIOLET, "VIOLET", // SKINCOLOR_VIOLET,

View file

@ -62,7 +62,7 @@ extern const char *const MOBJTYPE_LIST[];
extern const char *const MOBJFLAG_LIST[]; extern const char *const MOBJFLAG_LIST[];
extern const char *const MOBJFLAG2_LIST[]; // \tMF2_(\S+).*// (.+) --> \t"\1", // \2 extern const char *const MOBJFLAG2_LIST[]; // \tMF2_(\S+).*// (.+) --> \t"\1", // \2
extern const char *const MOBJEFLAG_LIST[]; extern const char *const MOBJEFLAG_LIST[];
extern const char *const MAPTHINGFLAG_LIST[4]; extern const char *const MAPTHINGFLAG_LIST[];
extern const char *const PLAYERFLAG_LIST[]; extern const char *const PLAYERFLAG_LIST[];
extern const char *const GAMETYPERULE_LIST[]; extern const char *const GAMETYPERULE_LIST[];
extern const char *const ML_LIST[]; // Linedef flags extern const char *const ML_LIST[]; // Linedef flags

View file

@ -62,6 +62,10 @@ enum
#define MTF_AMBUSH 8 #define MTF_AMBUSH 8
// Do not use bit five or after, as they are used for object z-offsets. // Do not use bit five or after, as they are used for object z-offsets.
// Unless it's exclusive to UDMF.
// Flag to use Z as absolute spawn height, ignoring the floor and ceiling.
#define MTF_ABSOLUTEZ 16
#if defined(_MSC_VER) #if defined(_MSC_VER)
#pragma pack(1) #pragma pack(1)

View file

@ -269,8 +269,7 @@ typedef enum
// Desaturated // Desaturated
SKINCOLOR_AETHER, SKINCOLOR_AETHER,
SKINCOLOR_SLATE, SKINCOLOR_SLATE,
SKINCOLOR_METEORITE, SKINCOLOR_MOONSTONE,
SKINCOLOR_MERCURY,
SKINCOLOR_BLUEBELL, SKINCOLOR_BLUEBELL,
SKINCOLOR_PINK, SKINCOLOR_PINK,
SKINCOLOR_ROSEWOOD, SKINCOLOR_ROSEWOOD,
@ -307,10 +306,10 @@ typedef enum
SKINCOLOR_COPPER, SKINCOLOR_COPPER,
SKINCOLOR_APRICOT, SKINCOLOR_APRICOT,
SKINCOLOR_ORANGE, SKINCOLOR_ORANGE,
SKINCOLOR_PUMPKIN,
SKINCOLOR_RUST, SKINCOLOR_RUST,
SKINCOLOR_GOLD, SKINCOLOR_TANGERINE,
SKINCOLOR_TOPAZ, SKINCOLOR_TOPAZ,
SKINCOLOR_GOLD,
SKINCOLOR_SANDY, SKINCOLOR_SANDY,
SKINCOLOR_GOLDENROD, SKINCOLOR_GOLDENROD,
SKINCOLOR_YELLOW, SKINCOLOR_YELLOW,
@ -320,20 +319,21 @@ typedef enum
SKINCOLOR_LIME, SKINCOLOR_LIME,
SKINCOLOR_PERIDOT, SKINCOLOR_PERIDOT,
SKINCOLOR_APPLE, SKINCOLOR_APPLE,
SKINCOLOR_HEADLIGHT,
SKINCOLOR_CHARTREUSE, SKINCOLOR_CHARTREUSE,
SKINCOLOR_GREEN, SKINCOLOR_GREEN,
SKINCOLOR_FOREST, SKINCOLOR_FOREST,
SKINCOLOR_SHAMROCK, SKINCOLOR_SHAMROCK,
SKINCOLOR_JADE, SKINCOLOR_JADE,
SKINCOLOR_HEADLIGHT,
SKINCOLOR_MINT, SKINCOLOR_MINT,
SKINCOLOR_MASTER, SKINCOLOR_MASTER,
SKINCOLOR_EMERALD, SKINCOLOR_EMERALD,
SKINCOLOR_BOTTLE,
SKINCOLOR_SEAFOAM, SKINCOLOR_SEAFOAM,
SKINCOLOR_ISLAND, SKINCOLOR_ISLAND,
SKINCOLOR_BOTTLE,
SKINCOLOR_AQUA, SKINCOLOR_AQUA,
SKINCOLOR_TEAL, SKINCOLOR_TEAL,
SKINCOLOR_OCEAN,
SKINCOLOR_WAVE, SKINCOLOR_WAVE,
SKINCOLOR_CYAN, SKINCOLOR_CYAN,
SKINCOLOR_TURQUOISE, SKINCOLOR_TURQUOISE,
@ -359,7 +359,7 @@ typedef enum
SKINCOLOR_NOBLE, SKINCOLOR_NOBLE,
SKINCOLOR_FUCHSIA, SKINCOLOR_FUCHSIA,
SKINCOLOR_BUBBLEGUM, SKINCOLOR_BUBBLEGUM,
SKINCOLOR_CRYSTAL, SKINCOLOR_SIBERITE,
SKINCOLOR_MAGENTA, SKINCOLOR_MAGENTA,
SKINCOLOR_NEON, SKINCOLOR_NEON,
SKINCOLOR_VIOLET, SKINCOLOR_VIOLET,

View file

@ -113,6 +113,15 @@ int endswith (const char *base, const char *tag);
#define HAVE_DOSSTR_FUNCS #define HAVE_DOSSTR_FUNCS
#endif #endif
#if defined (__APPLE__)
#define SRB2_HAVE_STRLCPY
#elif defined (__GLIBC_PREREQ)
// glibc 2.38: added strlcpy and strlcat to _DEFAULT_SOURCE
#if __GLIBC_PREREQ(2, 38)
#define SRB2_HAVE_STRLCPY
#endif
#endif
#ifndef HAVE_DOSSTR_FUNCS #ifndef HAVE_DOSSTR_FUNCS
int strupr(char *n); // from dosstr.c int strupr(char *n); // from dosstr.c
int strlwr(char *n); // from dosstr.c int strlwr(char *n); // from dosstr.c
@ -120,7 +129,7 @@ int strlwr(char *n); // from dosstr.c
#include <stddef.h> // for size_t #include <stddef.h> // for size_t
#ifndef __APPLE__ #ifndef SRB2_HAVE_STRLCPY
size_t strlcat(char *dst, const char *src, size_t siz); size_t strlcat(char *dst, const char *src, size_t siz);
size_t strlcpy(char *dst, const char *src, size_t siz); size_t strlcpy(char *dst, const char *src, size_t siz);
#endif #endif

View file

@ -14,13 +14,18 @@ size_t I_GetFreeMem(size_t *total)
return 0; return 0;
} }
void I_Sleep(UINT32 ms){} void I_Sleep(UINT32 ms)
{
(void)ms;
}
precise_t I_GetPreciseTime(void) { precise_t I_GetPreciseTime(void)
{
return 0; return 0;
} }
UINT64 I_GetPrecisePrecision(void) { UINT64 I_GetPrecisePrecision(void)
{
return 1000000; return 1000000;
} }
@ -182,6 +187,8 @@ const char *I_ClipboardPaste(void)
size_t I_GetRandomBytes(char *destination, size_t amount) size_t I_GetRandomBytes(char *destination, size_t amount)
{ {
(void)destination;
(void)amount;
return 0; return 0;
} }

View file

@ -1062,12 +1062,14 @@ static const char *credits[] = {
"\"Golden\"", "\"Golden\"",
"Vivian \"toaster\" Grannell", "Vivian \"toaster\" Grannell",
"Julio \"Chaos Zero 64\" Guir", "Julio \"Chaos Zero 64\" Guir",
"\"Hanicef\"",
"\"Hannu_Hanhi\"", // For many OpenGL performance improvements! "\"Hannu_Hanhi\"", // For many OpenGL performance improvements!
"Kepa \"Nev3r\" Iceta", "Kepa \"Nev3r\" Iceta",
"Thomas \"Shadow Hog\" Igoe", "Thomas \"Shadow Hog\" Igoe",
"Iestyn \"Monster Iestyn\" Jealous", "Iestyn \"Monster Iestyn\" Jealous",
"\"Kaito Sinclaire\"", "\"Kaito Sinclaire\"",
"\"Kalaron\"", // Coded some of Sryder13's collection of OpenGL fixes, especially fog "\"Kalaron\"", // Coded some of Sryder13's collection of OpenGL fixes, especially fog
"\"katsy\"",
"Ronald \"Furyhunter\" Kinard", // The SDL2 port "Ronald \"Furyhunter\" Kinard", // The SDL2 port
"\"Lat'\"", // SRB2-CHAT, the chat window from Kart "\"Lat'\"", // SRB2-CHAT, the chat window from Kart
"\"LZA\"", "\"LZA\"",
@ -1090,6 +1092,7 @@ static const char *credits[] = {
"Ben \"Cue\" Woodford", "Ben \"Cue\" Woodford",
"Lachlan \"Lach\" Wright", "Lachlan \"Lach\" Wright",
"Marco \"mazmazz\" Zafra", "Marco \"mazmazz\" Zafra",
"\"Zwip-Zwap Zapony\"",
"", "",
"\1Art", "\1Art",
"Victor \"VAdaPEGA\" Ara\x1Fjo", // Araújo -- sorry for our limited font! D: "Victor \"VAdaPEGA\" Ara\x1Fjo", // Araújo -- sorry for our limited font! D:
@ -1197,6 +1200,7 @@ static const char *credits[] = {
"FreeDoom Project", // Used some of the mancubus and rocket launcher sprites for Brak "FreeDoom Project", // Used some of the mancubus and rocket launcher sprites for Brak
"Kart Krew", "Kart Krew",
"Alex \"MistaED\" Fuller", "Alex \"MistaED\" Fuller",
"Howard Drossin", // Virtual Sonic - Sonic & Knuckles Theme
"Pascal \"CodeImp\" vd Heiden", // Doom Builder developer "Pascal \"CodeImp\" vd Heiden", // Doom Builder developer
"Randi Heit (<!>)", // For their MSPaint <!> sprite that we nicked "Randi Heit (<!>)", // For their MSPaint <!> sprite that we nicked
"Simon \"sirjuddington\" Judd", // SLADE developer "Simon \"sirjuddington\" Judd", // SLADE developer
@ -1644,7 +1648,7 @@ void F_GameEvaluationTicker(void)
sparklloop = 0; sparklloop = 0;
} }
if (finalecount == 5*TICRATE) if (G_CoopGametype() && !stagefailed && finalecount == 5*TICRATE)
{ {
serverGamedata->timesBeaten++; serverGamedata->timesBeaten++;
clientGamedata->timesBeaten++; clientGamedata->timesBeaten++;
@ -2256,7 +2260,7 @@ void F_InitMenuPresValues(void)
curfadevalue = 16; curfadevalue = 16;
curbgcolor = -1; curbgcolor = -1;
curbgxspeed = (gamestate == GS_TIMEATTACK) ? 0 : titlescrollxspeed; curbgxspeed = (gamestate == GS_TIMEATTACK) ? 0 : titlescrollxspeed;
curbgyspeed = (gamestate == GS_TIMEATTACK) ? 22 : titlescrollyspeed; curbgyspeed = (gamestate == GS_TIMEATTACK) ? 18 : titlescrollyspeed;
curbghide = (gamestate == GS_TIMEATTACK) ? false : true; curbghide = (gamestate == GS_TIMEATTACK) ? false : true;
curhidepics = hidetitlepics; curhidepics = hidetitlepics;

View file

@ -315,6 +315,8 @@ consvar_t cv_consolechat = CVAR_INIT ("chatmode", "Window", CV_SAVE, consolechat
// Pause game upon window losing focus // Pause game upon window losing focus
consvar_t cv_pauseifunfocused = CVAR_INIT ("pauseifunfocused", "Yes", CV_SAVE, CV_YesNo, NULL); consvar_t cv_pauseifunfocused = CVAR_INIT ("pauseifunfocused", "Yes", CV_SAVE, CV_YesNo, NULL);
consvar_t cv_instantretry = CVAR_INIT ("instantretry", "No", CV_SAVE, CV_YesNo, NULL);
consvar_t cv_crosshair = CVAR_INIT ("crosshair", "Cross", CV_SAVE, crosshair_cons_t, NULL); consvar_t cv_crosshair = CVAR_INIT ("crosshair", "Cross", CV_SAVE, crosshair_cons_t, NULL);
consvar_t cv_crosshair2 = CVAR_INIT ("crosshair2", "Cross", CV_SAVE, crosshair_cons_t, NULL); consvar_t cv_crosshair2 = CVAR_INIT ("crosshair2", "Cross", CV_SAVE, crosshair_cons_t, NULL);
consvar_t cv_invertmouse = CVAR_INIT ("invertmouse", "Off", CV_SAVE, CV_OnOff, NULL); consvar_t cv_invertmouse = CVAR_INIT ("invertmouse", "Off", CV_SAVE, CV_OnOff, NULL);
@ -2079,7 +2081,7 @@ boolean G_Responder(event_t *ev)
if (gameaction == ga_nothing && !singledemo && if (gameaction == ga_nothing && !singledemo &&
((demoplayback && !modeattacking && !titledemo) || gamestate == GS_TITLESCREEN)) ((demoplayback && !modeattacking && !titledemo) || gamestate == GS_TITLESCREEN))
{ {
if (ev->type == ev_keydown && ev->key != 301 && !(gamestate == GS_TITLESCREEN && finalecount < TICRATE)) if (ev->type == ev_keydown && ev->key != 301 && !(gamestate == GS_TITLESCREEN && finalecount < (cv_tutorialprompt.value ? TICRATE : 0)))
{ {
M_StartControlPanel(); M_StartControlPanel();
return true; return true;
@ -2137,7 +2139,7 @@ boolean G_Responder(event_t *ev)
if (! netgame) if (! netgame)
F_StartGameEvaluation(); F_StartGameEvaluation();
else if (server || IsPlayerAdmin(consoleplayer)) else if (server || IsPlayerAdmin(consoleplayer))
SendNetXCmd(XD_EXITLEVEL, NULL, 0); D_SendExitLevel(false);
return true; return true;
} }
} }
@ -2172,9 +2174,9 @@ boolean G_Responder(event_t *ev)
if (menuactive || pausedelay < 0 || leveltime < 2) if (menuactive || pausedelay < 0 || leveltime < 2)
return true; return true;
if (pausedelay < 1+(NEWTICRATE/2)) if (!cv_instantretry.value && pausedelay < 1+(NEWTICRATE/2))
pausedelay = 1+(NEWTICRATE/2); pausedelay = 1+(NEWTICRATE/2);
else if (++pausedelay > 1+(NEWTICRATE/2)+(NEWTICRATE/3)) else if (cv_instantretry.value || ++pausedelay > 1+(NEWTICRATE/2)+(NEWTICRATE/3))
{ {
G_SetModeAttackRetryFlag(); G_SetModeAttackRetryFlag();
return true; return true;
@ -4548,7 +4550,7 @@ static INT16 RandMap(UINT32 tolflags, INT16 pprevmap)
for (ix = 0; ix < NUMMAPS; ix++) for (ix = 0; ix < NUMMAPS; ix++)
if (mapheaderinfo[ix] && (mapheaderinfo[ix]->typeoflevel & tolflags) == tolflags if (mapheaderinfo[ix] && (mapheaderinfo[ix]->typeoflevel & tolflags) == tolflags
&& ix != pprevmap // Don't pick the same map. && ix != pprevmap // Don't pick the same map.
&& (dedicated || !M_MapLocked(ix+1, serverGamedata)) // Don't pick locked maps. && (!M_MapLocked(ix+1, serverGamedata)) // Don't pick locked maps.
) )
okmaps[numokmaps++] = ix; okmaps[numokmaps++] = ix;
@ -4811,7 +4813,7 @@ static void G_DoCompleted(void)
{ {
token--; token--;
if (!nextmapoverride) // if (!nextmapoverride) // Having a token should pull the player into the special stage before going to the overridden map (Issue #933)
for (i = 0; i < 7; i++) for (i = 0; i < 7; i++)
if (!(emeralds & (1<<i))) if (!(emeralds & (1<<i)))
{ {

View file

@ -49,6 +49,8 @@ extern boolean promptactive;
extern consvar_t cv_pauseifunfocused; extern consvar_t cv_pauseifunfocused;
extern consvar_t cv_instantretry;
// used in game menu // used in game menu
extern consvar_t cv_tutorialprompt; extern consvar_t cv_tutorialprompt;
extern consvar_t cv_chatwidth, cv_chatnotifications, cv_chatheight, cv_chattime, cv_consolechat, cv_chatbacktint, cv_chatspamprotection, cv_compactscoreboard; extern consvar_t cv_chatwidth, cv_chatnotifications, cv_chatheight, cv_chattime, cv_consolechat, cv_chatbacktint, cv_chatspamprotection, cv_compactscoreboard;

View file

@ -1699,7 +1699,7 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
if ((rover->fofflags & FOF_TRANSLUCENT && !(rover->fofflags & FOF_SPLAT)) || rover->blend) if ((rover->fofflags & FOF_TRANSLUCENT && !(rover->fofflags & FOF_SPLAT)) || rover->blend)
{ {
blendmode = rover->blend ? HWR_GetBlendModeFlag(rover->blend) : PF_Translucent; blendmode = rover->blend ? HWR_GetBlendModeFlag(rover->blend) : PF_Translucent;
Surf.PolyColor.s.alpha = (UINT8)rover->alpha-1 > 255 ? 255 : rover->alpha-1; Surf.PolyColor.s.alpha = max(0, min(rover->alpha, 255));
} }
if (gl_frontsector->numlights) if (gl_frontsector->numlights)
@ -1822,7 +1822,7 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
if ((rover->fofflags & FOF_TRANSLUCENT && !(rover->fofflags & FOF_SPLAT)) || rover->blend) if ((rover->fofflags & FOF_TRANSLUCENT && !(rover->fofflags & FOF_SPLAT)) || rover->blend)
{ {
blendmode = rover->blend ? HWR_GetBlendModeFlag(rover->blend) : PF_Translucent; blendmode = rover->blend ? HWR_GetBlendModeFlag(rover->blend) : PF_Translucent;
Surf.PolyColor.s.alpha = (UINT8)rover->alpha-1 > 255 ? 255 : rover->alpha-1; Surf.PolyColor.s.alpha = max(0, min(rover->alpha, 255));
} }
if (gl_backsector->numlights) if (gl_backsector->numlights)
@ -3095,7 +3095,7 @@ static void HWR_Subsector(size_t num)
false, false,
*rover->bottomheight, *rover->bottomheight,
*gl_frontsector->lightlist[light].lightlevel, *gl_frontsector->lightlist[light].lightlevel,
rover->alpha-1 > 255 ? 255 : rover->alpha-1, rover->master->frontsector, max(0, min(rover->alpha, 255)), rover->master->frontsector,
HWR_RippleBlend(gl_frontsector, rover, false) | (rover->blend ? HWR_GetBlendModeFlag(rover->blend) : PF_Translucent), HWR_RippleBlend(gl_frontsector, rover, false) | (rover->blend ? HWR_GetBlendModeFlag(rover->blend) : PF_Translucent),
false, *gl_frontsector->lightlist[light].extra_colormap); false, *gl_frontsector->lightlist[light].extra_colormap);
} }
@ -3141,7 +3141,7 @@ static void HWR_Subsector(size_t num)
true, true,
*rover->topheight, *rover->topheight,
*gl_frontsector->lightlist[light].lightlevel, *gl_frontsector->lightlist[light].lightlevel,
rover->alpha-1 > 255 ? 255 : rover->alpha-1, rover->master->frontsector, max(0, min(rover->alpha, 255)), rover->master->frontsector,
HWR_RippleBlend(gl_frontsector, rover, false) | (rover->blend ? HWR_GetBlendModeFlag(rover->blend) : PF_Translucent), HWR_RippleBlend(gl_frontsector, rover, false) | (rover->blend ? HWR_GetBlendModeFlag(rover->blend) : PF_Translucent),
false, *gl_frontsector->lightlist[light].extra_colormap); false, *gl_frontsector->lightlist[light].extra_colormap);
} }
@ -3595,7 +3595,7 @@ static void HWR_DrawDropShadow(mobj_t *thing, fixed_t scale)
return; return;
} }
floordiff = abs((flip < 0 ? thing->height : 0) + interp.z - groundz); floordiff = abs((flip < 0 ? interp.height : 0) + interp.z - groundz);
alpha = floordiff / (4*FRACUNIT) + 75; alpha = floordiff / (4*FRACUNIT) + 75;
if (alpha >= 255) return; if (alpha >= 255) return;
@ -3606,9 +3606,7 @@ static void HWR_DrawDropShadow(mobj_t *thing, fixed_t scale)
HWR_GetPatch(gpatch); HWR_GetPatch(gpatch);
scalemul = FixedMul(FRACUNIT - floordiff/640, scale); scalemul = FixedMul(FRACUNIT - floordiff/640, scale);
scalemul = FixedMul(scalemul, (thing->radius*2) / gpatch->height); scalemul = FixedMul(scalemul, (interp.radius*2) / gpatch->height);
if ((thing->scale != thing->old_scale) && (thing->scale >= FRACUNIT/1024)) // Interpolate shadows when scaling mobjs
scalemul = FixedMul(scalemul, FixedDiv(interp.scale, thing->scale));
fscale = FIXED_TO_FLOAT(scalemul); fscale = FIXED_TO_FLOAT(scalemul);
fx = FIXED_TO_FLOAT(interp.x); fx = FIXED_TO_FLOAT(interp.x);
@ -3720,7 +3718,7 @@ static void HWR_RotateSpritePolyToAim(gl_vissprite_t *spr, FOutVector *wallVerts
if (P_MobjFlip(spr->mobj) == -1) if (P_MobjFlip(spr->mobj) == -1)
{ {
basey = FIXED_TO_FLOAT(interp.z + spr->mobj->height); basey = FIXED_TO_FLOAT(interp.z + interp.height);
} }
else else
{ {
@ -4055,32 +4053,32 @@ static void HWR_DrawBoundingBox(gl_vissprite_t *vis)
// repeat this 4 times (overhead) // repeat this 4 times (overhead)
// //
// //
// 17 20 21 11 // 15 16 17 09
// 16 15 14 10 // 14 13 12 08
// 27 22 *--* 07 12 // 23 18 *--* 07 10
// | | // | |
// 26 23 *--* 06 13 // 22 19 *--* 06 11
// 24 00 01 02 // 20 00 01 02
// 25 05 04 03 // 21 05 04 03
// //
v[000].x = v[005].x = v[015].x = v[016].x = v[017].x = v[020].x = v[ 0].x = v[ 5].x = v[13].x = v[14].x = v[15].x = v[16].x =
v[022].x = v[023].x = v[024].x = v[025].x = v[026].x = v[027].x = vis->x1; // west v[18].x = v[19].x = v[20].x = v[21].x = v[22].x = v[23].x = vis->x1; // west
v[001].x = v[002].x = v[003].x = v[004].x = v[006].x = v[007].x = v[ 1].x = v[ 2].x = v[ 3].x = v[ 4].x = v[ 6].x = v[ 7].x =
v[010].x = v[011].x = v[012].x = v[013].x = v[014].x = v[021].x = vis->x2; // east v[ 8].x = v[ 9].x = v[10].x = v[11].x = v[12].x = v[17].x = vis->x2; // east
v[000].z = v[001].z = v[002].z = v[003].z = v[004].z = v[005].z = v[ 0].z = v[ 1].z = v[ 2].z = v[ 3].z = v[ 4].z = v[ 5].z =
v[006].z = v[013].z = v[023].z = v[024].z = v[025].z = v[026].z = vis->z1; // south v[ 6].z = v[11].z = v[19].z = v[20].z = v[21].z = v[22].z = vis->z1; // south
v[007].z = v[010].z = v[011].z = v[012].z = v[014].z = v[015].z = v[ 7].z = v[ 8].z = v[ 9].z = v[10].z = v[12].z = v[13].z =
v[016].z = v[017].z = v[020].z = v[021].z = v[022].z = v[027].z = vis->z2; // north v[14].z = v[15].z = v[16].z = v[17].z = v[18].z = v[23].z = vis->z2; // north
v[000].y = v[001].y = v[002].y = v[006].y = v[007].y = v[010].y = v[ 0].y = v[ 1].y = v[ 2].y = v[ 6].y = v[ 7].y = v[ 8].y =
v[014].y = v[015].y = v[016].y = v[022].y = v[023].y = v[024].y = vis->gz; // bottom v[12].y = v[13].y = v[14].y = v[18].y = v[19].y = v[20].y = vis->gz; // bottom
v[003].y = v[004].y = v[005].y = v[011].y = v[012].y = v[013].y = v[ 3].y = v[ 4].y = v[ 5].y = v[ 9].y = v[10].y = v[11].y =
v[017].y = v[020].y = v[021].y = v[025].y = v[026].y = v[027].y = vis->gzt; // top v[15].y = v[16].y = v[17].y = v[21].y = v[22].y = v[23].y = vis->gzt; // top
Surf.PolyColor = V_GetColor(R_GetBoundingBoxColor(vis->mobj)); Surf.PolyColor = V_GetColor(R_GetBoundingBoxColor(vis->mobj));
@ -4143,14 +4141,11 @@ static void HWR_DrawSprite(gl_vissprite_t *spr)
float xscale, yscale; float xscale, yscale;
float xoffset, yoffset; float xoffset, yoffset;
float leftoffset, topoffset; float leftoffset, topoffset;
float scale = spr->scale;
float zoffset = (P_MobjFlip(spr->mobj) * 0.05f); float zoffset = (P_MobjFlip(spr->mobj) * 0.05f);
pslope_t *splatslope = NULL; pslope_t *splatslope = NULL;
INT32 i; INT32 i;
renderflags_t renderflags = spr->renderflags; renderflags_t renderflags = spr->renderflags;
if (renderflags & RF_SHADOWEFFECTS)
scale *= spr->shadowscale;
if (spr->rotateflags & SRF_3D || renderflags & RF_NOSPLATBILLBOARD) if (spr->rotateflags & SRF_3D || renderflags & RF_NOSPLATBILLBOARD)
angle = spr->mobj->angle; angle = spr->mobj->angle;
@ -5326,7 +5321,7 @@ static void HWR_ProjectSprite(mobj_t *thing)
} }
groundz = R_GetShadowZ(thing, NULL); groundz = R_GetShadowZ(thing, NULL);
floordiff = abs(((thing->eflags & MFE_VERTICALFLIP) ? caster->height : 0) + casterinterp.z - groundz); floordiff = abs(((thing->eflags & MFE_VERTICALFLIP) ? casterinterp.height : 0) + casterinterp.z - groundz);
shadowheight = FIXED_TO_FLOAT(floordiff); shadowheight = FIXED_TO_FLOAT(floordiff);
shadowscale = FIXED_TO_FLOAT(FixedMul(FRACUNIT - floordiff/640, casterinterp.scale)); shadowscale = FIXED_TO_FLOAT(FixedMul(FRACUNIT - floordiff/640, casterinterp.scale));
@ -5378,7 +5373,7 @@ static void HWR_ProjectSprite(mobj_t *thing)
if (vflip) if (vflip)
{ {
gz = FIXED_TO_FLOAT(interp.z + thing->height) - (FIXED_TO_FLOAT(spr_topoffset) * this_yscale); gz = FIXED_TO_FLOAT(interp.z + interp.height) - (FIXED_TO_FLOAT(spr_topoffset) * this_yscale);
gzt = gz + (FIXED_TO_FLOAT(spr_height) * this_yscale); gzt = gz + (FIXED_TO_FLOAT(spr_height) * this_yscale);
} }
else else
@ -5684,7 +5679,6 @@ static void HWR_ProjectBoundingBox(mobj_t *thing)
gl_vissprite_t *vis; gl_vissprite_t *vis;
float tr_x, tr_y; float tr_x, tr_y;
float tz; float tz;
float rad;
if (!thing) if (!thing)
return; return;
@ -5719,15 +5713,13 @@ static void HWR_ProjectBoundingBox(mobj_t *thing)
tr_x += gl_viewx; tr_x += gl_viewx;
tr_y += gl_viewy; tr_y += gl_viewy;
rad = FIXED_TO_FLOAT(thing->radius);
vis = HWR_NewVisSprite(); vis = HWR_NewVisSprite();
vis->x1 = tr_x - rad; vis->x1 = tr_x - FIXED_TO_FLOAT(interp.radius);
vis->x2 = tr_x + rad; vis->x2 = tr_x + FIXED_TO_FLOAT(interp.radius);
vis->z1 = tr_y - rad; vis->z1 = tr_y - FIXED_TO_FLOAT(interp.radius);
vis->z2 = tr_y + rad; vis->z2 = tr_y + FIXED_TO_FLOAT(interp.radius);
vis->gz = FIXED_TO_FLOAT(interp.z); vis->gz = FIXED_TO_FLOAT(interp.z);
vis->gzt = vis->gz + FIXED_TO_FLOAT(thing->height); vis->gzt = vis->gz + FIXED_TO_FLOAT(interp.height);
vis->mobj = thing; vis->mobj = thing;
vis->precip = false; vis->precip = false;

View file

@ -486,7 +486,7 @@ void HWR_InitModels(void)
size_t i; size_t i;
INT32 s; INT32 s;
FILE *f; FILE *f;
char name[24], filename[32]; char name[26], filename[32];
float scale, offset; float scale, offset;
size_t prefixlen; size_t prefixlen;
@ -585,7 +585,7 @@ modelfound:
void HWR_AddPlayerModel(int skin) // For skins that were added after startup void HWR_AddPlayerModel(int skin) // For skins that were added after startup
{ {
FILE *f; FILE *f;
char name[24], filename[32]; char name[26], filename[32];
float scale, offset; float scale, offset;
size_t prefixlen; size_t prefixlen;
@ -644,7 +644,7 @@ void HWR_AddSpriteModel(size_t spritenum) // For sprites that were added after s
// name[24] is used to check for names in the models.dat file that match with sprites or player skins // name[24] is used to check for names in the models.dat file that match with sprites or player skins
// sprite names are always 4 characters long, and names is for player skins can be up to 19 characters long // sprite names are always 4 characters long, and names is for player skins can be up to 19 characters long
// PLAYERMODELPREFIX is 6 characters long // PLAYERMODELPREFIX is 6 characters long
char name[24], filename[32]; char name[26], filename[32];
float scale, offset; float scale, offset;
if (nomd2s) if (nomd2s)
@ -1585,7 +1585,7 @@ boolean HWR_DrawModel(gl_vissprite_t *spr)
p.y = FIXED_TO_FLOAT(interp.y)+md2->offset; p.y = FIXED_TO_FLOAT(interp.y)+md2->offset;
if (flip) if (flip)
p.z = FIXED_TO_FLOAT(interp.z + spr->mobj->height); p.z = FIXED_TO_FLOAT(interp.z + interp.height);
else else
p.z = FIXED_TO_FLOAT(interp.z); p.z = FIXED_TO_FLOAT(interp.z);
@ -1621,8 +1621,8 @@ boolean HWR_DrawModel(gl_vissprite_t *spr)
p.roll = true; p.roll = true;
// rotation pivot // rotation pivot
p.centerx = FIXED_TO_FLOAT(spr->mobj->radius / 2); p.centerx = FIXED_TO_FLOAT(interp.radius / 2);
p.centery = FIXED_TO_FLOAT(spr->mobj->height / 2); p.centery = FIXED_TO_FLOAT(interp.height / 2);
// rotation axes relative to camera // rotation axes relative to camera
p.rollx = FIXED_TO_FLOAT(FINECOSINE(FixedAngle(camAngleDiff) >> ANGLETOFINESHIFT)); p.rollx = FIXED_TO_FLOAT(FINECOSINE(FixedAngle(camAngleDiff) >> ANGLETOFINESHIFT));

View file

@ -672,6 +672,9 @@ void GeneratePolygonNormals(model_t *model, int ztag)
for (k = 0; k < mesh->numTriangles; k++) for (k = 0; k < mesh->numTriangles; k++)
{ {
/// TODO: normalize vectors
(void)vertices;
(void)polyNormals;
// Vector::Normal(vertices, polyNormals); // Vector::Normal(vertices, polyNormals);
vertices += 3 * 3; vertices += 3 * 3;
polyNormals++; polyNormals++;

View file

@ -2013,7 +2013,7 @@ void HU_Drawer(void)
V_DrawCenteredString(BASEVIDWIDTH/2, 180, V_YELLOWMAP | V_ALLOWLOWERCASE, resynch_text); V_DrawCenteredString(BASEVIDWIDTH/2, 180, V_YELLOWMAP | V_ALLOWLOWERCASE, resynch_text);
} }
if (modeattacking && pausedelay > 0 && !pausebreakkey) if (modeattacking && pausedelay > 0 && !(pausebreakkey || cv_instantretry.value))
{ {
INT32 strength = ((pausedelay - 1 - NEWTICRATE/2)*10)/(NEWTICRATE/3); INT32 strength = ((pausedelay - 1 - NEWTICRATE/2)*10)/(NEWTICRATE/3);
INT32 y = hudinfo[HUD_LIVES].y - 13; INT32 y = hudinfo[HUD_LIVES].y - 13;

View file

@ -7194,7 +7194,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
sfx_cgot, // deathsound sfx_cgot, // deathsound
EMERALD1, // speed EMERALD1, // speed
16*FRACUNIT, // radius 16*FRACUNIT, // radius
32*FRACUNIT, // height 24*FRACUNIT, // height
0, // display offset 0, // display offset
16, // mass 16, // mass
0, // damage 0, // damage
@ -7220,7 +7220,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
sfx_cgot, // deathsound sfx_cgot, // deathsound
EMERALD2, // speed EMERALD2, // speed
16*FRACUNIT, // radius 16*FRACUNIT, // radius
32*FRACUNIT, // height 24*FRACUNIT, // height
0, // display offset 0, // display offset
16, // mass 16, // mass
0, // damage 0, // damage
@ -7246,7 +7246,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
sfx_cgot, // deathsound sfx_cgot, // deathsound
EMERALD3, // speed EMERALD3, // speed
16*FRACUNIT, // radius 16*FRACUNIT, // radius
32*FRACUNIT, // height 24*FRACUNIT, // height
0, // display offset 0, // display offset
16, // mass 16, // mass
0, // damage 0, // damage
@ -7272,7 +7272,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
sfx_cgot, // deathsound sfx_cgot, // deathsound
EMERALD4, // speed EMERALD4, // speed
16*FRACUNIT, // radius 16*FRACUNIT, // radius
32*FRACUNIT, // height 24*FRACUNIT, // height
0, // display offset 0, // display offset
16, // mass 16, // mass
0, // damage 0, // damage
@ -7298,7 +7298,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
sfx_cgot, // deathsound sfx_cgot, // deathsound
EMERALD5, // speed EMERALD5, // speed
16*FRACUNIT, // radius 16*FRACUNIT, // radius
32*FRACUNIT, // height 24*FRACUNIT, // height
0, // display offset 0, // display offset
16, // mass 16, // mass
0, // damage 0, // damage
@ -7324,7 +7324,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
sfx_cgot, // deathsound sfx_cgot, // deathsound
EMERALD6, // speed EMERALD6, // speed
16*FRACUNIT, // radius 16*FRACUNIT, // radius
32*FRACUNIT, // height 24*FRACUNIT, // height
0, // display offset 0, // display offset
16, // mass 16, // mass
0, // damage 0, // damage
@ -7350,7 +7350,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
sfx_cgot, // deathsound sfx_cgot, // deathsound
EMERALD7, // speed EMERALD7, // speed
16*FRACUNIT, // radius 16*FRACUNIT, // radius
32*FRACUNIT, // height 24*FRACUNIT, // height
0, // display offset 0, // display offset
16, // mass 16, // mass
0, // damage 0, // damage
@ -18344,7 +18344,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
S_NULL, // xdeathstate S_NULL, // xdeathstate
sfx_itemup, // deathsound sfx_itemup, // deathsound
60*FRACUNIT, // speed 60*FRACUNIT, // speed
24*FRACUNIT, // radius 16*FRACUNIT, // radius
24*FRACUNIT, // height 24*FRACUNIT, // height
0, // display offset 0, // display offset
pw_bouncering, // mass pw_bouncering, // mass
@ -18371,7 +18371,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
S_NULL, // xdeathstate S_NULL, // xdeathstate
sfx_itemup, // deathsound sfx_itemup, // deathsound
60*FRACUNIT, // speed 60*FRACUNIT, // speed
24*FRACUNIT, // radius 16*FRACUNIT, // radius
24*FRACUNIT, // height 24*FRACUNIT, // height
0, // display offset 0, // display offset
pw_railring, // mass pw_railring, // mass
@ -18425,7 +18425,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
S_NULL, // xdeathstate S_NULL, // xdeathstate
sfx_itemup, // deathsound sfx_itemup, // deathsound
60*FRACUNIT, // speed 60*FRACUNIT, // speed
24*FRACUNIT, // radius 16*FRACUNIT, // radius
24*FRACUNIT, // height 24*FRACUNIT, // height
0, // display offset 0, // display offset
pw_automaticring, // mass pw_automaticring, // mass
@ -18452,7 +18452,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
S_NULL, // xdeathstate S_NULL, // xdeathstate
sfx_itemup, // deathsound sfx_itemup, // deathsound
60*FRACUNIT, // speed 60*FRACUNIT, // speed
24*FRACUNIT, // radius 16*FRACUNIT, // radius
24*FRACUNIT, // height 24*FRACUNIT, // height
0, // display offset 0, // display offset
pw_explosionring, // mass pw_explosionring, // mass
@ -18479,7 +18479,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
S_NULL, // xdeathstate S_NULL, // xdeathstate
sfx_itemup, // deathsound sfx_itemup, // deathsound
60*FRACUNIT, // speed 60*FRACUNIT, // speed
24*FRACUNIT, // radius 16*FRACUNIT, // radius
24*FRACUNIT, // height 24*FRACUNIT, // height
0, // display offset 0, // display offset
pw_scatterring, // mass pw_scatterring, // mass
@ -18506,7 +18506,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
S_NULL, // xdeathstate S_NULL, // xdeathstate
sfx_itemup, // deathsound sfx_itemup, // deathsound
60*FRACUNIT, // speed 60*FRACUNIT, // speed
24*FRACUNIT, // radius 16*FRACUNIT, // radius
24*FRACUNIT, // height 24*FRACUNIT, // height
0, // display offset 0, // display offset
pw_grenadering, // mass pw_grenadering, // mass
@ -18535,7 +18535,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
sfx_ncitem, // deathsound sfx_ncitem, // deathsound
60*FRACUNIT, // speed 60*FRACUNIT, // speed
24*FRACUNIT, // radius 24*FRACUNIT, // radius
24*FRACUNIT, // height 40*FRACUNIT, // height
0, // display offset 0, // display offset
pw_bouncering, // mass pw_bouncering, // mass
2*TICRATE, // damage 2*TICRATE, // damage
@ -18562,7 +18562,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
sfx_ncitem, // deathsound sfx_ncitem, // deathsound
60*FRACUNIT, // speed 60*FRACUNIT, // speed
24*FRACUNIT, // radius 24*FRACUNIT, // radius
24*FRACUNIT, // height 40*FRACUNIT, // height
0, // display offset 0, // display offset
pw_railring, // mass pw_railring, // mass
2*TICRATE, // damage 2*TICRATE, // damage
@ -18589,7 +18589,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
sfx_ncitem, // deathsound sfx_ncitem, // deathsound
60*FRACUNIT, // speed 60*FRACUNIT, // speed
24*FRACUNIT, // radius 24*FRACUNIT, // radius
24*FRACUNIT, // height 40*FRACUNIT, // height
0, // display offset 0, // display offset
pw_automaticring, // mass pw_automaticring, // mass
2*TICRATE, // damage 2*TICRATE, // damage
@ -18616,7 +18616,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
sfx_ncitem, // deathsound sfx_ncitem, // deathsound
60*FRACUNIT, // speed 60*FRACUNIT, // speed
24*FRACUNIT, // radius 24*FRACUNIT, // radius
24*FRACUNIT, // height 40*FRACUNIT, // height
0, // display offset 0, // display offset
pw_explosionring, // mass pw_explosionring, // mass
2*TICRATE, // damage 2*TICRATE, // damage
@ -18643,7 +18643,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
sfx_ncitem, // deathsound sfx_ncitem, // deathsound
60*FRACUNIT, // speed 60*FRACUNIT, // speed
24*FRACUNIT, // radius 24*FRACUNIT, // radius
24*FRACUNIT, // height 40*FRACUNIT, // height
0, // display offset 0, // display offset
pw_scatterring, // mass pw_scatterring, // mass
2*TICRATE, // damage 2*TICRATE, // damage
@ -18670,7 +18670,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
sfx_ncitem, // deathsound sfx_ncitem, // deathsound
60*FRACUNIT, // speed 60*FRACUNIT, // speed
24*FRACUNIT, // radius 24*FRACUNIT, // radius
24*FRACUNIT, // height 40*FRACUNIT, // height
0, // display offset 0, // display offset
pw_grenadering, // mass pw_grenadering, // mass
2*TICRATE, // damage 2*TICRATE, // damage
@ -21584,10 +21584,9 @@ skincolor_t skincolors[MAXSKINCOLORS] = {
{"Black", {0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1b, 0x1b, 0x1c, 0x1d, 0x1d, 0x1e, 0x1e, 0x1f, 0x1f}, SKINCOLOR_WHITE, 7, V_GRAYMAP, true}, // SKINCOLOR_BLACK {"Black", {0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1b, 0x1b, 0x1c, 0x1d, 0x1d, 0x1e, 0x1e, 0x1f, 0x1f}, SKINCOLOR_WHITE, 7, V_GRAYMAP, true}, // SKINCOLOR_BLACK
// Desaturated // Desaturated
{"Aether", {0x00, 0x00, 0x01, 0x02, 0x02, 0x03, 0x91, 0x91, 0x91, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xaf}, SKINCOLOR_GREY, 15, 0, true}, // SKINCOLOR_AETHER {"Aether", {0x00, 0x00, 0x01, 0x01, 0x90, 0x90, 0x91, 0x91, 0x92, 0xaa, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xae}, SKINCOLOR_GREY, 15, 0, true}, // SKINCOLOR_AETHER
{"Slate", {0x00, 0x02, 0x04, 0x06, 0x08, 0x0a, 0xaa, 0xaa, 0xaa, 0xab, 0xac, 0xac, 0xad, 0xad, 0xae, 0xaf}, SKINCOLOR_SILVER, 12, 0, true}, // SKINCOLOR_SLATE {"Slate", {0x00, 0x02, 0x04, 0x06, 0x08, 0x0a, 0xaa, 0xaa, 0xaa, 0xab, 0xac, 0xac, 0xad, 0xad, 0xae, 0xaf}, SKINCOLOR_SILVER, 12, 0, true}, // SKINCOLOR_SLATE
{"Meteorite", { 0, 4, 8, 9, 11, 12, 14, 15, 171, 172, 173, 174, 175, 27, 29, 31}, SKINCOLOR_TOPAZ, 15, V_GRAYMAP, true}, // SKINCOLOR_METEORITE {"Moonstone", { 0, 4, 8, 9, 11, 12, 14, 15, 171, 172, 173, 174, 175, 27, 29, 31}, SKINCOLOR_TOPAZ, 15, V_GRAYMAP, true}, // SKINCOLOR_MOONSTONE
{"Mercury", { 0, 3, 4, 7, 11, 12, 14, 15, 171, 172, 173, 155, 157, 159, 253, 254}, SKINCOLOR_ECRU, 15, V_AZUREMAP, true}, // SKINCOLOR_MERCURY
{"Bluebell", {0x90, 0x91, 0x92, 0x93, 0x94, 0x94, 0x95, 0xac, 0xac, 0xad, 0xad, 0xa8, 0xa8, 0xa9, 0xfd, 0xfe}, SKINCOLOR_COPPER, 4, V_BLUEMAP, true}, // SKINCOLOR_BLUEBELL {"Bluebell", {0x90, 0x91, 0x92, 0x93, 0x94, 0x94, 0x95, 0xac, 0xac, 0xad, 0xad, 0xa8, 0xa8, 0xa9, 0xfd, 0xfe}, SKINCOLOR_COPPER, 4, V_BLUEMAP, true}, // SKINCOLOR_BLUEBELL
{"Pink", {0xd0, 0xd0, 0xd1, 0xd1, 0xd2, 0xd2, 0xd3, 0xd3, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0x2b, 0x2c, 0x2e}, SKINCOLOR_AZURE, 9, V_REDMAP, true}, // SKINCOLOR_PINK {"Pink", {0xd0, 0xd0, 0xd1, 0xd1, 0xd2, 0xd2, 0xd3, 0xd3, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0x2b, 0x2c, 0x2e}, SKINCOLOR_AZURE, 9, V_REDMAP, true}, // SKINCOLOR_PINK
{"Rosewood", { 209, 210, 211, 212, 213, 214, 228, 230, 232, 234, 235, 237, 26, 27, 28, 29}, SKINCOLOR_SEPIA, 5, V_BROWNMAP, true}, // SKINCOLOR_ROSEWOOD {"Rosewood", { 209, 210, 211, 212, 213, 214, 228, 230, 232, 234, 235, 237, 26, 27, 28, 29}, SKINCOLOR_SEPIA, 5, V_BROWNMAP, true}, // SKINCOLOR_ROSEWOOD
@ -21597,37 +21596,37 @@ skincolor_t skincolors[MAXSKINCOLORS] = {
{"Boulder", {0xde, 0xe0, 0xe1, 0xe4, 0xe7, 0xe9, 0xeb, 0xec, 0xed, 0xed, 0xed, 0x19, 0x19, 0x1b, 0x1d, 0x1e}, SKINCOLOR_KETCHUP, 0, V_BROWNMAP, true}, // SKINCOLOR_BOULDER {"Boulder", {0xde, 0xe0, 0xe1, 0xe4, 0xe7, 0xe9, 0xeb, 0xec, 0xed, 0xed, 0xed, 0x19, 0x19, 0x1b, 0x1d, 0x1e}, SKINCOLOR_KETCHUP, 0, V_BROWNMAP, true}, // SKINCOLOR_BOULDER
{"Bronze", { 82, 84, 50, 51, 223, 228, 230, 232, 234, 236, 237, 238, 239, 239, 30, 31}, SKINCOLOR_VOLCANIC, 9, V_BROWNMAP, true}, // SKINCOLOR_BRONZE {"Bronze", { 82, 84, 50, 51, 223, 228, 230, 232, 234, 236, 237, 238, 239, 239, 30, 31}, SKINCOLOR_VOLCANIC, 9, V_BROWNMAP, true}, // SKINCOLOR_BRONZE
{"Sepia", { 88, 84, 85, 86, 224, 226, 228, 230, 232, 235, 236, 237, 238, 239, 28, 28}, SKINCOLOR_ROSEWOOD, 5, V_BROWNMAP, true}, // SKINCOLOR_SEPIA {"Sepia", { 88, 84, 85, 86, 224, 226, 228, 230, 232, 235, 236, 237, 238, 239, 28, 28}, SKINCOLOR_ROSEWOOD, 5, V_BROWNMAP, true}, // SKINCOLOR_SEPIA
{"Ecru", { 80, 83, 84, 85, 86, 242, 243, 245, 230, 232, 234, 236, 238, 239, 47, 47}, SKINCOLOR_MERCURY, 15, V_BROWNMAP, true}, // SKINCOLOR_ECRU {"Ecru", { 80, 83, 84, 85, 86, 242, 243, 245, 230, 232, 234, 236, 238, 239, 47, 47}, SKINCOLOR_ARCTIC, 12, V_BROWNMAP, true}, // SKINCOLOR_ECRU
{"Tan", {0x51, 0x51, 0x54, 0x54, 0x55, 0x55, 0x56, 0x56, 0x56, 0x57, 0xf5, 0xf5, 0xf9, 0xf9, 0xed, 0xed}, SKINCOLOR_BROWN, 12, V_BROWNMAP, true}, // SKINCOLOR_TAN {"Tan", {0x51, 0x51, 0x54, 0x54, 0x55, 0x55, 0x56, 0x56, 0x56, 0x57, 0xf5, 0xf5, 0xf9, 0xf9, 0xed, 0xed}, SKINCOLOR_BROWN, 12, V_BROWNMAP, true}, // SKINCOLOR_TAN
{"Beige", {0x54, 0x55, 0x56, 0x56, 0xf2, 0xf3, 0xf3, 0xf4, 0xf5, 0xf6, 0xf8, 0xf9, 0xfa, 0xfb, 0xed, 0xed}, SKINCOLOR_MOSS, 5, V_BROWNMAP, true}, // SKINCOLOR_BEIGE {"Beige", {0x54, 0x55, 0x56, 0x56, 0xf2, 0xf3, 0xf3, 0xf4, 0xf5, 0xf6, 0xf8, 0xf9, 0xfa, 0xfb, 0xed, 0xed}, SKINCOLOR_MOSS, 5, V_BROWNMAP, true}, // SKINCOLOR_BEIGE
{"Rosebush", { 208, 216, 209, 85, 90, 91, 91, 92, 191, 93, 94, 107, 109, 110, 111, 111}, SKINCOLOR_EGGPLANT, 5, V_GREENMAP, true}, // SKINCOLOR_ROSEBUSH {"Rosebush", { 208, 216, 209, 85, 90, 91, 91, 92, 191, 93, 94, 107, 109, 110, 111, 111}, SKINCOLOR_EGGPLANT, 5, V_GREENMAP, true}, // SKINCOLOR_ROSEBUSH
{"Moss", {0x58, 0x58, 0x59, 0x59, 0x5a, 0x5a, 0x5b, 0x5b, 0x5b, 0x5c, 0x5d, 0x5d, 0x5e, 0x5e, 0x5f, 0x5f}, SKINCOLOR_BEIGE, 13, V_GREENMAP, true}, // SKINCOLOR_MOSS {"Moss", {0x58, 0x58, 0x59, 0x59, 0x5a, 0x5a, 0x5b, 0x5b, 0x5b, 0x5c, 0x5d, 0x5d, 0x5e, 0x5e, 0x5f, 0x5f}, SKINCOLOR_BEIGE, 13, V_GREENMAP, true}, // SKINCOLOR_MOSS
{"Azure", {0x90, 0x90, 0x91, 0x91, 0xaa, 0xaa, 0xab, 0xab, 0xab, 0xac, 0xad, 0xad, 0xae, 0xae, 0xaf, 0xaf}, SKINCOLOR_PINK, 5, V_AZUREMAP, true}, // SKINCOLOR_AZURE {"Azure", {0x90, 0x90, 0x91, 0x91, 0xaa, 0xaa, 0xab, 0xab, 0xab, 0xac, 0xad, 0xad, 0xae, 0xae, 0xaf, 0xaf}, SKINCOLOR_PINK, 5, V_AZUREMAP, true}, // SKINCOLOR_AZURE
{"Eggplant", { 4, 8, 11, 11, 16, 195, 195, 195, 196, 186, 187, 187, 254, 254, 30, 31}, SKINCOLOR_ROSEBUSH, 5, V_PURPLEMAP, true}, // SKINCOLOR_EGGPLANT {"Eggplant", { 4, 8, 11, 11, 16, 195, 195, 195, 196, 186, 187, 187, 254, 254, 30, 31}, SKINCOLOR_ROSEBUSH, 5, V_PURPLEMAP, true}, // SKINCOLOR_EGGPLANT
{"Lavender", {0xc0, 0xc0, 0xc1, 0xc1, 0xc2, 0xc2, 0xc3, 0xc3, 0xc3, 0xc4, 0xc5, 0xc5, 0xc6, 0xc6, 0xc7, 0xc7}, SKINCOLOR_HEADLIGHT, 8, V_PURPLEMAP, true}, // SKINCOLOR_LAVENDER {"Lavender", {0xc0, 0xc0, 0xc1, 0xc1, 0xc2, 0xc2, 0xc3, 0xc3, 0xc3, 0xc4, 0xc5, 0xc5, 0xc6, 0xc6, 0xc7, 0xc7}, SKINCOLOR_GOLD, 4, V_PURPLEMAP, true}, // SKINCOLOR_LAVENDER
// Viv's vivid colours (toast 21/07/17) // Viv's vivid colours (toast 21/07/17)
// Tweaks & additions (Lach, sphere, Alice, MotorRoach 26/10/22) // Tweaks & additions (Lach, Chrispy, sphere, Alice, MotorRoach & Saneko 26/10/22)
{"Ruby", {0xb0, 0xb0, 0xc9, 0xca, 0xcc, 0x26, 0x27, 0x28, 0x29, 0x2a, 0xb9, 0xb9, 0xba, 0xba, 0xbb, 0xfd}, SKINCOLOR_EMERALD, 10, V_REDMAP, true}, // SKINCOLOR_RUBY {"Ruby", {0xb0, 0xb0, 0xc9, 0xca, 0xcc, 0x26, 0x27, 0x28, 0x29, 0x2a, 0xb9, 0xb9, 0xba, 0xba, 0xbb, 0xfd}, SKINCOLOR_EMERALD, 10, V_REDMAP, true}, // SKINCOLOR_RUBY
{"Cherry", { 202, 203, 204, 205, 206, 40, 41, 42, 43, 44, 186, 187, 28, 29, 30, 31}, SKINCOLOR_MIDNIGHT, 10, V_REDMAP, true}, // SKINCOLOR_CHERRY {"Cherry", { 202, 203, 204, 205, 206, 40, 41, 42, 43, 44, 186, 187, 28, 29, 30, 31}, SKINCOLOR_MIDNIGHT, 10, V_REDMAP, true}, // SKINCOLOR_CHERRY
{"Salmon", {0xd0, 0xd0, 0xd1, 0xd2, 0x20, 0x21, 0x24, 0x25, 0x26, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e}, SKINCOLOR_FOREST, 6, V_REDMAP, true}, // SKINCOLOR_SALMON {"Salmon", {0xd0, 0xd0, 0xd1, 0xd2, 0x20, 0x21, 0x24, 0x25, 0x26, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e}, SKINCOLOR_FOREST, 6, V_REDMAP, true}, // SKINCOLOR_SALMON
{"Pepper", { 210, 32, 33, 34, 35, 35, 36, 37, 38, 39, 41, 43, 45, 45, 46, 47}, SKINCOLOR_GREEN, 10, V_REDMAP, true}, // SKINCOLOR_PEPPER {"Pepper", { 210, 32, 33, 34, 35, 35, 36, 37, 38, 39, 41, 43, 45, 45, 46, 47}, SKINCOLOR_MASTER, 8, V_REDMAP, true}, // SKINCOLOR_PEPPER
{"Red", {0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x47, 0x2e, 0x2f}, SKINCOLOR_MASTER, 8, V_REDMAP, true}, // SKINCOLOR_RED {"Red", {0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x47, 0x2e, 0x2f}, SKINCOLOR_GREEN, 10, V_REDMAP, true}, // SKINCOLOR_RED
{"Crimson", {0x27, 0x27, 0x28, 0x28, 0x29, 0x2a, 0x2b, 0x2b, 0x2c, 0x2d, 0x2e, 0x2e, 0x2e, 0x2f, 0x2f, 0x1f}, SKINCOLOR_ICY, 10, V_REDMAP, true}, // SKINCOLOR_CRIMSON {"Crimson", {0x27, 0x27, 0x28, 0x28, 0x29, 0x2a, 0x2b, 0x2b, 0x2c, 0x2d, 0x2e, 0x2e, 0x2e, 0x2f, 0x2f, 0x1f}, SKINCOLOR_ICY, 10, V_REDMAP, true}, // SKINCOLOR_CRIMSON
{"Flame", {0x31, 0x32, 0x33, 0x36, 0x22, 0x22, 0x25, 0x25, 0x25, 0xcd, 0xcf, 0xcf, 0xc5, 0xc5, 0xc7, 0xc7}, SKINCOLOR_PURPLE, 8, V_REDMAP, true}, // SKINCOLOR_FLAME {"Flame", {0x31, 0x32, 0x33, 0x36, 0x22, 0x22, 0x25, 0x25, 0x25, 0xcd, 0xcf, 0xcf, 0xc5, 0xc5, 0xc7, 0xc7}, SKINCOLOR_PURPLE, 8, V_REDMAP, true}, // SKINCOLOR_FLAME
{"Garnet", { 0, 83, 50, 53, 34, 35, 37, 38, 39, 40, 42, 44, 45, 46, 47, 47}, SKINCOLOR_AQUAMARINE, 6, V_REDMAP, true}, // SKINCOLOR_GARNET {"Garnet", { 0, 83, 50, 53, 34, 35, 37, 38, 39, 40, 42, 44, 45, 46, 47, 47}, SKINCOLOR_AQUAMARINE, 6, V_REDMAP, true}, // SKINCOLOR_GARNET
{"Ketchup", {0x48, 0x49, 0x40, 0x33, 0x34, 0x36, 0x22, 0x24, 0x26, 0x28, 0x2a, 0x2b, 0x2c, 0x47, 0x2e, 0x2f}, SKINCOLOR_BOULDER, 8, V_REDMAP, true}, // SKINCOLOR_KETCHUP {"Ketchup", {0x48, 0x49, 0x40, 0x33, 0x34, 0x36, 0x22, 0x24, 0x26, 0x28, 0x2a, 0x2b, 0x2c, 0x47, 0x2e, 0x2f}, SKINCOLOR_BOULDER, 8, V_REDMAP, true}, // SKINCOLOR_KETCHUP
{"Peachy", {0xd0, 0x30, 0x31, 0x31, 0x32, 0x32, 0xdc, 0xdc, 0xdc, 0xd3, 0xd4, 0xd4, 0xcc, 0xcd, 0xce, 0xcf}, SKINCOLOR_TEAL, 7, V_ROSYMAP, true}, // SKINCOLOR_PEACHY {"Peachy", {0xd0, 0x30, 0x31, 0x31, 0x32, 0x32, 0xdc, 0xdc, 0xdc, 0xd3, 0xd4, 0xd4, 0xcc, 0xcd, 0xce, 0xcf}, SKINCOLOR_TEAL, 7, V_ROSYMAP, true}, // SKINCOLOR_PEACHY
{"Quail", {0xd8, 0xd9, 0xdb, 0xdc, 0xde, 0xdf, 0xd5, 0xd5, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0x1d, 0x1f}, SKINCOLOR_WAVE, 5, V_BROWNMAP, true}, // SKINCOLOR_QUAIL {"Quail", {0xd8, 0xd9, 0xdb, 0xdc, 0xde, 0xdf, 0xd5, 0xd5, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0x1d, 0x1f}, SKINCOLOR_WAVE, 5, V_BROWNMAP, true}, // SKINCOLOR_QUAIL
{"Foundation", { 80, 81, 82, 84, 219, 221, 221, 212, 213, 214, 215, 195, 196, 186, 187, 30}, SKINCOLOR_DREAM, 6, V_ORANGEMAP, true}, // SKINCOLOR_FOUNDATION {"Foundation", { 80, 81, 82, 84, 219, 221, 221, 212, 213, 214, 215, 197, 186, 187, 187, 30}, SKINCOLOR_DREAM, 6, V_ORANGEMAP, true}, // SKINCOLOR_FOUNDATION
{"Sunset", {0x51, 0x52, 0x40, 0x40, 0x34, 0x36, 0xd5, 0xd5, 0xd6, 0xd7, 0xcf, 0xcf, 0xc6, 0xc6, 0xc7, 0xfe}, SKINCOLOR_SAPPHIRE, 5, V_ORANGEMAP, true}, // SKINCOLOR_SUNSET {"Sunset", {0x51, 0x52, 0x40, 0x40, 0x34, 0x36, 0xd5, 0xd5, 0xd6, 0xd7, 0xcf, 0xcf, 0xc6, 0xc6, 0xc7, 0xfe}, SKINCOLOR_SAPPHIRE, 5, V_ORANGEMAP, true}, // SKINCOLOR_SUNSET
{"Copper", {0x58, 0x54, 0x40, 0x34, 0x35, 0x38, 0x3a, 0x3c, 0x3d, 0x2a, 0x2b, 0x2c, 0x2c, 0xba, 0xba, 0xbb}, SKINCOLOR_BLUEBELL, 5, V_ORANGEMAP, true}, // SKINCOLOR_COPPER {"Copper", {0x58, 0x54, 0x40, 0x34, 0x35, 0x38, 0x3a, 0x3c, 0x3d, 0x2a, 0x2b, 0x2c, 0x2c, 0xba, 0xba, 0xbb}, SKINCOLOR_BLUEBELL, 5, V_ORANGEMAP, true}, // SKINCOLOR_COPPER
{"Apricot", {0x00, 0xd8, 0xd9, 0xda, 0xdb, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e}, SKINCOLOR_CYAN, 4, V_ORANGEMAP, true}, // SKINCOLOR_APRICOT {"Apricot", {0x00, 0xd8, 0xd9, 0xda, 0xdb, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e}, SKINCOLOR_CYAN, 4, V_ORANGEMAP, true}, // SKINCOLOR_APRICOT
{"Orange", { 49, 50, 51, 52, 53, 54, 55, 57, 58, 59, 60, 42, 44, 45, 46, 46}, SKINCOLOR_BLUE, 4, V_ORANGEMAP, true}, // SKINCOLOR_ORANGE {"Orange", { 49, 50, 51, 52, 53, 54, 55, 57, 58, 59, 60, 42, 44, 45, 46, 46}, SKINCOLOR_BLUE, 4, V_ORANGEMAP, true}, // SKINCOLOR_ORANGE
{"Pumpkin", { 51, 52, 53, 54, 56, 58, 59, 59, 61, 61, 63, 45, 46, 47, 47, 31}, SKINCOLOR_ARCTIC, 12, V_ORANGEMAP, true}, // SKINCOLOR_PUMPKIN
{"Rust", {0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3c, 0x3d, 0x3d, 0x3d, 0x3f, 0x2c, 0x2d, 0x47, 0x2e, 0x2f, 0x2f}, SKINCOLOR_YOGURT, 8, V_ORANGEMAP, true}, // SKINCOLOR_RUST {"Rust", {0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3c, 0x3d, 0x3d, 0x3d, 0x3f, 0x2c, 0x2d, 0x47, 0x2e, 0x2f, 0x2f}, SKINCOLOR_YOGURT, 8, V_ORANGEMAP, true}, // SKINCOLOR_RUST
{"Gold", {0x51, 0x51, 0x54, 0x54, 0x41, 0x42, 0x43, 0x43, 0x44, 0x45, 0x46, 0x3f, 0x2d, 0x2e, 0x2f, 0x2f}, SKINCOLOR_MAUVE, 8, V_YELLOWMAP, true}, // SKINCOLOR_GOLD {"Tangerine", { 81, 83, 64, 64, 51, 52, 53, 54, 56, 58, 60, 61, 63, 45, 46, 47}, SKINCOLOR_OCEAN, 12, V_ORANGEMAP, true}, // SKINCOLOR_TANGERINE
{"Topaz", { 0, 81, 83, 73, 74, 74, 65, 52, 53, 54, 56, 58, 60, 42, 43, 45}, SKINCOLOR_METEORITE, 10, V_YELLOWMAP, true}, // SKINCOLOR_TOPAZ {"Topaz", { 0, 81, 83, 73, 74, 74, 65, 52, 53, 54, 56, 58, 60, 42, 43, 45}, SKINCOLOR_MOONSTONE, 10, V_YELLOWMAP, true}, // SKINCOLOR_TOPAZ
{"Gold", {0x51, 0x51, 0x54, 0x54, 0x41, 0x42, 0x43, 0x43, 0x44, 0x45, 0x46, 0x3f, 0x2d, 0x2e, 0x2f, 0x2f}, SKINCOLOR_LAVENDER, 10, V_YELLOWMAP, true}, // SKINCOLOR_GOLD
{"Sandy", {0x53, 0x40, 0x41, 0x42, 0x43, 0xe6, 0xe9, 0xe9, 0xea, 0xec, 0xec, 0xc6, 0xc6, 0xc7, 0xc7, 0xfe}, SKINCOLOR_SKY, 8, V_YELLOWMAP, true}, // SKINCOLOR_SANDY {"Sandy", {0x53, 0x40, 0x41, 0x42, 0x43, 0xe6, 0xe9, 0xe9, 0xea, 0xec, 0xec, 0xc6, 0xc6, 0xc7, 0xc7, 0xfe}, SKINCOLOR_SKY, 8, V_YELLOWMAP, true}, // SKINCOLOR_SANDY
{"Goldenrod", { 0, 80, 81, 81, 83, 73, 73, 64, 65, 66, 67, 68, 69, 62, 44, 45}, SKINCOLOR_MAJESTY, 8, V_YELLOWMAP, true}, // SKINCOLOR_GOLDENROD {"Goldenrod", { 0, 80, 81, 81, 83, 73, 73, 64, 65, 66, 67, 68, 69, 62, 44, 45}, SKINCOLOR_MAJESTY, 8, V_YELLOWMAP, true}, // SKINCOLOR_GOLDENROD
{"Yellow", {0x52, 0x53, 0x49, 0x49, 0x4a, 0x4a, 0x4b, 0x4b, 0x4b, 0x4c, 0x4d, 0x4d, 0x4e, 0x4e, 0x4f, 0xed}, SKINCOLOR_CORNFLOWER, 8, V_YELLOWMAP, true}, // SKINCOLOR_YELLOW {"Yellow", {0x52, 0x53, 0x49, 0x49, 0x4a, 0x4a, 0x4b, 0x4b, 0x4b, 0x4c, 0x4d, 0x4d, 0x4e, 0x4e, 0x4f, 0xed}, SKINCOLOR_CORNFLOWER, 8, V_YELLOWMAP, true}, // SKINCOLOR_YELLOW
@ -21637,20 +21636,21 @@ skincolor_t skincolors[MAXSKINCOLORS] = {
{"Lime", {0x50, 0x51, 0x52, 0x53, 0x48, 0xbc, 0xbd, 0xbe, 0xbe, 0xbf, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f}, SKINCOLOR_MAGENTA, 9, V_PERIDOTMAP, true}, // SKINCOLOR_LIME {"Lime", {0x50, 0x51, 0x52, 0x53, 0x48, 0xbc, 0xbd, 0xbe, 0xbe, 0xbf, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f}, SKINCOLOR_MAGENTA, 9, V_PERIDOTMAP, true}, // SKINCOLOR_LIME
{"Peridot", {0x58, 0x58, 0xbc, 0xbc, 0xbd, 0xbd, 0xbe, 0xbe, 0xbe, 0xbf, 0x5e, 0x5e, 0x5f, 0x5f, 0x77, 0x77}, SKINCOLOR_COBALT, 2, V_PERIDOTMAP, true}, // SKINCOLOR_PERIDOT {"Peridot", {0x58, 0x58, 0xbc, 0xbc, 0xbd, 0xbd, 0xbe, 0xbe, 0xbe, 0xbf, 0x5e, 0x5e, 0x5f, 0x5f, 0x77, 0x77}, SKINCOLOR_COBALT, 2, V_PERIDOTMAP, true}, // SKINCOLOR_PERIDOT
{"Apple", {0x49, 0x49, 0xbc, 0xbd, 0xbe, 0xbe, 0xbe, 0x67, 0x69, 0x6a, 0x6b, 0x6b, 0x6c, 0x6d, 0x6d, 0x6d}, SKINCOLOR_RASPBERRY, 13, V_PERIDOTMAP, true}, // SKINCOLOR_APPLE {"Apple", {0x49, 0x49, 0xbc, 0xbd, 0xbe, 0xbe, 0xbe, 0x67, 0x69, 0x6a, 0x6b, 0x6b, 0x6c, 0x6d, 0x6d, 0x6d}, SKINCOLOR_RASPBERRY, 13, V_PERIDOTMAP, true}, // SKINCOLOR_APPLE
{"Headlight", { 0, 80, 81, 82, 73, 84, 64, 65, 91, 91, 124, 125, 126, 137, 138, 139}, SKINCOLOR_MAUVE, 8, V_YELLOWMAP, true}, // SKINCOLOR_HEADLIGHT
{"Chartreuse", { 80, 82, 72, 73, 188, 188, 113, 114, 114, 125, 126, 137, 138, 139, 253, 254}, SKINCOLOR_NOBLE, 9, V_PERIDOTMAP, true}, // SKINCOLOR_CHARTREUSE {"Chartreuse", { 80, 82, 72, 73, 188, 188, 113, 114, 114, 125, 126, 137, 138, 139, 253, 254}, SKINCOLOR_NOBLE, 9, V_PERIDOTMAP, true}, // SKINCOLOR_CHARTREUSE
{"Green", {0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f}, SKINCOLOR_PEPPER, 8, V_GREENMAP, true}, // SKINCOLOR_GREEN {"Green", {0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f}, SKINCOLOR_RED, 6, V_GREENMAP, true}, // SKINCOLOR_GREEN
{"Forest", {0x65, 0x66, 0x67, 0x68, 0x69, 0x69, 0x6a, 0x6b, 0x6b, 0x6c, 0x6d, 0x6d, 0x6e, 0x6e, 0x6e, 0x6f}, SKINCOLOR_SALMON, 9, V_GREENMAP, true}, // SKINCOLOR_FOREST {"Forest", {0x65, 0x66, 0x67, 0x68, 0x69, 0x69, 0x6a, 0x6b, 0x6b, 0x6c, 0x6d, 0x6d, 0x6e, 0x6e, 0x6e, 0x6f}, SKINCOLOR_SALMON, 9, V_GREENMAP, true}, // SKINCOLOR_FOREST
{"Shamrock", {0x70, 0x70, 0x71, 0x71, 0x72, 0x72, 0x73, 0x73, 0x73, 0x74, 0x75, 0x75, 0x76, 0x76, 0x77, 0x77}, SKINCOLOR_CRYSTAL, 10, V_GREENMAP, true}, // SKINCOLOR_SHAMROCK {"Shamrock", {0x70, 0x70, 0x71, 0x71, 0x72, 0x72, 0x73, 0x73, 0x73, 0x74, 0x75, 0x75, 0x76, 0x76, 0x77, 0x77}, SKINCOLOR_SIBERITE, 10, V_GREENMAP, true}, // SKINCOLOR_SHAMROCK
{"Jade", { 128, 120, 121, 122, 122, 113, 114, 114, 115, 116, 117, 118, 119, 110, 111, 30}, SKINCOLOR_ROSY, 7, V_GREENMAP, true}, // SKINCOLOR_JADE {"Jade", { 128, 120, 121, 122, 122, 113, 114, 114, 115, 116, 117, 118, 119, 110, 111, 30}, SKINCOLOR_TAFFY, 10, V_GREENMAP, true}, // SKINCOLOR_JADE
{"Headlight", { 0, 80, 81, 82, 73, 84, 64, 65, 91, 91, 124, 125, 126, 137, 138, 139}, SKINCOLOR_LAVENDER, 10, V_YELLOWMAP, true}, // SKINCOLOR_HEADLIGHT
{"Mint", {0x00, 0x00, 0x58, 0x58, 0x59, 0x62, 0x62, 0x62, 0x64, 0x67, 0x7e, 0x7e, 0x8f, 0x8f, 0x8a, 0x8a}, SKINCOLOR_VIOLET, 5, V_GREENMAP, true}, // SKINCOLOR_MINT {"Mint", {0x00, 0x00, 0x58, 0x58, 0x59, 0x62, 0x62, 0x62, 0x64, 0x67, 0x7e, 0x7e, 0x8f, 0x8f, 0x8a, 0x8a}, SKINCOLOR_VIOLET, 5, V_GREENMAP, true}, // SKINCOLOR_MINT
{"Master", { 0, 80, 88, 96, 112, 113, 99, 100, 124, 125, 126, 117, 107, 118, 119, 111}, SKINCOLOR_RED, 6, V_GREENMAP, true}, // SKINCOLOR_MASTER {"Master", { 0, 80, 88, 96, 112, 113, 99, 100, 124, 125, 126, 117, 107, 118, 119, 111}, SKINCOLOR_PEPPER, 8, V_GREENMAP, true}, // SKINCOLOR_MASTER
{"Emerald", { 80, 96, 112, 113, 114, 114, 125, 125, 126, 126, 137, 137, 138, 138, 139, 139}, SKINCOLOR_RUBY, 9, V_GREENMAP, true}, // SKINCOLOR_EMERALD {"Emerald", { 80, 96, 112, 113, 114, 114, 125, 125, 126, 126, 137, 137, 138, 138, 139, 139}, SKINCOLOR_RUBY, 9, V_GREENMAP, true}, // SKINCOLOR_EMERALD
{"Bottle", { 0, 1, 3, 4, 5, 140, 141, 141, 124, 125, 126, 127, 118, 119, 111, 111}, SKINCOLOR_LATTE, 14, V_AQUAMAP, true}, // SKINCOLOR_BOTTLE
{"Seafoam", {0x01, 0x58, 0x59, 0x5a, 0x7c, 0x7d, 0x7d, 0x7e, 0x7e, 0x8f, 0x8f, 0x8a, 0x8a, 0x8b, 0xfd, 0xfd}, SKINCOLOR_PLUM, 6, V_AQUAMAP, true}, // SKINCOLOR_SEAFOAM {"Seafoam", {0x01, 0x58, 0x59, 0x5a, 0x7c, 0x7d, 0x7d, 0x7e, 0x7e, 0x8f, 0x8f, 0x8a, 0x8a, 0x8b, 0xfd, 0xfd}, SKINCOLOR_PLUM, 6, V_AQUAMAP, true}, // SKINCOLOR_SEAFOAM
{"Island", { 96, 97, 113, 113, 114, 124, 142, 136, 136, 150, 151, 153, 168, 168, 169, 169}, SKINCOLOR_GALAXY, 7, V_AQUAMAP, true}, // SKINCOLOR_ISLAND {"Island", { 96, 97, 113, 113, 114, 124, 142, 136, 136, 150, 151, 153, 168, 168, 169, 169}, SKINCOLOR_GALAXY, 7, V_AQUAMAP, true}, // SKINCOLOR_ISLAND
{"Aqua", {0x78, 0x79, 0x7a, 0x7a, 0x7b, 0x7b, 0x7c, 0x7c, 0x7c, 0x7d, 0x7e, 0x7e, 0x7f, 0x7f, 0x76, 0x77}, SKINCOLOR_TAFFY, 10, V_AQUAMAP, true}, // SKINCOLOR_AQUA {"Bottle", { 0, 1, 3, 4, 5, 140, 141, 141, 124, 125, 126, 127, 118, 119, 111, 111}, SKINCOLOR_LATTE, 14, V_AQUAMAP, true}, // SKINCOLOR_BOTTLE
{"Aqua", {0x78, 0x79, 0x7a, 0x7a, 0x7b, 0x7b, 0x7c, 0x7c, 0x7c, 0x7d, 0x7e, 0x7e, 0x7f, 0x7f, 0x76, 0x77}, SKINCOLOR_ROSY, 7, V_AQUAMAP, true}, // SKINCOLOR_AQUA
{"Teal", {0x78, 0x78, 0x8c, 0x8c, 0x8d, 0x8d, 0x8d, 0x8e, 0x8e, 0x8f, 0x8f, 0x8f, 0x8a, 0x8a, 0x8a, 0x8a}, SKINCOLOR_PEACHY, 7, V_SKYMAP, true}, // SKINCOLOR_TEAL {"Teal", {0x78, 0x78, 0x8c, 0x8c, 0x8d, 0x8d, 0x8d, 0x8e, 0x8e, 0x8f, 0x8f, 0x8f, 0x8a, 0x8a, 0x8a, 0x8a}, SKINCOLOR_PEACHY, 7, V_SKYMAP, true}, // SKINCOLOR_TEAL
{"Ocean", { 120, 121, 122, 122, 123, 141, 142, 142, 136, 137, 138, 138, 139, 139, 253, 253}, SKINCOLOR_TANGERINE, 4, V_AQUAMAP, true}, // SKINCOLOR_OCEAN
{"Wave", {0x00, 0x78, 0x78, 0x79, 0x8d, 0x87, 0x88, 0x89, 0x89, 0xae, 0xa8, 0xa8, 0xa9, 0xa9, 0xfd, 0xfd}, SKINCOLOR_QUAIL, 5, V_SKYMAP, true}, // SKINCOLOR_WAVE {"Wave", {0x00, 0x78, 0x78, 0x79, 0x8d, 0x87, 0x88, 0x89, 0x89, 0xae, 0xa8, 0xa8, 0xa9, 0xa9, 0xfd, 0xfd}, SKINCOLOR_QUAIL, 5, V_SKYMAP, true}, // SKINCOLOR_WAVE
{"Cyan", {0x80, 0x81, 0xff, 0xff, 0x83, 0x83, 0x8d, 0x8d, 0x8d, 0x8e, 0x7e, 0x7f, 0x76, 0x76, 0x77, 0x6e}, SKINCOLOR_APRICOT, 6, V_SKYMAP, true}, // SKINCOLOR_CYAN {"Cyan", {0x80, 0x81, 0xff, 0xff, 0x83, 0x83, 0x8d, 0x8d, 0x8d, 0x8e, 0x7e, 0x7f, 0x76, 0x76, 0x77, 0x6e}, SKINCOLOR_APRICOT, 6, V_SKYMAP, true}, // SKINCOLOR_CYAN
{"Turquoise", { 0, 120, 121, 122, 123, 141, 141, 135, 136, 136, 150, 153, 155, 157, 159, 253}, SKINCOLOR_SANGRIA, 12, V_SKYMAP, true}, // SKINCOLOR_TURQUOISE {"Turquoise", { 0, 120, 121, 122, 123, 141, 141, 135, 136, 136, 150, 153, 155, 157, 159, 253}, SKINCOLOR_SANGRIA, 12, V_SKYMAP, true}, // SKINCOLOR_TURQUOISE
@ -21661,12 +21661,12 @@ skincolor_t skincolors[MAXSKINCOLORS] = {
{"Dream", { 80, 208, 200, 200, 146, 146, 133, 134, 135, 136, 137, 138, 139, 139, 254, 254}, SKINCOLOR_FOUNDATION, 9, V_SKYMAP, true}, // SKINCOLOR_DREAM {"Dream", { 80, 208, 200, 200, 146, 146, 133, 134, 135, 136, 137, 138, 139, 139, 254, 254}, SKINCOLOR_FOUNDATION, 9, V_SKYMAP, true}, // SKINCOLOR_DREAM
{"Icy", {0x00, 0x00, 0x00, 0x00, 0x80, 0x81, 0x83, 0x83, 0x86, 0x87, 0x95, 0x95, 0xad, 0xad, 0xae, 0xaf}, SKINCOLOR_CRIMSON, 0, V_SKYMAP, true}, // SKINCOLOR_ICY {"Icy", {0x00, 0x00, 0x00, 0x00, 0x80, 0x81, 0x83, 0x83, 0x86, 0x87, 0x95, 0x95, 0xad, 0xad, 0xae, 0xaf}, SKINCOLOR_CRIMSON, 0, V_SKYMAP, true}, // SKINCOLOR_ICY
{"Daybreak", { 80, 81, 82, 72, 64, 9, 11, 171, 149, 150, 151, 153, 156, 157, 159, 253}, SKINCOLOR_EVENTIDE, 12, V_BLUEMAP, true}, // SKINCOLOR_DAYBREAK {"Daybreak", { 80, 81, 82, 72, 64, 9, 11, 171, 149, 150, 151, 153, 156, 157, 159, 253}, SKINCOLOR_EVENTIDE, 12, V_BLUEMAP, true}, // SKINCOLOR_DAYBREAK
{"Sapphire", {0x80, 0x82, 0x86, 0x87, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xfd, 0xfe}, SKINCOLOR_SUNSET, 5, V_SKYMAP, true}, // SKINCOLOR_SAPPHIRE {"Sapphire", {0x80, 0x82, 0x86, 0x87, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xfd, 0xfe}, SKINCOLOR_SUNSET, 5, V_BLUEMAP, true}, // SKINCOLOR_SAPPHIRE
{"Arctic", { 0, 1, 3, 4, 146, 146, 147, 148, 148, 149, 150, 153, 156, 159, 253, 254}, SKINCOLOR_PUMPKIN, 6, V_BLUEMAP, true}, // SKINCOLOR_ARCTIC {"Arctic", { 0, 1, 3, 4, 145, 146, 147, 148, 148, 149, 150, 153, 156, 159, 253, 254}, SKINCOLOR_ECRU, 15, V_BLUEMAP, true}, // SKINCOLOR_ARCTIC
{"Cornflower", {0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x9a, 0x9c, 0x9d, 0x9d, 0x9e, 0x9e, 0x9e}, SKINCOLOR_YELLOW, 4, V_BLUEMAP, true}, // SKINCOLOR_CORNFLOWER {"Cornflower", {0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x9a, 0x9c, 0x9d, 0x9d, 0x9e, 0x9e, 0x9e}, SKINCOLOR_YELLOW, 4, V_BLUEMAP, true}, // SKINCOLOR_CORNFLOWER
{"Blue", {0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xfd, 0xfe}, SKINCOLOR_ORANGE, 5, V_BLUEMAP, true}, // SKINCOLOR_BLUE {"Blue", {0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xfd, 0xfe}, SKINCOLOR_ORANGE, 5, V_BLUEMAP, true}, // SKINCOLOR_BLUE
{"Cobalt", { 145, 147, 149, 150, 151, 153, 154, 155, 156, 157, 158, 159, 253, 253, 254, 254}, SKINCOLOR_PERIDOT, 5, V_BLUEMAP, true}, // SKINCOLOR_COBALT {"Cobalt", { 145, 147, 149, 150, 151, 153, 154, 155, 156, 157, 158, 159, 253, 253, 254, 254}, SKINCOLOR_PERIDOT, 5, V_BLUEMAP, true}, // SKINCOLOR_COBALT
{"Midnight", { 171, 171, 172, 173, 173, 174, 155, 156, 157, 159, 253, 253, 254, 254, 31, 31}, SKINCOLOR_CHERRY, 10, V_GRAYMAP, true}, // SKINCOLOR_MIDNIGHT {"Midnight", { 171, 171, 172, 173, 173, 174, 175, 157, 158, 159, 253, 253, 254, 254, 31, 31}, SKINCOLOR_CHERRY, 10, V_GRAYMAP, true}, // SKINCOLOR_MIDNIGHT
{"Galaxy", { 160, 161, 162, 163, 164, 165, 166, 166, 154, 155, 156, 157, 159, 253, 254, 31}, SKINCOLOR_ISLAND, 7, V_PURPLEMAP, true}, // SKINCOLOR_GALAXY {"Galaxy", { 160, 161, 162, 163, 164, 165, 166, 166, 154, 155, 156, 157, 159, 253, 254, 31}, SKINCOLOR_ISLAND, 7, V_PURPLEMAP, true}, // SKINCOLOR_GALAXY
{"Vapor", {0x80, 0x81, 0x83, 0x86, 0x94, 0x94, 0xa3, 0xa3, 0xa4, 0xa6, 0xa6, 0xa6, 0xa8, 0xa8, 0xa9, 0xa9}, SKINCOLOR_LILAC, 4, V_SKYMAP, true}, // SKINCOLOR_VAPOR {"Vapor", {0x80, 0x81, 0x83, 0x86, 0x94, 0x94, 0xa3, 0xa3, 0xa4, 0xa6, 0xa6, 0xa6, 0xa8, 0xa8, 0xa9, 0xa9}, SKINCOLOR_LILAC, 4, V_SKYMAP, true}, // SKINCOLOR_VAPOR
{"Dusk", {0x92, 0x93, 0x94, 0x94, 0xac, 0xad, 0xad, 0xad, 0xae, 0xae, 0xaf, 0xaf, 0xa9, 0xa9, 0xfd, 0xfd}, SKINCOLOR_OLIVE, 0, V_BLUEMAP, true}, // SKINCOLOR_DUSK {"Dusk", {0x92, 0x93, 0x94, 0x94, 0xac, 0xad, 0xad, 0xad, 0xae, 0xae, 0xaf, 0xaf, 0xa9, 0xa9, 0xfd, 0xfd}, SKINCOLOR_OLIVE, 0, V_BLUEMAP, true}, // SKINCOLOR_DUSK
@ -21676,21 +21676,21 @@ skincolor_t skincolors[MAXSKINCOLORS] = {
{"Noble", { 144, 146, 147, 148, 149, 164, 164, 165, 166, 185, 186, 186, 187, 187, 28, 29}, SKINCOLOR_CHARTREUSE, 12, V_PURPLEMAP, true}, // SKINCOLOR_NOBLE {"Noble", { 144, 146, 147, 148, 149, 164, 164, 165, 166, 185, 186, 186, 187, 187, 28, 29}, SKINCOLOR_CHARTREUSE, 12, V_PURPLEMAP, true}, // SKINCOLOR_NOBLE
{"Fuchsia", { 200, 201, 203, 204, 204, 183, 184, 184, 165, 166, 167, 168, 169, 159, 253, 254}, SKINCOLOR_LEMON, 10, V_PURPLEMAP, true}, // SKINCOLOR_FUCHSIA {"Fuchsia", { 200, 201, 203, 204, 204, 183, 184, 184, 165, 166, 167, 168, 169, 159, 253, 254}, SKINCOLOR_LEMON, 10, V_PURPLEMAP, true}, // SKINCOLOR_FUCHSIA
{"Bubblegum", { 0, 208, 208, 176, 177, 178, 179, 180, 181, 182, 164, 166, 167, 168, 169, 253}, SKINCOLOR_PASTEL, 8, V_MAGENTAMAP, true}, // SKINCOLOR_BUBBLEGUM {"Bubblegum", { 0, 208, 208, 176, 177, 178, 179, 180, 181, 182, 164, 166, 167, 168, 169, 253}, SKINCOLOR_PASTEL, 8, V_MAGENTAMAP, true}, // SKINCOLOR_BUBBLEGUM
{"Crystal", { 252, 177, 179, 180, 181, 181, 182, 182, 183, 164, 166, 167, 167, 168, 169, 159}, SKINCOLOR_EMERALD, 8, V_MAGENTAMAP, true}, // SKINCOLOR_CRYSTAL {"Siberite", { 252, 177, 179, 180, 181, 181, 182, 182, 183, 164, 166, 167, 167, 168, 169, 159}, SKINCOLOR_EMERALD, 8, V_MAGENTAMAP, true}, // SKINCOLOR_SIBERITE
{"Magenta", {0xb3, 0xb3, 0xb4, 0xb5, 0xb6, 0xb6, 0xb7, 0xb7, 0xb7, 0xb8, 0xb9, 0xb9, 0xba, 0xba, 0xbb, 0xbb}, SKINCOLOR_LIME, 6, V_MAGENTAMAP, true}, // SKINCOLOR_MAGENTA {"Magenta", {0xb3, 0xb3, 0xb4, 0xb5, 0xb6, 0xb6, 0xb7, 0xb7, 0xb7, 0xb8, 0xb9, 0xb9, 0xba, 0xba, 0xbb, 0xbb}, SKINCOLOR_LIME, 6, V_MAGENTAMAP, true}, // SKINCOLOR_MAGENTA
{"Neon", {0xb3, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xb9, 0xba, 0xba, 0xbb, 0xbb, 0xc7, 0xc7, 0x1d, 0x1d, 0x1e}, SKINCOLOR_CERULEAN, 2, V_MAGENTAMAP, true}, // SKINCOLOR_NEON {"Neon", {0xb3, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xb9, 0xba, 0xba, 0xbb, 0xbb, 0xc7, 0xc7, 0x1d, 0x1d, 0x1e}, SKINCOLOR_CERULEAN, 2, V_MAGENTAMAP, true}, // SKINCOLOR_NEON
{"Violet", {0xd0, 0xd1, 0xd2, 0xca, 0xcc, 0xb8, 0xb9, 0xb9, 0xba, 0xa8, 0xa8, 0xa9, 0xa9, 0xfd, 0xfe, 0xfe}, SKINCOLOR_MINT, 6, V_MAGENTAMAP, true}, // SKINCOLOR_VIOLET {"Violet", {0xd0, 0xd1, 0xd2, 0xca, 0xcc, 0xb8, 0xb9, 0xb9, 0xba, 0xa8, 0xa8, 0xa9, 0xa9, 0xfd, 0xfe, 0xfe}, SKINCOLOR_MINT, 6, V_MAGENTAMAP, true}, // SKINCOLOR_VIOLET
{"Royal", { 208, 209, 192, 192, 192, 193, 193, 194, 194, 172, 173, 174, 175, 175, 139, 139}, SKINCOLOR_FANCY, 9, V_PURPLEMAP, true}, // SKINCOLOR_ROYAL {"Royal", { 208, 209, 192, 192, 192, 193, 193, 194, 194, 172, 173, 174, 175, 175, 139, 139}, SKINCOLOR_FANCY, 9, V_PURPLEMAP, true}, // SKINCOLOR_ROYAL
{"Lilac", {0x00, 0xd0, 0xd1, 0xd2, 0xd3, 0xc1, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc5, 0xc6, 0xc6, 0xfe, 0x1f}, SKINCOLOR_VAPOR, 4, V_ROSYMAP, true}, // SKINCOLOR_LILAC {"Lilac", {0x00, 0xd0, 0xd1, 0xd2, 0xd3, 0xc1, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc5, 0xc6, 0xc6, 0xfe, 0x1f}, SKINCOLOR_VAPOR, 4, V_ROSYMAP, true}, // SKINCOLOR_LILAC
{"Mauve", { 176, 177, 178, 192, 193, 194, 195, 195, 196, 185, 185, 186, 186, 187, 187, 253}, SKINCOLOR_GOLD, 4, V_PURPLEMAP, true}, // SKINCOLOR_MAUVE {"Mauve", { 176, 177, 178, 192, 193, 194, 195, 195, 196, 185, 185, 186, 186, 187, 187, 253}, SKINCOLOR_HEADLIGHT, 8, V_PURPLEMAP, true}, // SKINCOLOR_MAUVE
{"Eventide", { 51, 52, 53, 33, 34, 204, 183, 183, 184, 184, 166, 167, 168, 169, 253, 254}, SKINCOLOR_DAYBREAK, 13, V_MAGENTAMAP, true}, // SKINCOLOR_EVENTIDE {"Eventide", { 51, 52, 53, 33, 34, 204, 183, 183, 184, 184, 166, 167, 168, 169, 253, 254}, SKINCOLOR_DAYBREAK, 13, V_MAGENTAMAP, true}, // SKINCOLOR_EVENTIDE
{"Plum", {0xc8, 0xd3, 0xd5, 0xd6, 0xd7, 0xce, 0xcf, 0xb9, 0xb9, 0xba, 0xba, 0xa9, 0xa9, 0xa9, 0xfd, 0xfe}, SKINCOLOR_MINT, 7, V_ROSYMAP, true}, // SKINCOLOR_PLUM {"Plum", {0xc8, 0xd3, 0xd5, 0xd6, 0xd7, 0xce, 0xcf, 0xb9, 0xb9, 0xba, 0xba, 0xa9, 0xa9, 0xa9, 0xfd, 0xfe}, SKINCOLOR_MINT, 7, V_ROSYMAP, true}, // SKINCOLOR_PLUM
{"Raspberry", {0xc8, 0xc9, 0xca, 0xcb, 0xcb, 0xcc, 0xcd, 0xcd, 0xce, 0xb9, 0xb9, 0xba, 0xba, 0xbb, 0xfe, 0xfe}, SKINCOLOR_APPLE, 13, V_ROSYMAP, true}, // SKINCOLOR_RASPBERRY {"Raspberry", {0xc8, 0xc9, 0xca, 0xcb, 0xcb, 0xcc, 0xcd, 0xcd, 0xce, 0xb9, 0xb9, 0xba, 0xba, 0xbb, 0xfe, 0xfe}, SKINCOLOR_APPLE, 13, V_ROSYMAP, true}, // SKINCOLOR_RASPBERRY
{"Taffy", { 1, 176, 176, 177, 178, 179, 202, 203, 204, 204, 205, 206, 207, 44, 45, 46}, SKINCOLOR_AQUA, 1, V_ROSYMAP, true}, // SKINCOLOR_TAFFY {"Taffy", { 1, 176, 176, 177, 178, 179, 202, 203, 204, 204, 205, 206, 207, 44, 45, 46}, SKINCOLOR_JADE, 8, V_ROSYMAP, true}, // SKINCOLOR_TAFFY
{"Rosy", {0xfc, 0xc8, 0xc8, 0xc9, 0xc9, 0xca, 0xca, 0xcb, 0xcb, 0xcc, 0xcc, 0xcd, 0xcd, 0xce, 0xce, 0xcf}, SKINCOLOR_JADE, 8, V_ROSYMAP, true}, // SKINCOLOR_ROSY {"Rosy", {0xfc, 0xc8, 0xc8, 0xc9, 0xc9, 0xca, 0xca, 0xcb, 0xcb, 0xcc, 0xcc, 0xcd, 0xcd, 0xce, 0xce, 0xcf}, SKINCOLOR_AQUA, 1, V_ROSYMAP, true}, // SKINCOLOR_ROSY
{"Fancy", { 0, 208, 49, 210, 210, 202, 202, 203, 204, 204, 205, 206, 207, 207, 186, 186}, SKINCOLOR_ROYAL, 9, V_ROSYMAP, true}, // SKINCOLOR_FANCY {"Fancy", { 0, 208, 49, 210, 210, 202, 202, 203, 204, 204, 205, 206, 207, 207, 186, 186}, SKINCOLOR_ROYAL, 9, V_ROSYMAP, true}, // SKINCOLOR_FANCY
{"Sangria", { 210, 32, 33, 34, 34, 215, 215, 207, 207, 185, 186, 186, 186, 169, 169, 253}, SKINCOLOR_TURQUOISE, 12, V_ROSYMAP, true}, // SKINCOLOR_SANGRIA {"Sangria", { 210, 32, 33, 34, 34, 215, 215, 207, 207, 185, 186, 186, 186, 169, 169, 253}, SKINCOLOR_TURQUOISE, 12, V_ROSYMAP, true}, // SKINCOLOR_SANGRIA
{"Volcanic", { 35, 38, 41, 42, 44, 46, 46, 169, 169, 159, 253, 254, 30, 30, 31, 31}, SKINCOLOR_BRONZE, 9, V_REDMAP, true}, // SKINCOLOR_VOLCANIC {"Volcanic", { 54, 36, 42, 44, 45, 46, 46, 47, 28, 253, 253, 254, 254, 30, 31, 31}, SKINCOLOR_BRONZE, 9, V_REDMAP, true}, // SKINCOLOR_VOLCANIC
// super // super
{"Super Silver 1", {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x03}, SKINCOLOR_BLACK, 15, 0, false}, // SKINCOLOR_SUPERSILVER1 {"Super Silver 1", {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x03}, SKINCOLOR_BLACK, 15, 0, false}, // SKINCOLOR_SUPERSILVER1

View file

@ -3657,7 +3657,7 @@ static int lib_gAddGametype(lua_State *L)
// Partly lifted from Got_AddPlayer // Partly lifted from Got_AddPlayer
static int lib_gAddPlayer(lua_State *L) static int lib_gAddPlayer(lua_State *L)
{ {
INT16 i, newplayernum, botcount = 1; INT16 i, newplayernum;
player_t *newplayer; player_t *newplayer;
SINT8 skinnum = 0, bot; SINT8 skinnum = 0, bot;
@ -3665,10 +3665,8 @@ static int lib_gAddPlayer(lua_State *L)
{ {
if (!playeringame[i]) if (!playeringame[i])
break; break;
if (players[i].bot)
botcount++; // How many of us are there already?
} }
if (i >= MAXPLAYERS) if (i >= MAXPLAYERS)
{ {
lua_pushnil(L); lua_pushnil(L);
@ -3939,7 +3937,7 @@ static int lib_gDoReborn(lua_State *L)
} }
// Another Lua function that doesn't actually exist! // Another Lua function that doesn't actually exist!
// Sets nextmapoverride & skipstats without instantly ending the level, for instances where other sources should be exiting the level, like normal signposts. // Sets nextmapoverride, skipstats and nextgametype without instantly ending the level, for instances where other sources should be exiting the level, like normal signposts.
static int lib_gSetCustomExitVars(lua_State *L) static int lib_gSetCustomExitVars(lua_State *L)
{ {
int n = lua_gettop(L); // Num arguments int n = lua_gettop(L); // Num arguments
@ -3952,6 +3950,7 @@ static int lib_gSetCustomExitVars(lua_State *L)
// G_SetCustomExitVars(int) [nextmap override only] // G_SetCustomExitVars(int) [nextmap override only]
// G_SetCustomExitVars(nil, int) [skipstats only] // G_SetCustomExitVars(nil, int) [skipstats only]
// G_SetCustomExitVars(int, int) [both of the above] // G_SetCustomExitVars(int, int) [both of the above]
// G_SetCustomExitVars(int, int, int) [nextmapoverride, skipstats and nextgametype]
nextmapoverride = 0; nextmapoverride = 0;
skipstats = 0; skipstats = 0;
@ -3961,7 +3960,7 @@ static int lib_gSetCustomExitVars(lua_State *L)
{ {
nextmapoverride = (INT16)luaL_optinteger(L, 1, 0); nextmapoverride = (INT16)luaL_optinteger(L, 1, 0);
skipstats = (INT16)luaL_optinteger(L, 2, 0); skipstats = (INT16)luaL_optinteger(L, 2, 0);
nextgametype = (INT16)luaL_optinteger(L, 3, 0); nextgametype = (INT16)luaL_optinteger(L, 3, -1);
} }
return 0; return 0;

View file

@ -615,7 +615,7 @@ static int cvar_get(lua_State *L)
break; break;
default: default:
if (devparm) if (devparm)
return luaL_error(L, LUA_QL("consvar_t") " has no field named " LUA_QS, field); return luaL_error(L, LUA_QL("consvar_t") " has no field named " LUA_QS ".", lua_tostring(L, 2));
else else
return 0; return 0;
} }

View file

@ -282,7 +282,6 @@ static int patch_get(lua_State *L)
patch_t *patch = *((patch_t **)luaL_checkudata(L, 1, META_PATCH)); patch_t *patch = *((patch_t **)luaL_checkudata(L, 1, META_PATCH));
enum patch field = Lua_optoption(L, 2, -1, patch_fields_ref); enum patch field = Lua_optoption(L, 2, -1, patch_fields_ref);
// patches are invalidated when switching renderers
if (!patch) { if (!patch) {
if (field == patch_valid) { if (field == patch_valid) {
lua_pushboolean(L, 0); lua_pushboolean(L, 0);
@ -436,7 +435,7 @@ static int camera_set(lua_State *L)
cam->momz = luaL_checkfixed(L, 3); cam->momz = luaL_checkfixed(L, 3);
break; break;
default: default:
return luaL_error(L, LUA_QL("camera_t") " has no field named " LUA_QS, camera_opt[field]); return luaL_error(L, LUA_QL("camera_t") " has no field named " LUA_QS ".", lua_tostring(L, 2));
} }
return 0; return 0;
} }
@ -1487,7 +1486,6 @@ void LUA_SetHudHook(int hook, huddrawlist_h list)
break; break;
case HUD_HOOK(intermission): case HUD_HOOK(intermission):
lua_pushboolean(gL, intertype == int_spec && lua_pushboolean(gL, stagefailed);
stagefailed);
} }
} }

View file

@ -805,8 +805,9 @@ static int sector_set(lua_State *L)
case sector_fslope: // f_slope case sector_fslope: // f_slope
case sector_cslope: // c_slope case sector_cslope: // c_slope
case sector_friction: // friction case sector_friction: // friction
default:
return luaL_error(L, "sector_t field " LUA_QS " cannot be set.", sector_opt[field]); return luaL_error(L, "sector_t field " LUA_QS " cannot be set.", sector_opt[field]);
default:
return luaL_error(L, "sector_t has no field named " LUA_QS ".", lua_tostring(L, 2));
case sector_floorheight: { // floorheight case sector_floorheight: { // floorheight
boolean flag; boolean flag;
mobj_t *ptmthing = tmthing; mobj_t *ptmthing = tmthing;
@ -1287,8 +1288,9 @@ static int side_set(lua_State *L)
case side_sector: case side_sector:
case side_special: case side_special:
case side_text: case side_text:
default:
return luaL_error(L, "side_t field " LUA_QS " cannot be set.", side_opt[field]); return luaL_error(L, "side_t field " LUA_QS " cannot be set.", side_opt[field]);
default:
return luaL_error(L, "side_t has no field named " LUA_QS ".", lua_tostring(L, 2));
case side_textureoffset: case side_textureoffset:
side->textureoffset = luaL_checkfixed(L, 3); side->textureoffset = luaL_checkfixed(L, 3);
break; break;
@ -2299,8 +2301,9 @@ static int ffloor_set(lua_State *L)
case ffloor_target: // target case ffloor_target: // target
case ffloor_next: // next case ffloor_next: // next
case ffloor_prev: // prev case ffloor_prev: // prev
default:
return luaL_error(L, "ffloor_t field " LUA_QS " cannot be set.", ffloor_opt[field]); return luaL_error(L, "ffloor_t field " LUA_QS " cannot be set.", ffloor_opt[field]);
default:
return luaL_error(L, "ffloor_t has no field named " LUA_QS ".", lua_tostring(L, 2));
case ffloor_topheight: { // topheight case ffloor_topheight: { // topheight
boolean flag; boolean flag;
fixed_t lastpos = *ffloor->topheight; fixed_t lastpos = *ffloor->topheight;
@ -2434,8 +2437,9 @@ static int slope_set(lua_State *L)
case slope_d: // d case slope_d: // d
case slope_flags: // flags case slope_flags: // flags
case slope_normal: // normal case slope_normal: // normal
default:
return luaL_error(L, "pslope_t field " LUA_QS " cannot be set.", slope_opt[field]); return luaL_error(L, "pslope_t field " LUA_QS " cannot be set.", slope_opt[field]);
default:
return luaL_error(L, "pslope_t has no field named " LUA_QS ".", lua_tostring(L, 2));
case slope_o: { // o case slope_o: { // o
luaL_checktype(L, 3, LUA_TTABLE); luaL_checktype(L, 3, LUA_TTABLE);

View file

@ -25,6 +25,7 @@ enum skin {
skin_flags, skin_flags,
skin_realname, skin_realname,
skin_hudname, skin_hudname,
skin_supername,
skin_ability, skin_ability,
skin_ability2, skin_ability2,
skin_thokitem, skin_thokitem,
@ -63,6 +64,7 @@ static const char *const skin_opt[] = {
"flags", "flags",
"realname", "realname",
"hudname", "hudname",
"supername",
"ability", "ability",
"ability2", "ability2",
"thokitem", "thokitem",
@ -126,6 +128,9 @@ static int skin_get(lua_State *L)
case skin_hudname: case skin_hudname:
lua_pushstring(L, skin->hudname); lua_pushstring(L, skin->hudname);
break; break;
case skin_supername:
lua_pushstring(L, skin->supername);
break;
case skin_ability: case skin_ability:
lua_pushinteger(L, skin->ability); lua_pushinteger(L, skin->ability);
break; break;

View file

@ -1103,6 +1103,8 @@ static mapthing_t *OP_CreateNewMapThing(player_t *player, UINT16 type, boolean c
mt->options = (mt->z << ZSHIFT) | (UINT16)cv_opflags.value; mt->options = (mt->z << ZSHIFT) | (UINT16)cv_opflags.value;
mt->scale = player->mo->scale; mt->scale = player->mo->scale;
mt->spritexscale = player->mo->spritexscale;
mt->spriteyscale = player->mo->spriteyscale;
memset(mt->args, 0, NUMMAPTHINGARGS*sizeof(*mt->args)); memset(mt->args, 0, NUMMAPTHINGARGS*sizeof(*mt->args));
memset(mt->stringargs, 0x00, NUMMAPTHINGSTRINGARGS*sizeof(*mt->stringargs)); memset(mt->stringargs, 0x00, NUMMAPTHINGSTRINGARGS*sizeof(*mt->stringargs));
mt->pitch = mt->roll = 0; mt->pitch = mt->roll = 0;

View file

@ -467,6 +467,15 @@ UINT8 M_SecretUnlocked(INT32 type, gamedata_t *data)
UINT8 M_MapLocked(INT32 mapnum, gamedata_t *data) UINT8 M_MapLocked(INT32 mapnum, gamedata_t *data)
{ {
if (dedicated)
{
// If you're in a dedicated server, every level is unlocked.
// Yes, technically this means you can view any level by
// running a dedicated server and joining it yourself, but
// that's better than making dedicated server's lives hell.
return false;
}
if (!mapheaderinfo[mapnum-1] || mapheaderinfo[mapnum-1]->unlockrequired < 0) if (!mapheaderinfo[mapnum-1] || mapheaderinfo[mapnum-1]->unlockrequired < 0)
{ {
return false; return false;
@ -480,6 +489,48 @@ UINT8 M_MapLocked(INT32 mapnum, gamedata_t *data)
return false; return false;
} }
UINT8 M_CampaignWarpIsCheat(INT32 gt, INT32 mapnum, gamedata_t *data)
{
if (M_MapLocked(mapnum, data) == true)
{
// Warping to locked maps is definitely always a cheat
return true;
}
if ((gametypes[gt].rules & GTR_CAMPAIGN) == 0)
{
// Not a campaign, do whatever you want.
return false;
}
if (G_IsSpecialStage(mapnum))
{
// Warping to special stages is a cheat
return true;
}
if (mapheaderinfo[mapnum-1]->menuflags & LF2_HIDEINMENU)
{
// You're never allowed to warp to this level.
return true;
}
if (mapheaderinfo[mapnum-1]->menuflags & LF2_NOVISITNEEDED)
{
// You're always allowed to warp to this level.
return false;
}
if (mapnum == spstage_start)
{
// Warping to the first level is never a cheat
return false;
}
// It's only a cheat if you've never been there.
return (!(data->mapvisited[mapnum-1]));
}
INT32 M_CountEmblems(gamedata_t *data) INT32 M_CountEmblems(gamedata_t *data)
{ {
INT32 found = 0, i; INT32 found = 0, i;

View file

@ -252,6 +252,7 @@ void M_SilentUpdateSkinAvailabilites(void);
UINT8 M_AnySecretUnlocked(gamedata_t *data); UINT8 M_AnySecretUnlocked(gamedata_t *data);
UINT8 M_SecretUnlocked(INT32 type, gamedata_t *data); UINT8 M_SecretUnlocked(INT32 type, gamedata_t *data);
UINT8 M_MapLocked(INT32 mapnum, gamedata_t *data); UINT8 M_MapLocked(INT32 mapnum, gamedata_t *data);
UINT8 M_CampaignWarpIsCheat(INT32 gt, INT32 mapnum, gamedata_t *data);
INT32 M_CountEmblems(gamedata_t *data); INT32 M_CountEmblems(gamedata_t *data);
// Emblem shit // Emblem shit

View file

@ -2651,7 +2651,7 @@ static boolean MIT_SetCurBackground(UINT32 menutype, INT32 level, INT32 *retval,
{ {
strncpy(curbgname, defaultname, 9); strncpy(curbgname, defaultname, 9);
curbgxspeed = (gamestate == GS_TIMEATTACK) ? 0 : titlescrollxspeed; curbgxspeed = (gamestate == GS_TIMEATTACK) ? 0 : titlescrollxspeed;
curbgyspeed = (gamestate == GS_TIMEATTACK) ? 0 : titlescrollyspeed; curbgyspeed = (gamestate == GS_TIMEATTACK) ? 18 : titlescrollyspeed;
} }
} }
return false; return false;
@ -2845,8 +2845,8 @@ static void M_HandleMenuPresState(menu_t *newMenu)
curfadevalue = 16; curfadevalue = 16;
curhidepics = hidetitlepics; curhidepics = hidetitlepics;
curbgcolor = -1; curbgcolor = -1;
curbgxspeed = titlescrollxspeed; curbgxspeed = (gamestate == GS_TIMEATTACK) ? 0 : titlescrollxspeed;
curbgyspeed = titlescrollyspeed; curbgyspeed = (gamestate == GS_TIMEATTACK) ? 18 : titlescrollyspeed;
curbghide = (gamestate != GS_TIMEATTACK); // show in time attack, hide in other menus curbghide = (gamestate != GS_TIMEATTACK); // show in time attack, hide in other menus
curttmode = ttmode; curttmode = ttmode;
@ -3198,7 +3198,7 @@ boolean M_Responder(event_t *ev)
|| gamestate == GS_CREDITS || gamestate == GS_EVALUATION || gamestate == GS_GAMEEND) || gamestate == GS_CREDITS || gamestate == GS_EVALUATION || gamestate == GS_GAMEEND)
return false; return false;
if (gamestate == GS_TITLESCREEN && finalecount < TICRATE) if (gamestate == GS_TITLESCREEN && finalecount < (cv_tutorialprompt.value ? TICRATE : 0))
return false; return false;
if (CON_Ready() && gamestate != GS_WAITINGPLAYERS) if (CON_Ready() && gamestate != GS_WAITINGPLAYERS)
@ -12045,6 +12045,136 @@ static INT32 setupm_fakeskin;
static menucolor_t *setupm_fakecolor; static menucolor_t *setupm_fakecolor;
static boolean colorgrid; static boolean colorgrid;
#define COLOR_GRID_ROW_SIZE (16)
static UINT16 M_GetColorGridIndex(UINT16 color)
{
menucolor_t *look;
UINT16 i = 0;
if (!skincolors[color].accessible)
{
return 0;
}
for (look = menucolorhead; ; i++, look = look->next)
{
while (!skincolors[look->color].accessible) // skip inaccessible colors
{
if (look == menucolortail)
{
return 0;
}
look = look->next;
}
if (look->color == color)
{
return i;
}
if (look == menucolortail)
{
return 0;
}
}
}
static INT32 M_GridIndexToX(UINT16 index)
{
return (index % COLOR_GRID_ROW_SIZE);
}
static INT32 M_GridIndexToY(UINT16 index)
{
return (index / COLOR_GRID_ROW_SIZE);
}
static UINT16 M_ColorGridLen(void)
{
menucolor_t *look;
UINT16 i = 0;
for (look = menucolorhead; ; i++)
{
do
{
if (look == menucolortail)
{
return i;
}
look = look->next;
}
while (!skincolors[look->color].accessible); // skip inaccessible colors
}
}
static UINT16 M_GridPosToGridIndex(INT32 x, INT32 y)
{
const UINT16 grid_len = M_ColorGridLen();
const UINT16 grid_height = ((grid_len - 1) / COLOR_GRID_ROW_SIZE) + 1;
const UINT16 last_row_len = COLOR_GRID_ROW_SIZE - ((grid_height * COLOR_GRID_ROW_SIZE) - grid_len);
UINT16 row_len = COLOR_GRID_ROW_SIZE;
UINT16 new_index = 0;
while (y < 0)
{
y += grid_height;
}
y = (y % grid_height);
if (y >= grid_height-1 && last_row_len > 0)
{
row_len = last_row_len;
}
while (x < 0)
{
x += row_len;
}
x = (x % row_len);
new_index = (y * COLOR_GRID_ROW_SIZE) + x;
if (new_index >= grid_len)
{
new_index = grid_len - 1;
}
return new_index;
}
static menucolor_t *M_GridIndexToMenuColor(UINT16 index)
{
menucolor_t *look = menucolorhead;
UINT16 i = 0;
for (look = menucolorhead; ; i++, look = look->next)
{
while (!skincolors[look->color].accessible) // skip inaccessible colors
{
if (look == menucolortail)
{
return menucolorhead;
}
look = look->next;
}
if (i == index)
{
return look;
}
if (look == menucolortail)
{
return menucolorhead;
}
}
}
static void M_DrawSetupMultiPlayerMenu(void) static void M_DrawSetupMultiPlayerMenu(void)
{ {
INT32 x, y, cursory = 0, flags = 0; INT32 x, y, cursory = 0, flags = 0;
@ -12163,32 +12293,54 @@ colordraw:
boolean stoprow = false; boolean stoprow = false;
menucolor_t *mc; // Last accessed color menucolor_t *mc; // Last accessed color
const UINT16 grid_len = M_ColorGridLen();
const UINT16 grid_end_y = M_GridIndexToY(grid_len - 1);
INT32 grid_select = M_GetColorGridIndex(setupm_fakecolor->color);
INT32 grid_select_y = M_GridIndexToY(grid_select);
x = 132; x = 132;
y = 66; y = 66;
pos = min(max(0, 16*((M_GetColorIndex(setupm_fakecolor->color)-1)/16) - 64), 16*(M_GetColorIndex(menucolortail->color)/16-1) - 128);
mc = M_GetColorFromIndex(pos); pos = M_GridPosToGridIndex(0, max(0, min(grid_select_y - 3, grid_end_y - 7)));
mc = M_GridIndexToMenuColor(pos);
// Draw grid // Draw grid
V_DrawFill(x-2, y-2, 132, 132, 159); V_DrawFill(x-2, y-2, 132, 132, 159);
for (j = 0; j < 8; j++) for (j = 0; j < 8; j++)
{ {
for (i = 0; i < 16; i++) for (i = 0; i < COLOR_GRID_ROW_SIZE; i++)
{ {
if (skincolors[mc->color].accessible && !stoprow) if (skincolors[mc->color].accessible)
{ {
M_DrawColorRamp(x + i*w, y + j*16, w, 1, skincolors[mc->color]); M_DrawColorRamp(x + i*w, y + j*16, w, 1, skincolors[mc->color]);
if (mc->color == setupm_fakecolor->color) // store current color position
if (mc == setupm_fakecolor) // store current color position
{ {
cx = x + i*w; cx = x + i*w;
cy = y + j*16; cy = y + j*16;
} }
} }
mc = mc->next;
while (!skincolors[mc->color].accessible && !stoprow) // Find accessible color after this one if (stoprow)
{
break;
}
// Find accessible color after this one
do
{ {
mc = mc->next; mc = mc->next;
if (mc == menucolortail) stoprow = true; if (mc == menucolortail)
{
stoprow = true;
} }
} while (!skincolors[mc->color].accessible && !stoprow);
}
if (stoprow)
{
break;
} }
} }
@ -12309,15 +12461,16 @@ static void M_HandleSetupMultiPlayer(INT32 choice)
case KEY_DOWNARROW: case KEY_DOWNARROW:
case KEY_UPARROW: case KEY_UPARROW:
{ {
UINT8 i;
if (itemOn == 2 && colorgrid) if (itemOn == 2 && colorgrid)
{ {
for (i = 0; i < 16; i++) UINT16 index = M_GetColorGridIndex(setupm_fakecolor->color);
{ INT32 x = M_GridIndexToX(index);
setupm_fakecolor = (choice == KEY_UPARROW) ? setupm_fakecolor->prev : setupm_fakecolor->next; INT32 y = M_GridIndexToY(index);
while (!skincolors[setupm_fakecolor->color].accessible) // skip inaccessible colors
setupm_fakecolor = (choice == KEY_UPARROW) ? setupm_fakecolor->prev : setupm_fakecolor->next; y += (choice == KEY_UPARROW) ? -1 : 1;
}
index = M_GridPosToGridIndex(x, y);
setupm_fakecolor = M_GridIndexToMenuColor(index);
} }
else if (choice == KEY_UPARROW) else if (choice == KEY_UPARROW)
M_PrevOpt(); M_PrevOpt();
@ -12344,8 +12497,8 @@ static void M_HandleSetupMultiPlayer(INT32 choice)
} }
else if (itemOn == 2) // player color else if (itemOn == 2) // player color
{ {
S_StartSound(NULL,sfx_menu1); // Tails
setupm_fakecolor = setupm_fakecolor->prev; setupm_fakecolor = setupm_fakecolor->prev;
S_StartSound(NULL,sfx_menu1); // Tails
} }
break; break;
@ -12384,8 +12537,8 @@ static void M_HandleSetupMultiPlayer(INT32 choice)
} }
else if (itemOn == 2) // player color else if (itemOn == 2) // player color
{ {
S_StartSound(NULL,sfx_menu1); // Tails
setupm_fakecolor = setupm_fakecolor->next; setupm_fakecolor = setupm_fakecolor->next;
S_StartSound(NULL,sfx_menu1); // Tails
} }
break; break;
@ -12395,14 +12548,29 @@ static void M_HandleSetupMultiPlayer(INT32 choice)
UINT8 i; UINT8 i;
if (itemOn == 2) // player color if (itemOn == 2) // player color
{ {
S_StartSound(NULL,sfx_menu1); if (colorgrid)
for (i = 0; i < (colorgrid ? 64 : 13); i++) // or (282-charw)/(2*indexwidth) {
UINT16 index = M_GetColorGridIndex(setupm_fakecolor->color);
INT32 x = M_GridIndexToX(index);
INT32 y = M_GridIndexToY(index);
y += (choice == KEY_UPARROW) ? -4 : 4;
index = M_GridPosToGridIndex(x, y);
setupm_fakecolor = M_GridIndexToMenuColor(index);
}
else
{
for (i = 0; i < 13; i++) // or (282-charw)/(2*indexwidth)
{ {
setupm_fakecolor = (choice == KEY_PGUP) ? setupm_fakecolor->prev : setupm_fakecolor->next; setupm_fakecolor = (choice == KEY_PGUP) ? setupm_fakecolor->prev : setupm_fakecolor->next;
while (!skincolors[setupm_fakecolor->color].accessible) // skip inaccessible colors while (!skincolors[setupm_fakecolor->color].accessible) // skip inaccessible colors
setupm_fakecolor = (choice == KEY_PGUP) ? setupm_fakecolor->prev : setupm_fakecolor->next; setupm_fakecolor = (choice == KEY_PGUP) ? setupm_fakecolor->prev : setupm_fakecolor->next;
} }
} }
S_StartSound(NULL, sfx_menu1); // Tails
}
} }
break; break;
@ -12431,7 +12599,6 @@ static void M_HandleSetupMultiPlayer(INT32 choice)
} }
} }
break; break;
break;
case KEY_DEL: case KEY_DEL:
if (itemOn == 0 && (l = strlen(setupm_name))!=0) if (itemOn == 0 && (l = strlen(setupm_name))!=0)

View file

@ -1131,7 +1131,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
if (!(mo2->type == MT_RING || mo2->type == MT_COIN if (!(mo2->type == MT_RING || mo2->type == MT_COIN
|| mo2->type == MT_BLUESPHERE || mo2->type == MT_BOMBSPHERE || mo2->type == MT_BLUESPHERE || mo2->type == MT_BOMBSPHERE
|| mo2->type == MT_NIGHTSCHIP || mo2->type == MT_NIGHTSSTAR || mo2->type == MT_NIGHTSCHIP || mo2->type == MT_NIGHTSSTAR
|| ((mo2->type == MT_EMBLEM) && (mo2->reactiontime & GE_NIGHTSPULL)))) || ((mo2->type == MT_EMBLEM) && (mo2->reactiontime & GE_NIGHTSPULL) && P_CanPickupEmblem(player, mo2->health - 1) && !P_EmblemWasCollected(mo2->health - 1))))
continue; continue;
// Yay! The thing's in reach! Pull it in! // Yay! The thing's in reach! Pull it in!
@ -2222,7 +2222,7 @@ void P_CheckTimeLimit(void)
} }
if (server) if (server)
SendNetXCmd(XD_EXITLEVEL, NULL, 0); D_SendExitLevel(false);
} }
//Optional tie-breaker for Match/CTF //Optional tie-breaker for Match/CTF
@ -2297,11 +2297,11 @@ void P_CheckTimeLimit(void)
} }
} }
if (server) if (server)
SendNetXCmd(XD_EXITLEVEL, NULL, 0); D_SendExitLevel(false);
} }
if (server) if (server)
SendNetXCmd(XD_EXITLEVEL, NULL, 0); D_SendExitLevel(false);
} }
/** Checks if a player's score is over the pointlimit and the round should end. /** Checks if a player's score is over the pointlimit and the round should end.
@ -2330,7 +2330,7 @@ void P_CheckPointLimit(void)
{ {
if (teamscores[G_GetTeam(i)] >= (UINT32)cv_pointlimit.value) if (teamscores[G_GetTeam(i)] >= (UINT32)cv_pointlimit.value)
{ {
SendNetXCmd(XD_EXITLEVEL, NULL, 0); D_SendExitLevel(false);
return; return;
} }
} }
@ -2345,7 +2345,7 @@ void P_CheckPointLimit(void)
if ((UINT32)cv_pointlimit.value <= players[i].score) if ((UINT32)cv_pointlimit.value <= players[i].score)
{ {
SendNetXCmd(XD_EXITLEVEL, NULL, 0); D_SendExitLevel(false);
return; return;
} }
} }
@ -2389,7 +2389,7 @@ void P_CheckSurvivors(void)
{ {
CONS_Printf(M_GetText("The IT player has left the game.\n")); CONS_Printf(M_GetText("The IT player has left the game.\n"));
if (server) if (server)
SendNetXCmd(XD_EXITLEVEL, NULL, 0); D_SendExitLevel(false);
return; return;
} }
@ -2409,7 +2409,7 @@ void P_CheckSurvivors(void)
{ {
CONS_Printf(M_GetText("All players have been tagged!\n")); CONS_Printf(M_GetText("All players have been tagged!\n"));
if (server) if (server)
SendNetXCmd(XD_EXITLEVEL, NULL, 0); D_SendExitLevel(false);
} }
return; return;
@ -2421,7 +2421,7 @@ void P_CheckSurvivors(void)
{ {
CONS_Printf(M_GetText("There are no players able to become IT.\n")); CONS_Printf(M_GetText("There are no players able to become IT.\n"));
if (server) if (server)
SendNetXCmd(XD_EXITLEVEL, NULL, 0); D_SendExitLevel(false);
} }
return; return;
@ -2433,7 +2433,7 @@ void P_CheckSurvivors(void)
{ {
CONS_Printf(M_GetText("All players have been tagged!\n")); CONS_Printf(M_GetText("All players have been tagged!\n"));
if (server) if (server)
SendNetXCmd(XD_EXITLEVEL, NULL, 0); D_SendExitLevel(false);
} }
} }

View file

@ -2524,7 +2524,6 @@ boolean P_CheckCameraPosition(fixed_t x, fixed_t y, camera_t *thiscam)
boolean P_TryCameraMove(fixed_t x, fixed_t y, camera_t *thiscam) boolean P_TryCameraMove(fixed_t x, fixed_t y, camera_t *thiscam)
{ {
subsector_t *s = R_PointInSubsector(x, y); subsector_t *s = R_PointInSubsector(x, y);
boolean retval = true;
boolean itsatwodlevel = false; boolean itsatwodlevel = false;
floatok = false; floatok = false;
@ -2539,8 +2538,8 @@ boolean P_TryCameraMove(fixed_t x, fixed_t y, camera_t *thiscam)
fixed_t tryx = thiscam->x; fixed_t tryx = thiscam->x;
fixed_t tryy = thiscam->y; fixed_t tryy = thiscam->y;
if ((thiscam == &camera && (players[displayplayer].pflags & PF_NOCLIP)) if ((thiscam == &camera && (players[displayplayer].pflags & PF_NOCLIP || players[displayplayer].powers[pw_carry] == CR_NIGHTSMODE))
|| (thiscam == &camera2 && (players[secondarydisplayplayer].pflags & PF_NOCLIP))) || (thiscam == &camera2 && (players[secondarydisplayplayer].pflags & PF_NOCLIP || players[secondarydisplayplayer].powers[pw_carry] == CR_NIGHTSMODE)))
{ // Noclipping player camera noclips too!! { // Noclipping player camera noclips too!!
floatok = true; floatok = true;
thiscam->floorz = thiscam->z; thiscam->floorz = thiscam->z;
@ -2608,7 +2607,7 @@ boolean P_TryCameraMove(fixed_t x, fixed_t y, camera_t *thiscam)
thiscam->y = y; thiscam->y = y;
thiscam->subsector = s; thiscam->subsector = s;
return retval; return true;
} }
// //
@ -3731,7 +3730,9 @@ void P_SlideMove(mobj_t *mo)
boolean papercol = false; boolean papercol = false;
vertex_t v1, v2; // fake vertexes vertex_t v1, v2; // fake vertexes
line_t junk; // fake linedef static line_t junk; // fake linedef
memset(&junk, 0x00, sizeof(junk));
if (tmhitthing && mo->z + mo->height > tmhitthing->z && mo->z < tmhitthing->z + tmhitthing->height) if (tmhitthing && mo->z + mo->height > tmhitthing->z && mo->z < tmhitthing->z + tmhitthing->height)
{ {

View file

@ -3691,7 +3691,7 @@ boolean P_CameraThinker(player_t *player, camera_t *thiscam, boolean resetcalled
dummy.y = thiscam->y; dummy.y = thiscam->y;
dummy.z = thiscam->z; dummy.z = thiscam->z;
dummy.height = thiscam->height; dummy.height = thiscam->height;
if (!resetcalled && !(player->pflags & PF_NOCLIP) && !P_CheckSight(&dummy, player->mo)) // TODO: "P_CheckCameraSight" instead. if (!resetcalled && !(player->pflags & PF_NOCLIP || player->powers[pw_carry] == CR_NIGHTSMODE) && !P_CheckSight(&dummy, player->mo)) // TODO: "P_CheckCameraSight" instead.
P_ResetCamera(player, thiscam); P_ResetCamera(player, thiscam);
else else
{ {
@ -3722,7 +3722,7 @@ boolean P_CameraThinker(player_t *player, camera_t *thiscam, boolean resetcalled
// adjust height // adjust height
thiscam->z += thiscam->momz + player->mo->pmomz; thiscam->z += thiscam->momz + player->mo->pmomz;
if (!itsatwodlevel && !(player->pflags & PF_NOCLIP)) if (!itsatwodlevel && !(player->pflags & PF_NOCLIP || player->powers[pw_carry] == CR_NIGHTSMODE))
{ {
// clip movement // clip movement
if (thiscam->z <= thiscam->floorz) // hit the floor if (thiscam->z <= thiscam->floorz) // hit the floor
@ -6885,7 +6885,6 @@ void P_RunOverlays(void)
mo->eflags = (mo->eflags & ~MFE_VERTICALFLIP) | (mo->target->eflags & MFE_VERTICALFLIP); mo->eflags = (mo->eflags & ~MFE_VERTICALFLIP) | (mo->target->eflags & MFE_VERTICALFLIP);
mo->scale = mo->destscale = mo->target->scale; mo->scale = mo->destscale = mo->target->scale;
mo->angle = (mo->target->player ? mo->target->player->drawangle : mo->target->angle) + mo->movedir; mo->angle = (mo->target->player ? mo->target->player->drawangle : mo->target->angle) + mo->movedir;
P_SetTarget(&mo->dontdrawforviewmobj, mo->target->dontdrawforviewmobj); // Hide the overlay from the view that its target is hidden from - But don't copy drawonlyforplayer!
if (!(mo->state->frame & FF_ANIMATE)) if (!(mo->state->frame & FF_ANIMATE))
zoffs = FixedMul(((signed)mo->state->var2)*FRACUNIT, mo->scale); zoffs = FixedMul(((signed)mo->state->var2)*FRACUNIT, mo->scale);
@ -9231,7 +9230,7 @@ static void P_DragonbomberThink(mobj_t *mobj)
else else
{ {
fixed_t vspeed = FixedMul(mobj->info->speed >> 3, mobj->scale); fixed_t vspeed = FixedMul(mobj->info->speed >> 3, mobj->scale);
fixed_t z = mobj->target->z + (mobj->height >> 1) + (mobj->flags & MFE_VERTICALFLIP ? -128*mobj->scale : 128*mobj->scale + mobj->target->height); fixed_t z = mobj->target->z + (mobj->height >> 1) + (mobj->eflags & MFE_VERTICALFLIP ? -128*mobj->scale : (128*mobj->scale + mobj->target->height));
angle_t diff = R_PointToAngle2(mobj->x, mobj->y, mobj->target->x, mobj->target->y) - mobj->angle; angle_t diff = R_PointToAngle2(mobj->x, mobj->y, mobj->target->x, mobj->target->y) - mobj->angle;
if (diff > ANGLE_180) if (diff > ANGLE_180)
mobj->angle -= DRAGONTURNSPEED; mobj->angle -= DRAGONTURNSPEED;
@ -10562,6 +10561,29 @@ static fixed_t P_DefaultMobjShadowScale (mobj_t *thing)
case MT_REDFLAG: case MT_REDFLAG:
case MT_BLUEFLAG: case MT_BLUEFLAG:
case MT_BOUNCERING:
case MT_AUTOMATICRING:
case MT_INFINITYRING:
case MT_RAILRING:
case MT_EXPLOSIONRING:
case MT_SCATTERRING:
case MT_GRENADERING:
case MT_BOUNCEPICKUP:
case MT_RAILPICKUP:
case MT_AUTOPICKUP:
case MT_EXPLODEPICKUP:
case MT_SCATTERPICKUP:
case MT_GRENADEPICKUP:
case MT_REDRING:
case MT_THROWNBOUNCE:
case MT_THROWNINFINITY:
case MT_THROWNAUTOMATIC:
case MT_THROWNSCATTER:
case MT_THROWNEXPLOSION:
case MT_THROWNGRENADE:
case MT_EMBLEM: case MT_EMBLEM:
case MT_TOKEN: case MT_TOKEN:
@ -11894,7 +11916,7 @@ void P_SetAbsoluteSpawnPointHeight(spawnpoint_t *spawnpoint, fixed_t offset)
spawnpoint->z = ceilingspawn; spawnpoint->z = ceilingspawn;
} }
fixed_t P_GetMobjSpawnHeight(const mobjtype_t mobjtype, const fixed_t x, const fixed_t y, const fixed_t dz, const fixed_t offset, const boolean flip, const fixed_t scale) fixed_t P_GetMobjSpawnHeight(const mobjtype_t mobjtype, const fixed_t x, const fixed_t y, const fixed_t dz, const fixed_t offset, const boolean flip, const fixed_t scale, const boolean absolutez)
{ {
const subsector_t *ss = R_PointInSubsector(x, y); const subsector_t *ss = R_PointInSubsector(x, y);
@ -11904,9 +11926,9 @@ fixed_t P_GetMobjSpawnHeight(const mobjtype_t mobjtype, const fixed_t x, const f
// Establish height. // Establish height.
if (flip) if (flip)
return P_GetSectorCeilingZAt(ss->sector, x, y) - dz - FixedMul(scale, offset + mobjinfo[mobjtype].height); return (absolutez ? dz : P_GetSectorCeilingZAt(ss->sector, x, y) - dz) - FixedMul(scale, offset + mobjinfo[mobjtype].height);
else else
return P_GetSectorFloorZAt(ss->sector, x, y) + dz + FixedMul(scale, offset); return (absolutez ? dz : P_GetSectorFloorZAt(ss->sector, x, y) + dz) + FixedMul(scale, offset);
} }
fixed_t P_GetMapThingSpawnHeight(const mobjtype_t mobjtype, const mapthing_t* mthing, const fixed_t x, const fixed_t y) fixed_t P_GetMapThingSpawnHeight(const mobjtype_t mobjtype, const mapthing_t* mthing, const fixed_t x, const fixed_t y)
@ -11914,6 +11936,7 @@ fixed_t P_GetMapThingSpawnHeight(const mobjtype_t mobjtype, const mapthing_t* mt
fixed_t dz = mthing->z << FRACBITS; // Base offset from the floor. fixed_t dz = mthing->z << FRACBITS; // Base offset from the floor.
fixed_t offset = 0; // Specific scaling object offset. fixed_t offset = 0; // Specific scaling object offset.
boolean flip = (!!(mobjinfo[mobjtype].flags & MF_SPAWNCEILING) ^ !!(mthing->options & MTF_OBJECTFLIP)); boolean flip = (!!(mobjinfo[mobjtype].flags & MF_SPAWNCEILING) ^ !!(mthing->options & MTF_OBJECTFLIP));
boolean absolutez = !!(mthing->options & MTF_ABSOLUTEZ);
switch (mobjtype) switch (mobjtype)
{ {
@ -11969,7 +11992,7 @@ fixed_t P_GetMapThingSpawnHeight(const mobjtype_t mobjtype, const mapthing_t* mt
offset += mthing->args[0] ? 0 : 24*FRACUNIT; offset += mthing->args[0] ? 0 : 24*FRACUNIT;
} }
if (!(dz + offset)) // Snap to the surfaces when there's no offset set. if (!(dz + offset) && !absolutez) // Snap to the surfaces when there's no offset set.
{ {
if (flip) if (flip)
return ONCEILINGZ; return ONCEILINGZ;
@ -11977,7 +12000,7 @@ fixed_t P_GetMapThingSpawnHeight(const mobjtype_t mobjtype, const mapthing_t* mt
return ONFLOORZ; return ONFLOORZ;
} }
return P_GetMobjSpawnHeight(mobjtype, x, y, dz, offset, flip, mthing->scale); return P_GetMobjSpawnHeight(mobjtype, x, y, dz, offset, flip, mthing->scale, absolutez);
} }
static boolean P_SpawnNonMobjMapThing(mapthing_t *mthing) static boolean P_SpawnNonMobjMapThing(mapthing_t *mthing)
@ -12658,7 +12681,7 @@ static boolean P_SetupNiGHTSDrone(mapthing_t *mthing, mobj_t *mobj)
dronemangoaldiff = max(mobjinfo[MT_NIGHTSDRONE_MAN].height - mobjinfo[MT_NIGHTSDRONE_GOAL].height, 0); dronemangoaldiff = max(mobjinfo[MT_NIGHTSDRONE_MAN].height - mobjinfo[MT_NIGHTSDRONE_GOAL].height, 0);
if (flip && mobj->height != oldheight) if (flip && mobj->height != oldheight)
P_MoveOrigin(mobj, mobj->x, mobj->y, mobj->z - (mobj->height - oldheight)); P_SetOrigin(mobj, mobj->x, mobj->y, mobj->z - (mobj->height - oldheight));
if (!flip) if (!flip)
{ {
@ -13505,7 +13528,7 @@ void P_SpawnHoop(mapthing_t *mthing)
vector4_t v, res; vector4_t v, res;
fixed_t x = mthing->x << FRACBITS; fixed_t x = mthing->x << FRACBITS;
fixed_t y = mthing->y << FRACBITS; fixed_t y = mthing->y << FRACBITS;
fixed_t z = P_GetMobjSpawnHeight(MT_HOOP, x, y, mthing->z << FRACBITS, 0, false, mthing->scale); fixed_t z = P_GetMobjSpawnHeight(MT_HOOP, x, y, mthing->z << FRACBITS, 0, false, mthing->scale, mthing->options & MTF_ABSOLUTEZ);
hoopcenter = P_SpawnMobj(x, y, z, MT_HOOPCENTER); hoopcenter = P_SpawnMobj(x, y, z, MT_HOOPCENTER);
hoopcenter->spawnpoint = mthing; hoopcenter->spawnpoint = mthing;
@ -13632,7 +13655,7 @@ static void P_SpawnItemRow(mapthing_t *mthing, mobjtype_t *itemtypes, UINT8 numi
itemtypes[r] = P_GetMobjtypeSubstitute(&dummything, itemtypes[r]); itemtypes[r] = P_GetMobjtypeSubstitute(&dummything, itemtypes[r]);
} }
} }
z = P_GetMobjSpawnHeight(itemtypes[0], x, y, z, 0, mthing->options & MTF_OBJECTFLIP, mthing->scale); z = P_GetMobjSpawnHeight(itemtypes[0], x, y, z, 0, mthing->options & MTF_OBJECTFLIP, mthing->scale, mthing->options & MTF_ABSOLUTEZ);
for (r = 0; r < numitems; r++) for (r = 0; r < numitems; r++)
{ {
@ -13691,7 +13714,7 @@ static void P_SpawnItemCircle(mapthing_t *mthing, mobjtype_t *itemtypes, UINT8 n
itemtypes[i] = P_GetMobjtypeSubstitute(&dummything, itemtypes[i]); itemtypes[i] = P_GetMobjtypeSubstitute(&dummything, itemtypes[i]);
} }
} }
z = P_GetMobjSpawnHeight(itemtypes[0], x, y, z, 0, false, mthing->scale); z = P_GetMobjSpawnHeight(itemtypes[0], x, y, z, 0, false, mthing->scale, mthing->options & MTF_ABSOLUTEZ);
for (i = 0; i < numitems; i++) for (i = 0; i < numitems; i++)
{ {

View file

@ -486,7 +486,7 @@ void P_AddCachedAction(mobj_t *mobj, INT32 statenum);
// check mobj against water content, before movement code // check mobj against water content, before movement code
void P_MobjCheckWater(mobj_t *mobj); void P_MobjCheckWater(mobj_t *mobj);
fixed_t P_GetMobjSpawnHeight(const mobjtype_t mobjtype, const fixed_t x, const fixed_t y, const fixed_t dz, const fixed_t offset, const boolean flip, const fixed_t scale); fixed_t P_GetMobjSpawnHeight(const mobjtype_t mobjtype, const fixed_t x, const fixed_t y, const fixed_t dz, const fixed_t offset, const boolean flip, const fixed_t scale, const boolean absolutez);
fixed_t P_GetMapThingSpawnHeight(const mobjtype_t mobjtype, const mapthing_t* mthing, const fixed_t x, const fixed_t y); fixed_t P_GetMapThingSpawnHeight(const mobjtype_t mobjtype, const mapthing_t* mthing, const fixed_t x, const fixed_t y);
mobj_t *P_SpawnMapThing(mapthing_t *mthing); mobj_t *P_SpawnMapThing(mapthing_t *mthing);

View file

@ -50,6 +50,7 @@
#include "m_random.h" #include "m_random.h"
#include "dehacked.h" // for map headers #include "dehacked.h" // for map headers
#include "deh_tables.h" // FREE_SKINCOLORS
#include "r_main.h" #include "r_main.h"
#include "m_cond.h" // for emblems #include "m_cond.h" // for emblems
@ -1267,12 +1268,19 @@ static void P_WriteDuplicateText(const char *text, char **target)
static void P_WriteSkincolor(INT32 constant, char **target) static void P_WriteSkincolor(INT32 constant, char **target)
{ {
const char *color_name;
if (constant <= SKINCOLOR_NONE if (constant <= SKINCOLOR_NONE
|| constant >= (INT32)numskincolors) || constant >= (INT32)numskincolors)
return; return;
if (constant >= SKINCOLOR_FIRSTFREESLOT)
color_name = FREE_SKINCOLORS[constant - SKINCOLOR_FIRSTFREESLOT];
else
color_name = COLOR_ENUMS[constant];
P_WriteDuplicateText( P_WriteDuplicateText(
va("SKINCOLOR_%s", skincolors[constant].name), va("SKINCOLOR_%s", color_name),
target target
); );
} }
@ -2045,6 +2053,8 @@ static void ParseTextmapThingParameter(UINT32 i, const char *param, const char *
// Flags // Flags
else if (fastcmp(param, "flip") && fastcmp("true", val)) else if (fastcmp(param, "flip") && fastcmp("true", val))
mapthings[i].options |= MTF_OBJECTFLIP; mapthings[i].options |= MTF_OBJECTFLIP;
else if (fastcmp(param, "absolutez") && fastcmp("true", val))
mapthings[i].options |= MTF_ABSOLUTEZ;
else if (fastncmp(param, "stringarg", 9) && strlen(param) > 9) else if (fastncmp(param, "stringarg", 9) && strlen(param) > 9)
{ {
@ -5498,7 +5508,7 @@ static void P_ConvertBinaryLinedefTypes(void)
break; break;
case 442: //Change object type state case 442: //Change object type state
lines[i].args[0] = tag; lines[i].args[0] = tag;
lines[i].args[3] = (lines[i].sidenum[1] == 0xffff) ? 1 : 0; lines[i].args[1] = (lines[i].sidenum[1] == 0xffff) ? 1 : 0;
break; break;
case 443: //Call Lua function case 443: //Call Lua function
if (lines[i].stringargs[0] == NULL) if (lines[i].stringargs[0] == NULL)
@ -6843,6 +6853,9 @@ static void P_ConvertBinaryThingTypes(void)
default: default:
break; break;
} }
// Clear binary thing height hacks, to prevent interfering with UDMF-only flags
mapthings[i].options &= 0xF;
} }
} }
@ -8261,7 +8274,7 @@ static boolean P_LoadAddon(UINT16 numlumps)
{ {
CONS_Printf(M_GetText("Current map %d replaced by added file, ending the level to ensure consistency.\n"), gamemap); CONS_Printf(M_GetText("Current map %d replaced by added file, ending the level to ensure consistency.\n"), gamemap);
if (server) if (server)
SendNetXCmd(XD_EXITLEVEL, NULL, 0); D_SendExitLevel(false);
} }
return true; return true;

View file

@ -566,6 +566,7 @@ static void line_SpawnViaMapthingVertexes(const int linenum, const boolean spawn
case TMSP_BACKCEILING: case TMSP_BACKCEILING:
slopetoset = &line->backsector->c_slope; slopetoset = &line->backsector->c_slope;
side = &sides[line->sidenum[1]]; side = &sides[line->sidenum[1]];
break;
default: default:
return; return;
} }

View file

@ -3286,19 +3286,18 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
foundrover = true; foundrover = true;
// If fading an invisible FOF whose render flags we did not yet set, // If fading an invisible FOF whose render flags we did not yet set,
// initialize its alpha to 1 // initialize its alpha to 0 for relative alpha calculation
// for relative alpha calc
if (!(line->args[3] & TMST_DONTDOTRANSLUCENT) && // do translucent if (!(line->args[3] & TMST_DONTDOTRANSLUCENT) && // do translucent
(rover->spawnflags & FOF_NOSHADE) && // do not include light blocks, which don't set FOF_NOSHADE (rover->spawnflags & FOF_NOSHADE) && // do not include light blocks, which don't set FOF_NOSHADE
!(rover->spawnflags & FOF_RENDERSIDES) && !(rover->spawnflags & FOF_RENDERSIDES) &&
!(rover->spawnflags & FOF_RENDERPLANES) && !(rover->spawnflags & FOF_RENDERPLANES) &&
!(rover->fofflags & FOF_RENDERALL)) !(rover->fofflags & FOF_RENDERALL))
rover->alpha = 1; rover->alpha = 0;
P_RemoveFakeFloorFader(rover); P_RemoveFakeFloorFader(rover);
P_FadeFakeFloor(rover, P_FadeFakeFloor(rover,
rover->alpha, rover->alpha,
max(1, min(256, (line->args[3] & TMST_RELATIVE) ? rover->alpha + destvalue : destvalue)), max(0, min(255, (line->args[3] & TMST_RELATIVE) ? rover->alpha + destvalue : destvalue)),
0, // set alpha immediately 0, // set alpha immediately
false, NULL, // tic-based logic false, NULL, // tic-based logic
false, // do not handle FOF_EXISTS false, // do not handle FOF_EXISTS
@ -3372,19 +3371,18 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
else else
{ {
// If fading an invisible FOF whose render flags we did not yet set, // If fading an invisible FOF whose render flags we did not yet set,
// initialize its alpha to 1 // initialize its alpha to 1 for relative alpha calculation
// for relative alpha calc
if (!(line->args[4] & TMFT_DONTDOTRANSLUCENT) && // do translucent if (!(line->args[4] & TMFT_DONTDOTRANSLUCENT) && // do translucent
(rover->spawnflags & FOF_NOSHADE) && // do not include light blocks, which don't set FOF_NOSHADE (rover->spawnflags & FOF_NOSHADE) && // do not include light blocks, which don't set FOF_NOSHADE
!(rover->spawnflags & FOF_RENDERSIDES) && !(rover->spawnflags & FOF_RENDERSIDES) &&
!(rover->spawnflags & FOF_RENDERPLANES) && !(rover->spawnflags & FOF_RENDERPLANES) &&
!(rover->fofflags & FOF_RENDERALL)) !(rover->fofflags & FOF_RENDERALL))
rover->alpha = 1; rover->alpha = 0;
P_RemoveFakeFloorFader(rover); P_RemoveFakeFloorFader(rover);
P_FadeFakeFloor(rover, P_FadeFakeFloor(rover,
rover->alpha, rover->alpha,
max(1, min(256, (line->args[4] & TMFT_RELATIVE) ? rover->alpha + destvalue : destvalue)), max(0, min(255, (line->args[4] & TMFT_RELATIVE) ? rover->alpha + destvalue : destvalue)),
0, // set alpha immediately 0, // set alpha immediately
false, NULL, // tic-based logic false, NULL, // tic-based logic
!(line->args[4] & TMFT_DONTDOEXISTS), // do not handle FOF_EXISTS !(line->args[4] & TMFT_DONTDOEXISTS), // do not handle FOF_EXISTS
@ -6710,10 +6708,10 @@ void P_SpawnSpecials(boolean fromnetsave)
//Cutting options //Cutting options
if (ffloorflags & FOF_RENDERALL) if (ffloorflags & FOF_RENDERALL)
{ {
//If inside is visible, cut inner walls //If inside is visible from the outside, cut inner walls
if ((lines[i].args[1] < 255) || (lines[i].args[3] & TMFA_SPLAT) || (lines[i].args[4] & TMFT_VISIBLEFROMINSIDE)) if (lines[i].args[1] < 255 || (lines[i].args[3] & TMFA_SPLAT))
ffloorflags |= FOF_CUTEXTRA|FOF_EXTRA; ffloorflags |= FOF_CUTEXTRA|FOF_EXTRA;
else else if (!(lines[i].args[4] & TMFT_VISIBLEFROMINSIDE))
ffloorflags |= FOF_CUTLEVEL; ffloorflags |= FOF_CUTLEVEL;
} }
@ -6769,20 +6767,19 @@ void P_SpawnSpecials(boolean fromnetsave)
if (lines[i].args[4] & TMFC_SPLAT) if (lines[i].args[4] & TMFC_SPLAT)
ffloorflags |= FOF_SPLAT; ffloorflags |= FOF_SPLAT;
//If inside is visible, cut inner walls //If inside is visible from the outside, cut inner walls
if (lines[i].args[1] < 0xff || (lines[i].args[3] & TMFT_VISIBLEFROMINSIDE) || (lines[i].args[4] & TMFC_SPLAT)) if (lines[i].args[1] < 255 || (lines[i].args[4] & TMFC_SPLAT))
ffloorflags |= FOF_CUTEXTRA|FOF_EXTRA; ffloorflags |= FOF_CUTEXTRA|FOF_EXTRA;
else //If player can view it from the inside, render insides
ffloorflags |= FOF_CUTLEVEL; else if (lines[i].args[3] & TMFT_VISIBLEFROMINSIDE)
//If player can enter it, render insides
if (lines[i].args[3] & TMFT_VISIBLEFROMINSIDE)
{ {
if (ffloorflags & FOF_RENDERPLANES) if (ffloorflags & FOF_RENDERPLANES)
ffloorflags |= FOF_BOTHPLANES; ffloorflags |= FOF_BOTHPLANES;
if (ffloorflags & FOF_RENDERSIDES) if (ffloorflags & FOF_RENDERSIDES)
ffloorflags |= FOF_ALLSIDES; ffloorflags |= FOF_ALLSIDES;
} }
else
ffloorflags |= FOF_CUTLEVEL;
P_AddFakeFloorsByLine(i, lines[i].args[1], lines[i].args[2], ffloorflags, secthinkers); P_AddFakeFloorsByLine(i, lines[i].args[1], lines[i].args[2], ffloorflags, secthinkers);
if (lines[i].args[4] & TMFC_AIRBOB) if (lines[i].args[4] & TMFC_AIRBOB)
@ -6833,10 +6830,10 @@ void P_SpawnSpecials(boolean fromnetsave)
//Cutting options //Cutting options
if (ffloorflags & FOF_RENDERALL) if (ffloorflags & FOF_RENDERALL)
{ {
//If inside is visible, cut inner walls //If inside is visible from the outside, cut inner walls
if ((lines[i].args[1] < 255) || (lines[i].args[3] & TMFA_SPLAT) || (lines[i].args[4] & TMFT_VISIBLEFROMINSIDE)) if (lines[i].args[1] < 255 || (lines[i].args[3] & TMFA_SPLAT))
ffloorflags |= FOF_CUTEXTRA|FOF_EXTRA; ffloorflags |= FOF_CUTEXTRA|FOF_EXTRA;
else else if (!(lines[i].args[4] & TMFT_VISIBLEFROMINSIDE))
ffloorflags |= FOF_CUTLEVEL; ffloorflags |= FOF_CUTLEVEL;
} }
@ -7901,15 +7898,14 @@ static boolean P_FadeFakeFloor(ffloor_t *rover, INT16 sourcevalue, INT16 destval
if (rover->master->special == 258) // Laser block if (rover->master->special == 258) // Laser block
return false; return false;
// If fading an invisible FOF whose render flags we did not yet set, // If fading an invisible FOF whose render flags we did not yet set, initialize its alpha to 1
// initialize its alpha to 1
if (dotranslucent && if (dotranslucent &&
(rover->spawnflags & FOF_NOSHADE) && // do not include light blocks, which don't set FOF_NOSHADE (rover->spawnflags & FOF_NOSHADE) && // do not include light blocks, which don't set FOF_NOSHADE
!(rover->fofflags & FOF_FOG) && // do not include fog !(rover->fofflags & FOF_FOG) && // do not include fog
!(rover->spawnflags & FOF_RENDERSIDES) && !(rover->spawnflags & FOF_RENDERSIDES) &&
!(rover->spawnflags & FOF_RENDERPLANES) && !(rover->spawnflags & FOF_RENDERPLANES) &&
!(rover->fofflags & FOF_RENDERALL)) !(rover->fofflags & FOF_RENDERALL))
rover->alpha = 1; rover->alpha = 0;
if (fadingdata) if (fadingdata)
alpha = fadingdata->alpha; alpha = fadingdata->alpha;
@ -7995,7 +7991,7 @@ static boolean P_FadeFakeFloor(ffloor_t *rover, INT16 sourcevalue, INT16 destval
{ {
if (doexists && !(rover->spawnflags & FOF_BUSTUP)) if (doexists && !(rover->spawnflags & FOF_BUSTUP))
{ {
if (alpha <= 1) if (alpha <= 0)
rover->fofflags &= ~FOF_EXISTS; rover->fofflags &= ~FOF_EXISTS;
else else
rover->fofflags |= FOF_EXISTS; rover->fofflags |= FOF_EXISTS;
@ -8007,7 +8003,7 @@ static boolean P_FadeFakeFloor(ffloor_t *rover, INT16 sourcevalue, INT16 destval
if (dotranslucent && !(rover->fofflags & FOF_FOG)) if (dotranslucent && !(rover->fofflags & FOF_FOG))
{ {
if (alpha >= 256) if (alpha >= 255)
{ {
if (!(rover->fofflags & FOF_CUTSOLIDS) && if (!(rover->fofflags & FOF_CUTSOLIDS) &&
(rover->spawnflags & FOF_CUTSOLIDS)) (rover->spawnflags & FOF_CUTSOLIDS))
@ -8107,7 +8103,7 @@ static boolean P_FadeFakeFloor(ffloor_t *rover, INT16 sourcevalue, INT16 destval
else // clamp fadingdata->alpha to software's alpha levels else // clamp fadingdata->alpha to software's alpha levels
{ {
if (alpha < 12) if (alpha < 12)
rover->alpha = destvalue < 12 ? destvalue : 1; // Don't even draw it rover->alpha = destvalue < 12 ? destvalue : 0; // Don't even draw it
else if (alpha < 38) else if (alpha < 38)
rover->alpha = destvalue >= 12 && destvalue < 38 ? destvalue : 25; rover->alpha = destvalue >= 12 && destvalue < 38 ? destvalue : 25;
else if (alpha < 64) else if (alpha < 64)
@ -8127,7 +8123,7 @@ static boolean P_FadeFakeFloor(ffloor_t *rover, INT16 sourcevalue, INT16 destval
else if (alpha < 243) else if (alpha < 243)
rover->alpha = destvalue >= 217 && destvalue < 243 ? destvalue : 230; rover->alpha = destvalue >= 217 && destvalue < 243 ? destvalue : 230;
else // Opaque else // Opaque
rover->alpha = destvalue >= 243 ? destvalue : 256; rover->alpha = destvalue >= 243 ? destvalue : 255;
} }
} }
@ -8157,17 +8153,16 @@ static void P_AddFakeFloorFader(ffloor_t *rover, size_t sectornum, size_t ffloor
{ {
fade_t *d; fade_t *d;
// If fading an invisible FOF whose render flags we did not yet set, // If fading an invisible FOF whose render flags we did not yet set, initialize its alpha to 1
// initialize its alpha to 1
if (dotranslucent && if (dotranslucent &&
(rover->spawnflags & FOF_NOSHADE) && // do not include light blocks, which don't set FOF_NOSHADE (rover->spawnflags & FOF_NOSHADE) && // do not include light blocks, which don't set FOF_NOSHADE
!(rover->spawnflags & FOF_RENDERSIDES) && !(rover->spawnflags & FOF_RENDERSIDES) &&
!(rover->spawnflags & FOF_RENDERPLANES) && !(rover->spawnflags & FOF_RENDERPLANES) &&
!(rover->fofflags & FOF_RENDERALL)) !(rover->fofflags & FOF_RENDERALL))
rover->alpha = 1; rover->alpha = 0;
// already equal, nothing to do // already equal, nothing to do
if (rover->alpha == max(1, min(256, relative ? rover->alpha + destvalue : destvalue))) if (rover->alpha == max(0, min(255, relative ? rover->alpha + destvalue : destvalue)))
return; return;
d = Z_Malloc(sizeof *d, PU_LEVSPEC, NULL); d = Z_Malloc(sizeof *d, PU_LEVSPEC, NULL);
@ -8178,7 +8173,7 @@ static void P_AddFakeFloorFader(ffloor_t *rover, size_t sectornum, size_t ffloor
d->ffloornum = (UINT32)ffloornum; d->ffloornum = (UINT32)ffloornum;
d->alpha = d->sourcevalue = rover->alpha; d->alpha = d->sourcevalue = rover->alpha;
d->destvalue = max(1, min(256, relative ? rover->alpha + destvalue : destvalue)); // rover->alpha is 1-256 d->destvalue = max(0, min(255, relative ? rover->alpha + destvalue : destvalue)); // rover->alpha is 0-255
if (ticbased) if (ticbased)
{ {

View file

@ -1849,6 +1849,7 @@ void P_SpawnShieldOrb(player_t *player)
{ {
ov = P_SpawnMobj(shieldobj->x, shieldobj->y, shieldobj->z, MT_OVERLAY); ov = P_SpawnMobj(shieldobj->x, shieldobj->y, shieldobj->z, MT_OVERLAY);
P_SetTarget(&ov->target, shieldobj); P_SetTarget(&ov->target, shieldobj);
P_SetTarget(&ov->dontdrawforviewmobj, player->mo); // Hide the shield in first-person
P_SetMobjState(ov, shieldobj->info->seestate); P_SetMobjState(ov, shieldobj->info->seestate);
P_SetTarget(&shieldobj->tracer, ov); P_SetTarget(&shieldobj->tracer, ov);
} }
@ -1856,12 +1857,14 @@ void P_SpawnShieldOrb(player_t *player)
{ {
ov = P_SpawnMobj(shieldobj->x, shieldobj->y, shieldobj->z, MT_OVERLAY); ov = P_SpawnMobj(shieldobj->x, shieldobj->y, shieldobj->z, MT_OVERLAY);
P_SetTarget(&ov->target, shieldobj); P_SetTarget(&ov->target, shieldobj);
P_SetTarget(&ov->dontdrawforviewmobj, player->mo); // Hide the shield in first-person
P_SetMobjState(ov, shieldobj->info->meleestate); P_SetMobjState(ov, shieldobj->info->meleestate);
} }
if (shieldobj->info->missilestate) if (shieldobj->info->missilestate)
{ {
ov = P_SpawnMobj(shieldobj->x, shieldobj->y, shieldobj->z, MT_OVERLAY); ov = P_SpawnMobj(shieldobj->x, shieldobj->y, shieldobj->z, MT_OVERLAY);
P_SetTarget(&ov->target, shieldobj); P_SetTarget(&ov->target, shieldobj);
P_SetTarget(&ov->dontdrawforviewmobj, player->mo); // Hide the shield in first-person
P_SetMobjState(ov, shieldobj->info->missilestate); P_SetMobjState(ov, shieldobj->info->missilestate);
} }
if (player->powers[pw_shield] & SH_FORCE) if (player->powers[pw_shield] & SH_FORCE)
@ -2025,14 +2028,14 @@ mobj_t *P_SpawnGhostMobj(mobj_t *mobj)
ghost->standingslope = mobj->standingslope; ghost->standingslope = mobj->standingslope;
if (mobj->flags2 & MF2_OBJECTFLIP) if (mobj->flags2 & MF2_OBJECTFLIP)
ghost->flags |= MF2_OBJECTFLIP; ghost->flags2 |= MF2_OBJECTFLIP;
if (mobj->player && mobj->player->followmobj) if (mobj->player && mobj->player->followmobj)
{ {
mobj_t *ghost2 = P_SpawnGhostMobj(mobj->player->followmobj); mobj_t *ghost2 = P_SpawnGhostMobj(mobj->player->followmobj);
P_SetTarget(&ghost2->tracer, ghost); P_SetTarget(&ghost2->tracer, ghost);
P_SetTarget(&ghost->tracer, ghost2); P_SetTarget(&ghost->tracer, ghost2);
P_SetTarget(&ghost2->dontdrawforviewmobj, mobj); // Hide the follow-ghost for the non-follow object P_SetTarget(&ghost2->dontdrawforviewmobj, mobj); // Hide the follow-ghost for the non-follow target
ghost2->flags2 |= (mobj->player->followmobj->flags2 & MF2_LINKDRAW); ghost2->flags2 |= (mobj->player->followmobj->flags2 & MF2_LINKDRAW);
} }
@ -8741,7 +8744,10 @@ void P_MovePlayer(player_t *player)
player->mo->height = P_GetPlayerHeight(player); player->mo->height = P_GetPlayerHeight(player);
if (player->mo->eflags & MFE_VERTICALFLIP && player->mo->height != oldheight) // adjust z height for reverse gravity, similar to how it's done for scaling if (player->mo->eflags & MFE_VERTICALFLIP && player->mo->height != oldheight) // adjust z height for reverse gravity, similar to how it's done for scaling
{
player->mo->z -= player->mo->height - oldheight; player->mo->z -= player->mo->height - oldheight;
player->mo->old_z -= player->mo->height - oldheight; // Snap the Z adjustment, while keeping the Z interpolation
}
// Crush test... // Crush test...
if ((player->mo->ceilingz - player->mo->floorz < player->mo->height) if ((player->mo->ceilingz - player->mo->floorz < player->mo->height)
@ -11506,7 +11512,7 @@ static void P_DoMetalJetFume(player_t *player, mobj_t *fume)
} }
fume->movecount = dashmode; // keeps track of previous dashmode value so we know whether Metal is entering or leaving it fume->movecount = dashmode; // keeps track of previous dashmode value so we know whether Metal is entering or leaving it
fume->eflags = (fume->flags2 & ~MF2_OBJECTFLIP) | (mo->flags2 & MF2_OBJECTFLIP); // Make sure to flip in reverse gravity! fume->flags2 = (fume->flags2 & ~MF2_OBJECTFLIP) | (mo->flags2 & MF2_OBJECTFLIP); // Make sure to flip in reverse gravity!
fume->eflags = (fume->eflags & ~MFE_VERTICALFLIP) | (mo->eflags & MFE_VERTICALFLIP); // Make sure to flip in reverse gravity! fume->eflags = (fume->eflags & ~MFE_VERTICALFLIP) | (mo->eflags & MFE_VERTICALFLIP); // Make sure to flip in reverse gravity!
// Finally, set its position // Finally, set its position
@ -11757,7 +11763,7 @@ void P_PlayerThink(player_t *player)
if (!total || ((4*exiting)/total) >= numneeded) if (!total || ((4*exiting)/total) >= numneeded)
{ {
if (server) if (server)
SendNetXCmd(XD_EXITLEVEL, NULL, 0); D_SendExitLevel(false);
} }
else else
player->exiting = 3; player->exiting = 3;
@ -11765,7 +11771,7 @@ void P_PlayerThink(player_t *player)
else else
{ {
if (server) if (server)
SendNetXCmd(XD_EXITLEVEL, NULL, 0); D_SendExitLevel(false);
} }
} }
@ -11863,7 +11869,7 @@ void P_PlayerThink(player_t *player)
mo2 = (mobj_t *)th; mo2 = (mobj_t *)th;
if (!(mo2->type == MT_RING || mo2->type == MT_COIN if (!(mo2->type == MT_RING || mo2->type == MT_COIN
|| mo2->type == MT_BLUESPHERE || mo2->type == MT_BOMBSPHERE || mo2->type == MT_BLUESPHERE // || mo2->type == MT_BOMBSPHERE
|| mo2->type == MT_NIGHTSCHIP || mo2->type == MT_NIGHTSSTAR)) || mo2->type == MT_NIGHTSCHIP || mo2->type == MT_NIGHTSSTAR))
continue; continue;

View file

@ -34,7 +34,7 @@ static CV_PossibleValue_t renderhitbox_cons_t[] = {
{RENDERHITBOX_RINGS, "Rings"}, {RENDERHITBOX_RINGS, "Rings"},
{0}}; {0}};
consvar_t cv_renderhitbox = CVAR_INIT ("renderhitbox", "Off", CV_CHEAT, renderhitbox_cons_t, NULL); consvar_t cv_renderhitbox = CVAR_INIT ("renderhitbox", "Off", CV_CHEAT|CV_NOTINNET, renderhitbox_cons_t, NULL);
consvar_t cv_renderhitboxinterpolation = CVAR_INIT ("renderhitbox_interpolation", "On", CV_SAVE, CV_OnOff, NULL); consvar_t cv_renderhitboxinterpolation = CVAR_INIT ("renderhitbox_interpolation", "On", CV_SAVE, CV_OnOff, NULL);
consvar_t cv_renderhitboxgldepth = CVAR_INIT ("renderhitbox_gldepth", "Off", CV_SAVE, CV_OnOff, NULL); consvar_t cv_renderhitboxgldepth = CVAR_INIT ("renderhitbox_gldepth", "Off", CV_SAVE, CV_OnOff, NULL);
@ -268,6 +268,9 @@ boolean R_ThingBoundingBoxVisible(mobj_t *thing)
{ {
INT32 cvmode = cv_renderhitbox.value; INT32 cvmode = cv_renderhitbox.value;
if (multiplayer) // No hitboxes in multiplayer to avoid cheating
return false;
// Do not render bbox for these // Do not render bbox for these
switch (thing->type) switch (thing->type)
{ {

View file

@ -758,12 +758,12 @@ typedef struct drawseg_s
// Pointers to lists for sprite clipping, all three adjusted so [x1] is first value. // Pointers to lists for sprite clipping, all three adjusted so [x1] is first value.
INT16 *sprtopclip; INT16 *sprtopclip;
INT16 *sprbottomclip; INT16 *sprbottomclip;
INT16 *maskedtexturecol; fixed_t *maskedtexturecol;
struct visplane_s *ffloorplanes[MAXFFLOORS]; struct visplane_s *ffloorplanes[MAXFFLOORS];
INT32 numffloorplanes; INT32 numffloorplanes;
struct ffloor_s *thicksides[MAXFFLOORS]; struct ffloor_s *thicksides[MAXFFLOORS];
INT16 *thicksidecol; fixed_t *thicksidecol;
INT32 numthicksides; INT32 numthicksides;
fixed_t frontscale[MAXVIDWIDTH]; fixed_t frontscale[MAXVIDWIDTH];

View file

@ -292,6 +292,8 @@ void R_InterpolateMobjState(mobj_t *mobj, fixed_t frac, interpmobjstate_t *out)
out->y = mobj->y; out->y = mobj->y;
out->z = mobj->z; out->z = mobj->z;
out->scale = mobj->scale; out->scale = mobj->scale;
out->radius = mobj->radius;
out->height = mobj->height;
out->subsector = mobj->subsector; out->subsector = mobj->subsector;
out->angle = mobj->player ? mobj->player->drawangle : mobj->angle; out->angle = mobj->player ? mobj->player->drawangle : mobj->angle;
out->pitch = mobj->pitch; out->pitch = mobj->pitch;
@ -307,10 +309,22 @@ void R_InterpolateMobjState(mobj_t *mobj, fixed_t frac, interpmobjstate_t *out)
out->x = R_LerpFixed(mobj->old_x, mobj->x, frac); out->x = R_LerpFixed(mobj->old_x, mobj->x, frac);
out->y = R_LerpFixed(mobj->old_y, mobj->y, frac); out->y = R_LerpFixed(mobj->old_y, mobj->y, frac);
out->z = R_LerpFixed(mobj->old_z, mobj->z, frac); out->z = R_LerpFixed(mobj->old_z, mobj->z, frac);
out->scale = mobj->resetinterp ? mobj->scale : R_LerpFixed(mobj->old_scale, mobj->scale, frac);
out->spritexscale = mobj->resetinterp ? mobj->spritexscale : R_LerpFixed(mobj->old_spritexscale, mobj->spritexscale, frac); out->spritexscale = mobj->resetinterp ? mobj->spritexscale : R_LerpFixed(mobj->old_spritexscale, mobj->spritexscale, frac);
out->spriteyscale = mobj->resetinterp ? mobj->spriteyscale : R_LerpFixed(mobj->old_spriteyscale, mobj->spriteyscale, frac); out->spriteyscale = mobj->resetinterp ? mobj->spriteyscale : R_LerpFixed(mobj->old_spriteyscale, mobj->spriteyscale, frac);
if (mobj->scale == mobj->old_scale) // Tiny optimisation - scale is usually unchanging, so let's skip a lerp, two FixedMuls, and two FixedDivs
{
out->scale = mobj->scale;
out->radius = mobj->radius;
out->height = mobj->height;
}
else
{
out->scale = R_LerpFixed(mobj->old_scale, mobj->scale, frac);
out->radius = FixedMul(mobj->radius, FixedDiv(out->scale, mobj->scale));
out->height = FixedMul(mobj->height, FixedDiv(out->scale, mobj->scale));
}
// Sprite offsets are not interpolated until we have a way to interpolate them explicitly in Lua. // Sprite offsets are not interpolated until we have a way to interpolate them explicitly in Lua.
// It seems existing mods visually break more often than not if it is interpolated. // It seems existing mods visually break more often than not if it is interpolated.
out->spritexoffset = mobj->spritexoffset; out->spritexoffset = mobj->spritexoffset;
@ -340,6 +354,8 @@ void R_InterpolatePrecipMobjState(precipmobj_t *mobj, fixed_t frac, interpmobjst
out->y = mobj->y; out->y = mobj->y;
out->z = mobj->z; out->z = mobj->z;
out->scale = FRACUNIT; out->scale = FRACUNIT;
out->radius = mobj->radius;
out->height = mobj->height;
out->subsector = mobj->subsector; out->subsector = mobj->subsector;
out->angle = mobj->angle; out->angle = mobj->angle;
out->pitch = mobj->angle; out->pitch = mobj->angle;
@ -356,6 +372,8 @@ void R_InterpolatePrecipMobjState(precipmobj_t *mobj, fixed_t frac, interpmobjst
out->y = R_LerpFixed(mobj->old_y, mobj->y, frac); out->y = R_LerpFixed(mobj->old_y, mobj->y, frac);
out->z = R_LerpFixed(mobj->old_z, mobj->z, frac); out->z = R_LerpFixed(mobj->old_z, mobj->z, frac);
out->scale = FRACUNIT; out->scale = FRACUNIT;
out->radius = mobj->radius;
out->height = mobj->height;
out->spritexscale = R_LerpFixed(mobj->old_spritexscale, mobj->spritexscale, frac); out->spritexscale = R_LerpFixed(mobj->old_spritexscale, mobj->spritexscale, frac);
out->spriteyscale = R_LerpFixed(mobj->old_spriteyscale, mobj->spriteyscale, frac); out->spriteyscale = R_LerpFixed(mobj->old_spriteyscale, mobj->spriteyscale, frac);
out->spritexoffset = R_LerpFixed(mobj->old_spritexoffset, mobj->spritexoffset, frac); out->spritexoffset = R_LerpFixed(mobj->old_spritexoffset, mobj->spritexoffset, frac);

View file

@ -63,6 +63,8 @@ typedef struct {
angle_t roll; angle_t roll;
angle_t spriteroll; angle_t spriteroll;
fixed_t scale; fixed_t scale;
fixed_t radius;
fixed_t height;
fixed_t spritexscale; fixed_t spritexscale;
fixed_t spriteyscale; fixed_t spriteyscale;
fixed_t spritexoffset; fixed_t spritexoffset;

View file

@ -41,16 +41,6 @@
#include "hardware/hw_main.h" #include "hardware/hw_main.h"
#endif #endif
//profile stuff ---------------------------------------------------------
//#define TIMING
#ifdef TIMING
#include "p5prof.h"
INT64 mycount;
INT64 mytotal = 0;
//unsigned long nombre = 100000;
#endif
//profile stuff ---------------------------------------------------------
// Fineangles in the SCREENWIDTH wide window. // Fineangles in the SCREENWIDTH wide window.
#define FIELDOFVIEW 2048 #define FIELDOFVIEW 2048
@ -157,7 +147,8 @@ consvar_t cv_flipcam2 = CVAR_INIT ("flipcam2", "No", CV_SAVE|CV_CALL|CV_NOINIT,
consvar_t cv_shadow = CVAR_INIT ("shadow", "On", CV_SAVE, CV_OnOff, NULL); consvar_t cv_shadow = CVAR_INIT ("shadow", "On", CV_SAVE, CV_OnOff, NULL);
consvar_t cv_skybox = CVAR_INIT ("skybox", "On", CV_SAVE, CV_OnOff, NULL); consvar_t cv_skybox = CVAR_INIT ("skybox", "On", CV_SAVE, CV_OnOff, NULL);
consvar_t cv_ffloorclip = CVAR_INIT ("ffloorclip", "On", CV_SAVE, CV_OnOff, NULL); consvar_t cv_ffloorclip = CVAR_INIT ("r_ffloorclip", "On", CV_SAVE, CV_OnOff, NULL);
consvar_t cv_spriteclip = CVAR_INIT ("r_spriteclip", "On", CV_SAVE, CV_OnOff, NULL);
consvar_t cv_allowmlook = CVAR_INIT ("allowmlook", "Yes", CV_NETVAR|CV_ALLOWLUA, CV_YesNo, NULL); consvar_t cv_allowmlook = CVAR_INIT ("allowmlook", "Yes", CV_NETVAR|CV_ALLOWLUA, CV_YesNo, NULL);
consvar_t cv_showhud = CVAR_INIT ("showhud", "Yes", CV_CALL|CV_ALLOWLUA, CV_YesNo, R_SetViewSize); consvar_t cv_showhud = CVAR_INIT ("showhud", "Yes", CV_CALL|CV_ALLOWLUA, CV_YesNo, R_SetViewSize);
consvar_t cv_translucenthud = CVAR_INIT ("translucenthud", "10", CV_SAVE, translucenthud_cons_t, NULL); consvar_t cv_translucenthud = CVAR_INIT ("translucenthud", "10", CV_SAVE, translucenthud_cons_t, NULL);
@ -1479,6 +1470,7 @@ void R_RenderPlayerView(player_t *player)
R_ClearClipSegs(); R_ClearClipSegs();
} }
R_ClearDrawSegs(); R_ClearDrawSegs();
R_ClearSegTables();
R_ClearSprites(); R_ClearSprites();
Portal_InitList(); Portal_InitList();
@ -1489,29 +1481,17 @@ void R_RenderPlayerView(player_t *player)
Mask_Pre(&masks[nummasks - 1]); Mask_Pre(&masks[nummasks - 1]);
curdrawsegs = ds_p; curdrawsegs = ds_p;
//profile stuff ---------------------------------------------------------
#ifdef TIMING
mytotal = 0;
ProfZeroTimer();
#endif
ps_numbspcalls.value.i = ps_numpolyobjects.value.i = ps_numdrawnodes.value.i = 0; ps_numbspcalls.value.i = ps_numpolyobjects.value.i = ps_numdrawnodes.value.i = 0;
PS_START_TIMING(ps_bsptime); PS_START_TIMING(ps_bsptime);
R_RenderBSPNode((INT32)numnodes - 1); R_RenderBSPNode((INT32)numnodes - 1);
PS_STOP_TIMING(ps_bsptime); PS_STOP_TIMING(ps_bsptime);
ps_numsprites.value.i = visspritecount;
#ifdef TIMING
RDMSR(0x10, &mycount);
mytotal += mycount; // 64bit add
CONS_Debug(DBG_RENDER, "RenderBSPNode: 0x%d %d\n", *((INT32 *)&mytotal + 1), (INT32)mytotal);
#endif
//profile stuff ---------------------------------------------------------
Mask_Post(&masks[nummasks - 1]); Mask_Post(&masks[nummasks - 1]);
PS_START_TIMING(ps_sw_spritecliptime); PS_START_TIMING(ps_sw_spritecliptime);
R_ClipSprites(drawsegs, NULL); R_ClipSprites(drawsegs, NULL);
PS_STOP_TIMING(ps_sw_spritecliptime); PS_STOP_TIMING(ps_sw_spritecliptime);
ps_numsprites.value.i = numvisiblesprites;
// Add skybox portals caused by sky visplanes. // Add skybox portals caused by sky visplanes.
if (cv_skybox.value && skyboxmo[0]) if (cv_skybox.value && skyboxmo[0])
@ -1602,6 +1582,7 @@ void R_RegisterEngineStuff(void)
CV_RegisterVar(&cv_shadow); CV_RegisterVar(&cv_shadow);
CV_RegisterVar(&cv_skybox); CV_RegisterVar(&cv_skybox);
CV_RegisterVar(&cv_ffloorclip); CV_RegisterVar(&cv_ffloorclip);
CV_RegisterVar(&cv_spriteclip);
CV_RegisterVar(&cv_cam_dist); CV_RegisterVar(&cv_cam_dist);
CV_RegisterVar(&cv_cam_still); CV_RegisterVar(&cv_cam_still);

View file

@ -114,7 +114,7 @@ extern consvar_t cv_chasecam, cv_chasecam2;
extern consvar_t cv_flipcam, cv_flipcam2; extern consvar_t cv_flipcam, cv_flipcam2;
extern consvar_t cv_shadow; extern consvar_t cv_shadow;
extern consvar_t cv_ffloorclip; extern consvar_t cv_ffloorclip, cv_spriteclip;
extern consvar_t cv_translucency; extern consvar_t cv_translucency;
extern consvar_t cv_drawdist, cv_drawdist_nights, cv_drawdist_precip; extern consvar_t cv_drawdist, cv_drawdist_nights, cv_drawdist_precip;
extern consvar_t cv_fov; extern consvar_t cv_fov;

View file

@ -53,10 +53,6 @@ INT32 numffloors;
#define visplane_hash(picnum,lightlevel,height) \ #define visplane_hash(picnum,lightlevel,height) \
((unsigned)((picnum)*3+(lightlevel)+(height)*7) & VISPLANEHASHMASK) ((unsigned)((picnum)*3+(lightlevel)+(height)*7) & VISPLANEHASHMASK)
//SoM: 3/23/2000: Use boom opening limit removal
size_t maxopenings;
INT16 *openings, *lastopening; /// \todo free leak
// //
// Clip values are the solid pixel bounding the range. // Clip values are the solid pixel bounding the range.
// floorclip starts out SCREENHEIGHT // floorclip starts out SCREENHEIGHT
@ -366,8 +362,6 @@ void R_ClearPlanes(void)
freehead = &(*freehead)->next; freehead = &(*freehead)->next;
} }
lastopening = openings;
// texture calculation // texture calculation
memset(cachedheight, 0, sizeof (cachedheight)); memset(cachedheight, 0, sizeof (cachedheight));
} }

View file

@ -60,9 +60,6 @@ extern visplane_t *floorplane;
extern visplane_t *ceilingplane; extern visplane_t *ceilingplane;
// Visplane related. // Visplane related.
extern INT16 *lastopening, *openings;
extern size_t maxopenings;
extern INT16 floorclip[MAXVIDWIDTH], ceilingclip[MAXVIDWIDTH]; extern INT16 floorclip[MAXVIDWIDTH], ceilingclip[MAXVIDWIDTH];
extern fixed_t frontscale[MAXVIDWIDTH], yslopetab[MAXVIDHEIGHT*16]; extern fixed_t frontscale[MAXVIDWIDTH], yslopetab[MAXVIDHEIGHT*16];
extern fixed_t cachedheight[MAXVIDHEIGHT]; extern fixed_t cachedheight[MAXVIDHEIGHT];

View file

@ -71,9 +71,22 @@ static fixed_t topfrac, topstep;
static fixed_t bottomfrac, bottomstep; static fixed_t bottomfrac, bottomstep;
static lighttable_t **walllights; static lighttable_t **walllights;
static INT16 *maskedtexturecol; static fixed_t *maskedtexturecol;
static fixed_t *maskedtextureheight = NULL; static fixed_t *maskedtextureheight = NULL;
//SoM: 3/23/2000: Use boom opening limit removal
static size_t numopenings;
static INT16 *openings, *lastopening;
static size_t texturecolumntablesize;
static fixed_t *texturecolumntable, *curtexturecolumntable;
void R_ClearSegTables(void)
{
lastopening = openings;
curtexturecolumntable = texturecolumntable;
}
// ========================================================================== // ==========================================================================
// R_RenderMaskedSegRange // R_RenderMaskedSegRange
// ========================================================================== // ==========================================================================
@ -350,9 +363,7 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2)
dc_texturemid += (textureheight[texnum])*times + textureheight[texnum]; dc_texturemid += (textureheight[texnum])*times + textureheight[texnum];
else else
dc_texturemid -= (textureheight[texnum])*times; dc_texturemid -= (textureheight[texnum])*times;
// calculate lighting
if (maskedtexturecol[dc_x] != INT16_MAX)
{
// Check for overflows first // Check for overflows first
overflow_test = (INT64)centeryfrac - (((INT64)dc_texturemid*spryscale)>>FRACBITS); overflow_test = (INT64)centeryfrac - (((INT64)dc_texturemid*spryscale)>>FRACBITS);
if (overflow_test < 0) overflow_test = -overflow_test; if (overflow_test < 0) overflow_test = -overflow_test;
@ -371,6 +382,7 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2)
continue; continue;
} }
// calculate lighting
if (dc_numlights) if (dc_numlights)
{ {
lighttable_t **xwalllights; lighttable_t **xwalllights;
@ -382,7 +394,7 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2)
dc_iscale = 0xffffffffu / (unsigned)spryscale; dc_iscale = 0xffffffffu / (unsigned)spryscale;
// draw the texture // draw the texture
col = (column_t *)((UINT8 *)R_GetColumn(texnum, maskedtexturecol[dc_x]) - 3); col = (column_t *)((UINT8 *)R_GetColumn(texnum, (maskedtexturecol[dc_x] >> FRACBITS)) - 3);
for (i = 0; i < dc_numlights; i++) for (i = 0; i < dc_numlights; i++)
{ {
@ -457,63 +469,9 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2)
dc_iscale = 0xffffffffu / (unsigned)spryscale; dc_iscale = 0xffffffffu / (unsigned)spryscale;
// draw the texture // draw the texture
col = (column_t *)((UINT8 *)R_GetColumn(texnum, maskedtexturecol[dc_x]) - 3); col = (column_t *)((UINT8 *)R_GetColumn(texnum, (maskedtexturecol[dc_x] >> FRACBITS)) - 3);
#if 0 // Disabling this allows inside edges to render below the planes, for until the clipping is fixed to work right when POs are near the camera. -Red
if (curline->dontrenderme && curline->polyseg && (curline->polyseg->flags & POF_RENDERPLANES))
{
fixed_t my_topscreen;
fixed_t my_bottomscreen;
fixed_t my_yl, my_yh;
my_topscreen = sprtopscreen + spryscale*col->topdelta;
my_bottomscreen = sprbotscreen == INT32_MAX ? my_topscreen + spryscale*col->length
: sprbotscreen + spryscale*col->length;
my_yl = (my_topscreen+FRACUNIT-1)>>FRACBITS;
my_yh = (my_bottomscreen-1)>>FRACBITS;
// CONS_Debug(DBG_RENDER, "my_topscreen: %d\nmy_bottomscreen: %d\nmy_yl: %d\nmy_yh: %d\n", my_topscreen, my_bottomscreen, my_yl, my_yh);
if (numffloors)
{
INT32 top = my_yl;
INT32 bottom = my_yh;
for (i = 0; i < numffloors; i++)
{
if (!ffloor[i].polyobj || ffloor[i].polyobj != curline->polyseg)
continue;
if (ffloor[i].height < viewz)
{
INT32 top_w = ffloor[i].plane->top[dc_x];
// CONS_Debug(DBG_RENDER, "Leveltime : %d\n", leveltime);
// CONS_Debug(DBG_RENDER, "Top is %d, top_w is %d\n", top, top_w);
if (top_w < top)
{
ffloor[i].plane->top[dc_x] = (INT16)top;
ffloor[i].plane->picnum = 0;
}
// CONS_Debug(DBG_RENDER, "top_w is now %d\n", ffloor[i].plane->top[dc_x]);
}
else if (ffloor[i].height > viewz)
{
INT32 bottom_w = ffloor[i].plane->bottom[dc_x];
if (bottom_w > bottom)
{
ffloor[i].plane->bottom[dc_x] = (INT16)bottom;
ffloor[i].plane->picnum = 0;
}
}
}
}
}
else
#endif
colfunc_2s(col); colfunc_2s(col);
}
spryscale += rw_scalestep; spryscale += rw_scalestep;
} }
} }
@ -857,16 +815,16 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
// draw the columns // draw the columns
for (dc_x = x1; dc_x <= x2; dc_x++) for (dc_x = x1; dc_x <= x2; dc_x++)
{ {
if (maskedtexturecol[dc_x] != INT16_MAX) // skew FOF walls
if (ffloortextureslide)
{ {
if (ffloortextureslide) { // skew FOF walls
if (oldx != -1) if (oldx != -1)
dc_texturemid += FixedMul(ffloortextureslide, (maskedtexturecol[oldx]-maskedtexturecol[dc_x])<<FRACBITS); dc_texturemid += FixedMul(ffloortextureslide, maskedtexturecol[oldx]-maskedtexturecol[dc_x]);
oldx = dc_x; oldx = dc_x;
} }
// Calculate bounds // Calculate bounds
// clamp the values if necessary to avoid overflows and rendering glitches caused by them // clamp the values if necessary to avoid overflows and rendering glitches caused by them
if (top_frac > (INT64)CLAMPMAX) sprtopscreen = windowtop = CLAMPMAX; if (top_frac > (INT64)CLAMPMAX) sprtopscreen = windowtop = CLAMPMAX;
else if (top_frac > (INT64)CLAMPMIN) sprtopscreen = windowtop = (fixed_t)top_frac; else if (top_frac > (INT64)CLAMPMIN) sprtopscreen = windowtop = (fixed_t)top_frac;
else sprtopscreen = windowtop = CLAMPMIN; else sprtopscreen = windowtop = CLAMPMIN;
@ -897,7 +855,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
dc_iscale = 0xffffffffu / (unsigned)spryscale; dc_iscale = 0xffffffffu / (unsigned)spryscale;
// Get data for the column // Get data for the column
col = (column_t *)((UINT8 *)R_GetColumn(texnum,maskedtexturecol[dc_x]) - 3); col = (column_t *)((UINT8 *)R_GetColumn(texnum, (maskedtexturecol[dc_x] >> FRACBITS)) - 3);
// SoM: New code does not rely on R_DrawColumnShadowed_8 which // SoM: New code does not rely on R_DrawColumnShadowed_8 which
// will (hopefully) put less strain on the stack. // will (hopefully) put less strain on the stack.
@ -1034,7 +992,6 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
colfunc_2s (col); colfunc_2s (col);
spryscale += rw_scalestep; spryscale += rw_scalestep;
} }
}
colfunc = colfuncs[BASEDRAWFUNC]; colfunc = colfuncs[BASEDRAWFUNC];
#undef CLAMPMAX #undef CLAMPMAX
@ -1270,7 +1227,7 @@ static void R_RenderSegLoop (void)
} }
oldtexturecolumn = texturecolumn; oldtexturecolumn = texturecolumn;
texturecolumn >>= FRACBITS; INT32 itexturecolumn = texturecolumn >> FRACBITS;
// texturecolumn and lighting are independent of wall tiers // texturecolumn and lighting are independent of wall tiers
if (segtextured) if (segtextured)
@ -1336,7 +1293,7 @@ static void R_RenderSegLoop (void)
dc_yl = yl; dc_yl = yl;
dc_yh = yh; dc_yh = yh;
dc_texturemid = rw_midtexturemid; dc_texturemid = rw_midtexturemid;
dc_source = R_GetColumn(midtexture,texturecolumn + (rw_offset_mid>>FRACBITS)); dc_source = R_GetColumn(midtexture, itexturecolumn + (rw_offset_mid>>FRACBITS));
dc_texheight = textureheight[midtexture]>>FRACBITS; dc_texheight = textureheight[midtexture]>>FRACBITS;
//profile stuff --------------------------------------------------------- //profile stuff ---------------------------------------------------------
@ -1397,7 +1354,7 @@ static void R_RenderSegLoop (void)
dc_yl = yl; dc_yl = yl;
dc_yh = mid; dc_yh = mid;
dc_texturemid = rw_toptexturemid; dc_texturemid = rw_toptexturemid;
dc_source = R_GetColumn(toptexture,texturecolumn + (rw_offset_top>>FRACBITS)); dc_source = R_GetColumn(toptexture, itexturecolumn + (rw_offset_top>>FRACBITS));
dc_texheight = textureheight[toptexture]>>FRACBITS; dc_texheight = textureheight[toptexture]>>FRACBITS;
colfunc(); colfunc();
ceilingclip[rw_x] = (INT16)mid; ceilingclip[rw_x] = (INT16)mid;
@ -1433,8 +1390,7 @@ static void R_RenderSegLoop (void)
dc_yl = mid; dc_yl = mid;
dc_yh = yh; dc_yh = yh;
dc_texturemid = rw_bottomtexturemid; dc_texturemid = rw_bottomtexturemid;
dc_source = R_GetColumn(bottomtexture, dc_source = R_GetColumn(bottomtexture, itexturecolumn + (rw_offset_bot>>FRACBITS));
texturecolumn + (rw_offset_bot>>FRACBITS));
dc_texheight = textureheight[bottomtexture]>>FRACBITS; dc_texheight = textureheight[bottomtexture]>>FRACBITS;
colfunc(); colfunc();
floorclip[rw_x] = (INT16)mid; floorclip[rw_x] = (INT16)mid;
@ -1453,7 +1409,7 @@ static void R_RenderSegLoop (void)
{ {
// save texturecol // save texturecol
// for backdrawing of masked mid texture // for backdrawing of masked mid texture
maskedtexturecol[rw_x] = (INT16)(texturecolumn + (rw_offset_mid>>FRACBITS)); maskedtexturecol[rw_x] = texturecolumn + rw_offset_mid;
if (maskedtextureheight != NULL) { if (maskedtextureheight != NULL) {
maskedtextureheight[rw_x] = (curline->linedef->flags & ML_MIDPEG) ? maskedtextureheight[rw_x] = (curline->linedef->flags & ML_MIDPEG) ?
@ -1512,6 +1468,73 @@ static INT64 R_CalcSegDist(seg_t* seg, INT64 x2, INT64 y2)
} }
} }
//SoM: Code to remove limits on openings.
static void R_AllocClippingTables(size_t range)
{
size_t pos = lastopening - openings;
size_t need = range * 2; // for both sprtopclip and sprbottomclip
if (pos + need < numopenings)
return;
INT16 *oldopenings = openings;
INT16 *oldlast = lastopening;
if (numopenings == 0)
numopenings = 16384;
numopenings += need;
openings = Z_Realloc(openings, numopenings * sizeof (*openings), PU_STATIC, NULL);
lastopening = openings + pos;
if (oldopenings == NULL)
return;
// borrowed fix from *cough* zdoom *cough*
// [RH] We also need to adjust the openings pointers that
// were already stored in drawsegs.
for (drawseg_t *ds = drawsegs; ds < ds_p; ds++)
{
// Check if it's in range of the openings
if (ds->sprtopclip + ds->x1 >= oldopenings && ds->sprtopclip + ds->x1 <= oldlast)
ds->sprtopclip = (ds->sprtopclip - oldopenings) + openings;
if (ds->sprbottomclip + ds->x1 >= oldopenings && ds->sprbottomclip + ds->x1 <= oldlast)
ds->sprbottomclip = (ds->sprbottomclip - oldopenings) + openings;
}
}
static void R_AllocTextureColumnTables(size_t range)
{
size_t pos = curtexturecolumntable - texturecolumntable;
// For both tables, we reserve exactly an amount of memory that's equivalent to
// how many columns the seg will take on the entire screen (think about it)
if (pos + range < texturecolumntablesize)
return;
fixed_t *oldtable = texturecolumntable;
fixed_t *oldlast = curtexturecolumntable;
if (texturecolumntablesize == 0)
texturecolumntablesize = 16384;
texturecolumntablesize += range;
texturecolumntable = Z_Realloc(texturecolumntable, texturecolumntablesize * sizeof (*texturecolumntable), PU_STATIC, NULL);
curtexturecolumntable = texturecolumntable + pos;
if (oldtable == NULL)
return;
for (drawseg_t *ds = drawsegs; ds < ds_p; ds++)
{
// Check if it's in range of the tables
if (ds->maskedtexturecol + ds->x1 >= oldtable && ds->maskedtexturecol + ds->x1 <= oldlast)
ds->maskedtexturecol = (ds->maskedtexturecol - oldtable) + texturecolumntable;
if (ds->thicksidecol + ds->x1 >= oldtable && ds->thicksidecol + ds->x1 <= oldlast)
ds->thicksidecol = (ds->thicksidecol - oldtable) + texturecolumntable;
}
}
// //
// R_StoreWallRange // R_StoreWallRange
// A wall segment will be drawn // A wall segment will be drawn
@ -1580,37 +1603,6 @@ void R_StoreWallRange(INT32 start, INT32 stop)
ds_p->curline = curline; ds_p->curline = curline;
rw_stopx = stop+1; rw_stopx = stop+1;
//SoM: Code to remove limits on openings.
{
size_t pos = lastopening - openings;
size_t need = (rw_stopx - start)*4 + pos;
if (need > maxopenings)
{
drawseg_t *ds; //needed for fix from *cough* zdoom *cough*
INT16 *oldopenings = openings;
INT16 *oldlast = lastopening;
do
maxopenings = maxopenings ? maxopenings*2 : 16384;
while (need > maxopenings);
openings = Z_Realloc(openings, maxopenings * sizeof (*openings), PU_STATIC, NULL);
lastopening = openings + pos;
// borrowed fix from *cough* zdoom *cough*
// [RH] We also need to adjust the openings pointers that
// were already stored in drawsegs.
for (ds = drawsegs; ds < ds_p; ds++)
{
#define ADJUST(p) if (ds->p + ds->x1 >= oldopenings && ds->p + ds->x1 <= oldlast) ds->p = ds->p - oldopenings + openings;
ADJUST(maskedtexturecol);
ADJUST(sprtopclip);
ADJUST(sprbottomclip);
ADJUST(thicksidecol);
#undef ADJUST
}
}
} // end of code to remove limits on openings
// calculate scale at both ends and step // calculate scale at both ends and step
ds_p->scale1 = rw_scale = R_ScaleFromGlobalAngle(viewangle + xtoviewangle[start]); ds_p->scale1 = rw_scale = R_ScaleFromGlobalAngle(viewangle + xtoviewangle[start]);
@ -2026,6 +2018,8 @@ void R_StoreWallRange(INT32 start, INT32 stop)
rw_toptexturemid += sidedef->rowoffset + sidedef->offsety_top; rw_toptexturemid += sidedef->rowoffset + sidedef->offsety_top;
rw_bottomtexturemid += sidedef->rowoffset + sidedef->offsety_bot; rw_bottomtexturemid += sidedef->rowoffset + sidedef->offsety_bot;
R_AllocTextureColumnTables(rw_stopx - start);
// allocate space for masked texture tables // allocate space for masked texture tables
if (frontsector && backsector && !Tag_Compare(&frontsector->tags, &backsector->tags) && (backsector->ffloors || frontsector->ffloors)) if (frontsector && backsector && !Tag_Compare(&frontsector->tags, &backsector->tags) && (backsector->ffloors || frontsector->ffloors))
{ {
@ -2040,8 +2034,8 @@ void R_StoreWallRange(INT32 start, INT32 stop)
//markceiling = markfloor = true; //markceiling = markfloor = true;
maskedtexture = true; maskedtexture = true;
ds_p->thicksidecol = maskedtexturecol = lastopening - rw_x; ds_p->thicksidecol = maskedtexturecol = curtexturecolumntable - rw_x;
lastopening += rw_stopx - rw_x; curtexturecolumntable += rw_stopx - rw_x;
lowcut = max(worldbottom, worldlow) + viewz; lowcut = max(worldbottom, worldlow) + viewz;
highcut = min(worldtop, worldhigh) + viewz; highcut = min(worldtop, worldhigh) + viewz;
@ -2224,8 +2218,8 @@ void R_StoreWallRange(INT32 start, INT32 stop)
// masked midtexture // masked midtexture
if (!ds_p->thicksidecol) if (!ds_p->thicksidecol)
{ {
ds_p->maskedtexturecol = maskedtexturecol = lastopening - rw_x; ds_p->maskedtexturecol = maskedtexturecol = curtexturecolumntable - rw_x;
lastopening += rw_stopx - rw_x; curtexturecolumntable += rw_stopx - rw_x;
} }
else else
ds_p->maskedtexturecol = ds_p->thicksidecol; ds_p->maskedtexturecol = ds_p->thicksidecol;
@ -2737,6 +2731,10 @@ void R_StoreWallRange(INT32 start, INT32 stop)
ds_p->portalpass = 0; ds_p->portalpass = 0;
// save sprite clipping info // save sprite clipping info
if (maskedtexture || (ds_p->silhouette & (SIL_TOP | SIL_BOTTOM)))
{
R_AllocClippingTables(rw_stopx - start);
if (((ds_p->silhouette & SIL_TOP) || maskedtexture) && !ds_p->sprtopclip) if (((ds_p->silhouette & SIL_TOP) || maskedtexture) && !ds_p->sprtopclip)
{ {
M_Memcpy(lastopening, ceilingclip + start, 2*(rw_stopx - start)); M_Memcpy(lastopening, ceilingclip + start, 2*(rw_stopx - start));
@ -2750,6 +2748,7 @@ void R_StoreWallRange(INT32 start, INT32 stop)
ds_p->sprbottomclip = lastopening - start; ds_p->sprbottomclip = lastopening - start;
lastopening += rw_stopx - start; lastopening += rw_stopx - start;
} }
}
if (maskedtexture && !(ds_p->silhouette & SIL_TOP)) if (maskedtexture && !(ds_p->silhouette & SIL_TOP))
{ {

View file

@ -22,5 +22,6 @@ transnum_t R_GetLinedefTransTable(fixed_t alpha);
void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2); void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2);
void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pffloor); void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pffloor);
void R_StoreWallRange(INT32 start, INT32 stop); void R_StoreWallRange(INT32 start, INT32 stop);
void R_ClearSegTables(void);
#endif #endif

View file

@ -113,6 +113,7 @@ static void Sk_SetDefaultValue(skin_t *skin)
strcpy(skin->realname, "Someone"); strcpy(skin->realname, "Someone");
strcpy(skin->hudname, "???"); strcpy(skin->hudname, "???");
strcpy(skin->supername, "Someone super");
skin->starttranscolor = 96; skin->starttranscolor = 96;
skin->prefcolor = SKINCOLOR_GREEN; skin->prefcolor = SKINCOLOR_GREEN;
@ -682,7 +683,7 @@ void R_AddSkins(UINT16 wadnum, boolean mainfile)
char *value; char *value;
size_t size; size_t size;
skin_t *skin; skin_t *skin;
boolean hudname, realname; boolean hudname, realname, supername;
// //
// search for all skin markers in pwad // search for all skin markers in pwad
@ -712,7 +713,7 @@ void R_AddSkins(UINT16 wadnum, boolean mainfile)
skin = &skins[numskins]; skin = &skins[numskins];
Sk_SetDefaultValue(skin); Sk_SetDefaultValue(skin);
skin->wadnum = wadnum; skin->wadnum = wadnum;
hudname = realname = false; hudname = realname = supername = false;
// parse // parse
stoken = strtok (buf2, "\r\n= "); stoken = strtok (buf2, "\r\n= ");
while (stoken) while (stoken)
@ -755,7 +756,7 @@ void R_AddSkins(UINT16 wadnum, boolean mainfile)
Z_Free(value2); Z_Free(value2);
} }
// copy to hudname and fullname as a default. // copy to hudname, realname, and supername as a default.
if (!realname) if (!realname)
{ {
STRBUFCPY(skin->realname, skin->name); STRBUFCPY(skin->realname, skin->name);
@ -771,6 +772,19 @@ void R_AddSkins(UINT16 wadnum, boolean mainfile)
strupr(skin->hudname); strupr(skin->hudname);
SYMBOLCONVERT(skin->hudname) SYMBOLCONVERT(skin->hudname)
} }
if (!supername)
{
char superstring[SKINNAMESIZE+7];
strcpy(superstring, "Super ");
strlcat(superstring, skin->name, sizeof(superstring));
STRBUFCPY(skin->supername, superstring);
}
}
else if (!stricmp(stoken, "supername"))
{ // Super name (eg. "Super Knuckles")
supername = true;
STRBUFCPY(skin->supername, value);
SYMBOLCONVERT(skin->supername)
} }
else if (!stricmp(stoken, "realname")) else if (!stricmp(stoken, "realname"))
{ // Display name (eg. "Knuckles") { // Display name (eg. "Knuckles")
@ -779,6 +793,13 @@ void R_AddSkins(UINT16 wadnum, boolean mainfile)
SYMBOLCONVERT(skin->realname) SYMBOLCONVERT(skin->realname)
if (!hudname) if (!hudname)
HUDNAMEWRITE(skin->realname); HUDNAMEWRITE(skin->realname);
if (!supername) //copy over default to capitalise the name
{
char superstring[SKINNAMESIZE+7];
strcpy(superstring, "Super ");
strlcat(superstring, skin->realname, sizeof(superstring));
STRBUFCPY(skin->supername, superstring);
}
} }
else if (!stricmp(stoken, "hudname")) else if (!stricmp(stoken, "hudname"))
{ // Life icon name (eg. "K.T.E") { // Life icon name (eg. "K.T.E")
@ -831,7 +852,7 @@ void R_PatchSkins(UINT16 wadnum, boolean mainfile)
char *value; char *value;
size_t size; size_t size;
skin_t *skin; skin_t *skin;
boolean noskincomplain, realname, hudname; boolean noskincomplain, realname, hudname, supername;
// //
// search for all skin patch markers in pwad // search for all skin patch markers in pwad
@ -855,7 +876,7 @@ void R_PatchSkins(UINT16 wadnum, boolean mainfile)
buf2[size] = '\0'; buf2[size] = '\0';
skin = NULL; skin = NULL;
noskincomplain = realname = hudname = false; noskincomplain = realname = hudname = supername = false;
/* /*
Parse. Has more phases than the parser in R_AddSkins because it needs to have the patching name first (no default skin name is acceptible for patching, unlike skin creation) Parse. Has more phases than the parser in R_AddSkins because it needs to have the patching name first (no default skin name is acceptible for patching, unlike skin creation)
@ -894,13 +915,26 @@ void R_PatchSkins(UINT16 wadnum, boolean mainfile)
else // Get the properties! else // Get the properties!
{ {
// Some of these can't go in R_ProcessPatchableFields because they have side effects for future lines. // Some of these can't go in R_ProcessPatchableFields because they have side effects for future lines.
if (!stricmp(stoken, "realname")) if (!stricmp(stoken, "supername"))
{ // Super name (eg. "Super Knuckles")
supername = true;
STRBUFCPY(skin->supername, value);
SYMBOLCONVERT(skin->supername)
}
else if (!stricmp(stoken, "realname"))
{ // Display name (eg. "Knuckles") { // Display name (eg. "Knuckles")
realname = true; realname = true;
STRBUFCPY(skin->realname, value); STRBUFCPY(skin->realname, value);
SYMBOLCONVERT(skin->realname) SYMBOLCONVERT(skin->realname)
if (!hudname) if (!hudname)
HUDNAMEWRITE(skin->realname); HUDNAMEWRITE(skin->realname);
if (!supername) //copy over default to capitalise the name
{
char superstring[SKINNAMESIZE+7];
strcpy(superstring, "Super ");
strlcat(superstring, skin->realname, sizeof(superstring));
STRBUFCPY(skin->supername, superstring);
}
} }
else if (!stricmp(stoken, "hudname")) else if (!stricmp(stoken, "hudname"))
{ // Life icon name (eg. "K.T.E") { // Life icon name (eg. "K.T.E")

View file

@ -35,8 +35,9 @@ typedef struct
UINT16 wadnum; UINT16 wadnum;
skinflags_t flags; skinflags_t flags;
char realname[SKINNAMESIZE+1]; // Display name for level completion. char realname[SKINNAMESIZE+1]; // Display name for level completion
char hudname[SKINNAMESIZE+1]; // HUD name to display (officially exactly 5 characters long) char hudname[SKINNAMESIZE+1]; // HUD name to display (officially exactly 5 characters long)
char supername[SKINNAMESIZE+7]; // Super name to display when collecting all emeralds
UINT8 ability; // ability definition UINT8 ability; // ability definition
UINT8 ability2; // secondary ability definition UINT8 ability2; // secondary ability definition

View file

@ -314,9 +314,7 @@ static void R_RasterizeFloorSplat(floorsplat_t *pSplat, vector2_t *verts, visspr
fixed_t planeheight = 0; fixed_t planeheight = 0;
fixed_t step; fixed_t step;
int spanfunctype = SPANDRAWFUNC_SPRITE; int spanfunctype;
prepare_rastertab();
#define RASTERPARAMS(vnum1, vnum2, tv1, tv2, tc, dir) \ #define RASTERPARAMS(vnum1, vnum2, tv1, tv2, tc, dir) \
x1 = verts[vnum1].x; \ x1 = verts[vnum1].x; \
@ -367,21 +365,15 @@ static void R_RasterizeFloorSplat(floorsplat_t *pSplat, vector2_t *verts, visspr
if (ry1 > maxy) \ if (ry1 > maxy) \
maxy = ry1; maxy = ry1;
// do segment a -> top of texture
RASTERPARAMS(3,2,0,pSplat->width-1,0,0);
// do segment b -> right side of texture
RASTERPARAMS(2,1,0,pSplat->width-1,pSplat->height-1,0);
// do segment c -> bottom of texture
RASTERPARAMS(1,0,pSplat->width-1,0,pSplat->height-1,0);
// do segment d -> left side of texture
RASTERPARAMS(0,3,pSplat->width-1,0,0,1);
ds_source = (UINT8 *)pSplat->pic; ds_source = (UINT8 *)pSplat->pic;
ds_flatwidth = pSplat->width; ds_flatwidth = pSplat->width;
ds_flatheight = pSplat->height; ds_flatheight = pSplat->height;
ds_powersoftwo = false;
if (R_CheckPowersOfTwo()) ds_powersoftwo = ds_solidcolor = false;
if (R_CheckSolidColorFlat())
ds_solidcolor = true;
else if (R_CheckPowersOfTwo())
{ {
R_SetFlatVars(ds_flatwidth * ds_flatheight); R_SetFlatVars(ds_flatwidth * ds_flatheight);
ds_powersoftwo = true; ds_powersoftwo = true;
@ -392,9 +384,8 @@ static void R_RasterizeFloorSplat(floorsplat_t *pSplat, vector2_t *verts, visspr
R_SetTiltedSpan(0); R_SetTiltedSpan(0);
R_SetScaledSlopePlane(pSplat->slope, vis->viewpoint.x, vis->viewpoint.y, vis->viewpoint.z, pSplat->xscale, pSplat->yscale, -pSplat->verts[0].x, pSplat->verts[0].y, vis->viewpoint.angle, pSplat->angle); R_SetScaledSlopePlane(pSplat->slope, vis->viewpoint.x, vis->viewpoint.y, vis->viewpoint.z, pSplat->xscale, pSplat->yscale, -pSplat->verts[0].x, pSplat->verts[0].y, vis->viewpoint.angle, pSplat->angle);
R_CalculateSlopeVectors(); R_CalculateSlopeVectors();
spanfunctype = SPANDRAWFUNC_TILTEDSPRITE;
} }
else else if (!ds_solidcolor)
{ {
planeheight = abs(pSplat->z - vis->viewpoint.z); planeheight = abs(pSplat->z - vis->viewpoint.z);
@ -429,23 +420,70 @@ static void R_RasterizeFloorSplat(floorsplat_t *pSplat, vector2_t *verts, visspr
ds_colormap = &vis->extra_colormap->colormap[ds_colormap - colormaps]; ds_colormap = &vis->extra_colormap->colormap[ds_colormap - colormaps];
} }
if (vis->transmap)
{
ds_transmap = vis->transmap; ds_transmap = vis->transmap;
// Determine which R_DrawWhatever to use
// Solid color
if (ds_solidcolor)
{
UINT16 px = *(UINT16 *)ds_source;
// Uh, it's not visible.
if (!(px & 0xFF00))
return;
// Pixel color is contained in the lower 8 bits (upper 8 are the opacity), so advance the pointer
ds_source++;
if (pSplat->slope)
{
if (ds_transmap)
spanfunctype = SPANDRAWFUNC_TILTEDTRANSSOLID;
else
spanfunctype = SPANDRAWFUNC_TILTEDSOLID;
}
else
{
if (ds_transmap)
spanfunctype = SPANDRAWFUNC_TRANSSOLID;
else
spanfunctype = SPANDRAWFUNC_SOLID;
}
}
// Transparent
else if (ds_transmap)
{
if (pSplat->slope) if (pSplat->slope)
spanfunctype = SPANDRAWFUNC_TILTEDTRANSSPRITE; spanfunctype = SPANDRAWFUNC_TILTEDTRANSSPRITE;
else else
spanfunctype = SPANDRAWFUNC_TRANSSPRITE; spanfunctype = SPANDRAWFUNC_TRANSSPRITE;
} }
// Opaque
else else
ds_transmap = NULL; {
if (pSplat->slope)
spanfunctype = SPANDRAWFUNC_TILTEDSPRITE;
else
spanfunctype = SPANDRAWFUNC_SPRITE;
}
if (ds_powersoftwo) if (ds_powersoftwo || ds_solidcolor)
spanfunc = spanfuncs[spanfunctype]; spanfunc = spanfuncs[spanfunctype];
else else
spanfunc = spanfuncs_npo2[spanfunctype]; spanfunc = spanfuncs_npo2[spanfunctype];
prepare_rastertab();
// do segment a -> top of texture
RASTERPARAMS(3,2,0,pSplat->width-1,0,0);
// do segment b -> right side of texture
RASTERPARAMS(2,1,0,pSplat->width-1,pSplat->height-1,0);
// do segment c -> bottom of texture
RASTERPARAMS(1,0,pSplat->width-1,0,pSplat->height-1,0);
// do segment d -> left side of texture
RASTERPARAMS(0,3,pSplat->width-1,0,0,1);
if (maxy >= vid.height) if (maxy >= vid.height)
maxy = vid.height-1; maxy = vid.height-1;
@ -500,7 +538,7 @@ static void R_RasterizeFloorSplat(floorsplat_t *pSplat, vector2_t *verts, visspr
if (x2 < x1) if (x2 < x1)
continue; continue;
if (!pSplat->slope) if (!ds_solidcolor && !pSplat->slope)
{ {
fixed_t xstep, ystep; fixed_t xstep, ystep;
fixed_t distance, span; fixed_t distance, span;
@ -549,7 +587,7 @@ static void R_RasterizeFloorSplat(floorsplat_t *pSplat, vector2_t *verts, visspr
rastertab[y].maxx = INT32_MIN; rastertab[y].maxx = INT32_MIN;
} }
if (pSplat->angle && !pSplat->slope) if (!ds_solidcolor && pSplat->angle && !pSplat->slope)
memset(cachedheight, 0, sizeof(cachedheight)); memset(cachedheight, 0, sizeof(cachedheight));
} }

View file

@ -524,7 +524,8 @@ void R_AddSpriteDefs(UINT16 wadnum)
// //
// GAME FUNCTIONS // GAME FUNCTIONS
// //
UINT32 visspritecount; UINT32 visspritecount, numvisiblesprites;
static UINT32 clippedvissprites; static UINT32 clippedvissprites;
static vissprite_t *visspritechunks[MAXVISSPRITES >> VISSPRITECHUNKBITS] = {NULL}; static vissprite_t *visspritechunks[MAXVISSPRITES >> VISSPRITECHUNKBITS] = {NULL};
@ -598,7 +599,7 @@ void R_InitSprites(void)
// //
void R_ClearSprites(void) void R_ClearSprites(void)
{ {
visspritecount = clippedvissprites = 0; visspritecount = numvisiblesprites = clippedvissprites = 0;
} }
// //
@ -844,6 +845,15 @@ static void R_DrawVisSprite(vissprite_t *vis)
if ((UINT64)overflow_test&0xFFFFFFFF80000000ULL) return; // ditto if ((UINT64)overflow_test&0xFFFFFFFF80000000ULL) return; // ditto
} }
// TODO This check should not be necessary. But Papersprites near to the camera will sometimes create invalid values
// for the vissprite's startfrac. This happens because they are not depth culled like other sprites.
// Someone who is more familiar with papersprites pls check and try to fix <3
if (vis->startfrac < 0 || vis->startfrac > (patch->width << FRACBITS))
{
// never draw vissprites with startfrac out of patch range
return;
}
colfunc = colfuncs[BASEDRAWFUNC]; // hack: this isn't resetting properly somewhere. colfunc = colfuncs[BASEDRAWFUNC]; // hack: this isn't resetting properly somewhere.
dc_colormap = vis->colormap; dc_colormap = vis->colormap;
dc_translation = R_GetSpriteTranslation(vis); dc_translation = R_GetSpriteTranslation(vis);
@ -887,7 +897,7 @@ static void R_DrawVisSprite(vissprite_t *vis)
frac = vis->startfrac; frac = vis->startfrac;
windowtop = windowbottom = sprbotscreen = INT32_MAX; windowtop = windowbottom = sprbotscreen = INT32_MAX;
if (!(vis->cut & SC_PRECIP) && vis->mobj->skin && ((skin_t *)vis->mobj->skin)->flags & SF_HIRES) if (vis->cut & SC_SHADOW && vis->mobj->skin && ((skin_t *)vis->mobj->skin)->flags & SF_HIRES)
this_scale = FixedMul(this_scale, ((skin_t *)vis->mobj->skin)->highresscale); this_scale = FixedMul(this_scale, ((skin_t *)vis->mobj->skin)->highresscale);
if (this_scale <= 0) if (this_scale <= 0)
this_scale = 1; this_scale = 1;
@ -1184,7 +1194,7 @@ fixed_t R_GetShadowZ(mobj_t *thing, pslope_t **shadowslope)
R_InterpolateMobjState(thing, FRACUNIT, &interp); R_InterpolateMobjState(thing, FRACUNIT, &interp);
} }
halfHeight = interp.z + (thing->height >> 1); halfHeight = interp.z + (interp.height >> 1);
floorz = P_GetFloorZ(thing, interp.subsector->sector, interp.x, interp.y, NULL); floorz = P_GetFloorZ(thing, interp.subsector->sector, interp.x, interp.y, NULL);
ceilingz = P_GetCeilingZ(thing, interp.subsector->sector, interp.x, interp.y, NULL); ceilingz = P_GetCeilingZ(thing, interp.subsector->sector, interp.x, interp.y, NULL);
@ -1248,8 +1258,8 @@ fixed_t R_GetShadowZ(mobj_t *thing, pslope_t **shadowslope)
} }
} }
if (isflipped ? (ceilingz < groundz - (!groundslope ? 0 : FixedMul(abs(groundslope->zdelta), thing->radius*3/2))) if (isflipped ? (ceilingz < groundz - (!groundslope ? 0 : FixedMul(abs(groundslope->zdelta), interp.radius*3/2)))
: (floorz > groundz + (!groundslope ? 0 : FixedMul(abs(groundslope->zdelta), thing->radius*3/2)))) : (floorz > groundz + (!groundslope ? 0 : FixedMul(abs(groundslope->zdelta), interp.radius*3/2))))
{ {
groundz = isflipped ? ceilingz : floorz; groundz = isflipped ? ceilingz : floorz;
groundslope = NULL; groundslope = NULL;
@ -1292,9 +1302,9 @@ static void R_SkewShadowSprite(
//CONS_Printf("Shadow is sloped by %d %d\n", xslope, zslope); //CONS_Printf("Shadow is sloped by %d %d\n", xslope, zslope);
if (viewz < groundz) if (viewz < groundz)
*shadowyscale += FixedMul(FixedMul(thing->radius*2 / spriteheight, scalemul), zslope); *shadowyscale += FixedMul(FixedMul(interp.radius*2 / spriteheight, scalemul), zslope);
else else
*shadowyscale -= FixedMul(FixedMul(thing->radius*2 / spriteheight, scalemul), zslope); *shadowyscale -= FixedMul(FixedMul(interp.radius*2 / spriteheight, scalemul), zslope);
*shadowyscale = abs((*shadowyscale)); *shadowyscale = abs((*shadowyscale));
*shadowskew = xslope; *shadowskew = xslope;
@ -1345,20 +1355,18 @@ static void R_ProjectDropShadow(mobj_t *thing, vissprite_t *vis, fixed_t scale,
return; return;
} }
floordiff = abs((isflipped ? thing->height : 0) + interp.z - groundz); floordiff = abs((isflipped ? interp.height : 0) + interp.z - groundz);
trans = floordiff / (100*FRACUNIT) + 3; trans = floordiff / (100*FRACUNIT) + 3;
if (trans >= 9) return; if (trans >= 9) return;
scalemul = FixedMul(FRACUNIT - floordiff/640, scale); scalemul = FixedMul(FRACUNIT - floordiff/640, scale);
if ((thing->scale != thing->old_scale) && (thing->scale >= FRACUNIT/1024)) // Interpolate shadows when scaling mobjs
scalemul = FixedMul(scalemul, FixedDiv(interp.scale, thing->scale));
patch = W_CachePatchName("DSHADOW", PU_SPRITE); patch = W_CachePatchName("DSHADOW", PU_SPRITE);
xscale = FixedDiv(projection, tz); xscale = FixedDiv(projection, tz);
yscale = FixedDiv(projectiony, tz); yscale = FixedDiv(projectiony, tz);
shadowxscale = FixedMul(thing->radius*2, scalemul); shadowxscale = FixedMul(interp.radius*2, scalemul);
shadowyscale = FixedMul(FixedMul(thing->radius*2, scalemul), FixedDiv(abs(groundz - viewz), tz)); shadowyscale = FixedMul(FixedMul(interp.radius*2, scalemul), FixedDiv(abs(groundz - viewz), tz));
shadowyscale = min(shadowyscale, shadowxscale) / patch->height; shadowyscale = min(shadowyscale, shadowxscale) / patch->height;
shadowxscale /= patch->width; shadowxscale /= patch->width;
shadowskew = 0; shadowskew = 0;
@ -1484,8 +1492,8 @@ static void R_ProjectBoundingBox(mobj_t *thing, vissprite_t *vis)
// 0--2 // 0--2
// start in the (0) corner // start in the (0) corner
gx = interp.x - thing->radius - viewx; gx = interp.x - interp.radius - viewx;
gy = interp.y - thing->radius - viewy; gy = interp.y - interp.radius - viewy;
tz = FixedMul(gx, viewcos) + FixedMul(gy, viewsin); tz = FixedMul(gx, viewcos) + FixedMul(gy, viewsin);
@ -1507,14 +1515,14 @@ static void R_ProjectBoundingBox(mobj_t *thing, vissprite_t *vis)
box = R_NewVisSprite(); box = R_NewVisSprite();
box->mobj = thing; box->mobj = thing;
box->mobjflags = thing->flags; box->mobjflags = thing->flags;
box->thingheight = thing->height; box->thingheight = interp.height;
box->cut = SC_BBOX; box->cut = SC_BBOX;
box->gx = tx; box->gx = tx;
box->gy = tz; box->gy = tz;
box->scale = 2 * FixedMul(thing->radius, viewsin); box->scale = 2 * FixedMul(interp.radius, viewsin);
box->xscale = 2 * FixedMul(thing->radius, viewcos); box->xscale = 2 * FixedMul(interp.radius, viewcos);
box->pz = interp.z; box->pz = interp.z;
box->pzt = box->pz + box->thingheight; box->pzt = box->pz + box->thingheight;
@ -1563,6 +1571,7 @@ static void R_ProjectSprite(mobj_t *thing)
fixed_t tr_x, tr_y; fixed_t tr_x, tr_y;
fixed_t tx, tz; fixed_t tx, tz;
fixed_t xscale, yscale; //added : 02-02-98 : aaargll..if I were a math-guy!!! fixed_t xscale, yscale; //added : 02-02-98 : aaargll..if I were a math-guy!!!
fixed_t radius, height; // For drop shadows
fixed_t sortscale, sortsplat = 0; fixed_t sortscale, sortsplat = 0;
fixed_t linkscale = 0; fixed_t linkscale = 0;
fixed_t sort_x = 0, sort_y = 0, sort_z; fixed_t sort_x = 0, sort_y = 0, sort_z;
@ -1638,6 +1647,8 @@ static void R_ProjectSprite(mobj_t *thing)
} }
this_scale = interp.scale; this_scale = interp.scale;
radius = interp.radius; // For drop shadows
height = interp.height; // Ditto
// transform the origin point // transform the origin point
tr_x = interp.x - viewx; tr_x = interp.x - viewx;
@ -1758,9 +1769,6 @@ static void R_ProjectSprite(mobj_t *thing)
I_Assert(lump < max_spritelumps); I_Assert(lump < max_spritelumps);
if (thing->skin && ((skin_t *)thing->skin)->flags & SF_HIRES)
this_scale = FixedMul(this_scale, ((skin_t *)thing->skin)->highresscale);
spr_width = spritecachedinfo[lump].width; spr_width = spritecachedinfo[lump].width;
spr_height = spritecachedinfo[lump].height; spr_height = spritecachedinfo[lump].height;
spr_offset = spritecachedinfo[lump].offset; spr_offset = spritecachedinfo[lump].offset;
@ -1810,6 +1818,14 @@ static void R_ProjectSprite(mobj_t *thing)
// calculate edges of the shape // calculate edges of the shape
spritexscale = interp.spritexscale; spritexscale = interp.spritexscale;
spriteyscale = interp.spriteyscale; spriteyscale = interp.spriteyscale;
if (thing->skin && ((skin_t *)thing->skin)->flags & SF_HIRES)
{
fixed_t highresscale = ((skin_t *)thing->skin)->highresscale;
spritexscale = FixedMul(spritexscale, highresscale);
spriteyscale = FixedMul(spriteyscale, highresscale);
}
if (spritexscale < 1 || spriteyscale < 1) if (spritexscale < 1 || spriteyscale < 1)
return; return;
@ -1977,6 +1993,8 @@ static void R_ProjectSprite(mobj_t *thing)
{ {
R_InterpolateMobjState(thing, FRACUNIT, &tracer_interp); R_InterpolateMobjState(thing, FRACUNIT, &tracer_interp);
} }
radius = tracer_interp.radius; // For drop shadows
height = tracer_interp.height; // Ditto
tr_x = (tracer_interp.x + sort_x) - viewx; tr_x = (tracer_interp.x + sort_x) - viewx;
tr_y = (tracer_interp.y + sort_y) - viewy; tr_y = (tracer_interp.y + sort_y) - viewy;
@ -2068,7 +2086,7 @@ static void R_ProjectSprite(mobj_t *thing)
if (abs(groundz-viewz)/tz > 4) if (abs(groundz-viewz)/tz > 4)
return; // Prevent stretchy shadows and possible crashes return; // Prevent stretchy shadows and possible crashes
floordiff = abs((isflipped ? caster->height : 0) + casterinterp.z - groundz); floordiff = abs((isflipped ? casterinterp.height : 0) + casterinterp.z - groundz);
trans += ((floordiff / (100*FRACUNIT)) + 3); trans += ((floordiff / (100*FRACUNIT)) + 3);
shadowscale = FixedMul(FRACUNIT - floordiff/640, casterinterp.scale); shadowscale = FixedMul(FRACUNIT - floordiff/640, casterinterp.scale);
} }
@ -2083,8 +2101,8 @@ static void R_ProjectSprite(mobj_t *thing)
if (shadowdraw) if (shadowdraw)
{ {
spritexscale = FixedMul(thing->radius * 2, FixedMul(shadowscale, spritexscale)); spritexscale = FixedMul(radius * 2, FixedMul(shadowscale, spritexscale));
spriteyscale = FixedMul(thing->radius * 2, FixedMul(shadowscale, spriteyscale)); spriteyscale = FixedMul(radius * 2, FixedMul(shadowscale, spriteyscale));
spriteyscale = FixedMul(spriteyscale, FixedDiv(abs(groundz - viewz), tz)); spriteyscale = FixedMul(spriteyscale, FixedDiv(abs(groundz - viewz), tz));
spriteyscale = min(spriteyscale, spritexscale) / patch->height; spriteyscale = min(spriteyscale, spritexscale) / patch->height;
spritexscale /= patch->width; spritexscale /= patch->width;
@ -2099,7 +2117,7 @@ static void R_ProjectSprite(mobj_t *thing)
{ {
R_SkewShadowSprite(thing, thing->standingslope, groundz, patch->height, shadowscale, &spriteyscale, &sheartan); R_SkewShadowSprite(thing, thing->standingslope, groundz, patch->height, shadowscale, &spriteyscale, &sheartan);
gzt = (isflipped ? (interp.z + thing->height) : interp.z) + patch->height * spriteyscale / 2; gzt = (isflipped ? (interp.z + height) : interp.z) + patch->height * spriteyscale / 2;
gz = gzt - patch->height * spriteyscale; gz = gzt - patch->height * spriteyscale;
cut |= SC_SHEAR; cut |= SC_SHEAR;
@ -2114,7 +2132,7 @@ static void R_ProjectSprite(mobj_t *thing)
// When vertical flipped, draw sprites from the top down, at least as far as offsets are concerned. // When vertical flipped, draw sprites from the top down, at least as far as offsets are concerned.
// sprite height - sprite topoffset is the proper inverse of the vertical offset, of course. // sprite height - sprite topoffset is the proper inverse of the vertical offset, of course.
// remember gz and gzt should be seperated by sprite height, not thing height - thing height can be shorter than the sprite itself sometimes! // remember gz and gzt should be seperated by sprite height, not thing height - thing height can be shorter than the sprite itself sometimes!
gz = interp.z + oldthing->height - FixedMul(spr_topoffset, FixedMul(spriteyscale, this_scale)); gz = interp.z + interp.height - FixedMul(spr_topoffset, FixedMul(spriteyscale, this_scale));
gzt = gz + FixedMul(spr_height, FixedMul(spriteyscale, this_scale)); gzt = gz + FixedMul(spr_height, FixedMul(spriteyscale, this_scale));
} }
else else
@ -2193,7 +2211,7 @@ static void R_ProjectSprite(mobj_t *thing)
vis->gy = interp.y; vis->gy = interp.y;
vis->gz = gz; vis->gz = gz;
vis->gzt = gzt; vis->gzt = gzt;
vis->thingheight = thing->height; vis->thingheight = height;
vis->pz = interp.z; vis->pz = interp.z;
vis->pzt = vis->pz + vis->thingheight; vis->pzt = vis->pz + vis->thingheight;
vis->texturemid = FixedDiv(gzt - viewz, spriteyscale); vis->texturemid = FixedDiv(gzt - viewz, spriteyscale);
@ -2633,6 +2651,14 @@ static void R_SortVisSprites(vissprite_t* vsprsortedhead, UINT32 start, UINT32 e
// bundle linkdraw // bundle linkdraw
for (ds = unsorted.prev; ds != &unsorted; ds = ds->prev) for (ds = unsorted.prev; ds != &unsorted; ds = ds->prev)
{ {
// Remove this sprite if it was determined to not be visible
if (ds->cut & SC_NOTVISIBLE)
{
ds->next->prev = ds->prev;
ds->prev->next = ds->next;
continue;
}
if (!(ds->cut & SC_LINKDRAW)) if (!(ds->cut & SC_LINKDRAW))
continue; continue;
@ -2659,21 +2685,27 @@ static void R_SortVisSprites(vissprite_t* vsprsortedhead, UINT32 start, UINT32 e
continue; continue;
// don't connect if the tracer's top is cut off, but lower than the link's top // don't connect if the tracer's top is cut off, but lower than the link's top
if ((dsfirst->cut & SC_TOP) if ((dsfirst->cut & SC_TOP) && dsfirst->szt > ds->szt)
&& dsfirst->szt > ds->szt)
continue; continue;
// don't connect if the tracer's bottom is cut off, but higher than the link's bottom // don't connect if the tracer's bottom is cut off, but higher than the link's bottom
if ((dsfirst->cut & SC_BOTTOM) if ((dsfirst->cut & SC_BOTTOM) && dsfirst->sz < ds->sz)
&& dsfirst->sz < ds->sz)
continue; continue;
// If the object isn't visible, then the bounding box isn't either
if (ds->cut & SC_BBOX && dsfirst->cut & SC_NOTVISIBLE)
ds->cut |= SC_NOTVISIBLE;
break; break;
} }
// remove from chain // remove from chain
ds->next->prev = ds->prev; ds->next->prev = ds->prev;
ds->prev->next = ds->next; ds->prev->next = ds->next;
if (ds->cut & SC_NOTVISIBLE)
continue;
linkedvissprites++; linkedvissprites++;
if (dsfirst != &unsorted) if (dsfirst != &unsorted)
@ -2725,6 +2757,8 @@ static void R_SortVisSprites(vissprite_t* vsprsortedhead, UINT32 start, UINT32 e
best = ds; best = ds;
} }
} }
if (best)
{
best->next->prev = best->prev; best->next->prev = best->prev;
best->prev->next = best->next; best->prev->next = best->next;
best->next = vsprsortedhead; best->next = vsprsortedhead;
@ -2733,6 +2767,7 @@ static void R_SortVisSprites(vissprite_t* vsprsortedhead, UINT32 start, UINT32 e
vsprsortedhead->prev = best; vsprsortedhead->prev = best;
} }
} }
}
// //
// R_CreateDrawNodes // R_CreateDrawNodes
@ -3161,6 +3196,44 @@ static void R_HeightSecClip(vissprite_t *spr, INT32 x1, INT32 x2)
} }
} }
static boolean R_CheckSpriteVisible(vissprite_t *spr, INT32 x1, INT32 x2)
{
INT16 sz = spr->sz;
INT16 szt = spr->szt;
fixed_t texturemid, yscale, scalestep = spr->scalestep;
INT32 height;
if (scalestep)
{
height = spr->patch->height;
yscale = spr->scale;
scalestep = FixedMul(scalestep, spr->spriteyscale);
if (spr->thingscale != FRACUNIT)
texturemid = FixedDiv(spr->texturemid, max(spr->thingscale, 1));
else
texturemid = spr->texturemid;
}
for (INT32 x = x1; x <= x2; x++)
{
if (scalestep)
{
fixed_t top = centeryfrac - FixedMul(texturemid, yscale);
fixed_t bottom = top + (height * yscale);
szt = (INT16)(top >> FRACBITS);
sz = (INT16)(bottom >> FRACBITS);
yscale += scalestep;
}
if (spr->cliptop[x] < spr->clipbot[x] && sz > spr->cliptop[x] && szt < spr->clipbot[x])
return true;
}
return false;
}
// R_ClipVisSprite // R_ClipVisSprite
// Clips vissprites without drawing, so that portals can work. -Red // Clips vissprites without drawing, so that portals can work. -Red
static void R_ClipVisSprite(vissprite_t *spr, INT32 x1, INT32 x2, portal_t* portal) static void R_ClipVisSprite(vissprite_t *spr, INT32 x1, INT32 x2, portal_t* portal)
@ -3304,8 +3377,7 @@ static void R_ClipVisSprite(vissprite_t *spr, INT32 x1, INT32 x2, portal_t* port
spr->clipbot[x] = (INT16)viewheight; spr->clipbot[x] = (INT16)viewheight;
if (spr->cliptop[x] == -2) if (spr->cliptop[x] == -2)
//Fab : 26-04-98: was -1, now clips against console bottom spr->cliptop[x] = -1;
spr->cliptop[x] = (INT16)con_clipviewtop;
} }
if (portal) if (portal)
@ -3330,6 +3402,14 @@ static void R_ClipVisSprite(vissprite_t *spr, INT32 x1, INT32 x2, portal_t* port
spr->cliptop[x] = -1; spr->cliptop[x] = -1;
} }
} }
// Check if it'll be visible
// Not done for floorsprites.
if (cv_spriteclip.value && (spr->cut & SC_SPLAT) == 0)
{
if (!R_CheckSpriteVisible(spr, x1, x2))
spr->cut |= SC_NOTVISIBLE;
}
} }
void R_ClipSprites(drawseg_t* dsstart, portal_t* portal) void R_ClipSprites(drawseg_t* dsstart, portal_t* portal)
@ -3398,8 +3478,19 @@ void R_ClipSprites(drawseg_t* dsstart, portal_t* portal)
{ {
vissprite_t *spr = R_GetVisSprite(clippedvissprites); vissprite_t *spr = R_GetVisSprite(clippedvissprites);
if (spr->cut & SC_BBOX) if (cv_spriteclip.value
&& (spr->szt > vid.height || spr->sz < 0)
&& !((spr->cut & SC_SPLAT) || spr->scalestep))
{
spr->cut |= SC_NOTVISIBLE;
continue; continue;
}
if (spr->cut & SC_BBOX)
{
numvisiblesprites++;
continue;
}
INT32 x1 = (spr->cut & SC_SPLAT) ? 0 : spr->x1; INT32 x1 = (spr->cut & SC_SPLAT) ? 0 : spr->x1;
INT32 x2 = (spr->cut & SC_SPLAT) ? viewwidth : spr->x2; INT32 x2 = (spr->cut & SC_SPLAT) ? viewwidth : spr->x2;
@ -3421,6 +3512,9 @@ void R_ClipSprites(drawseg_t* dsstart, portal_t* portal)
} }
R_ClipVisSprite(spr, x1, x2, portal); R_ClipVisSprite(spr, x1, x2, portal);
if ((spr->cut & SC_NOTVISIBLE) == 0)
numvisiblesprites++;
} }
} }

View file

@ -123,21 +123,22 @@ typedef enum
SC_NONE = 0, SC_NONE = 0,
SC_TOP = 1, SC_TOP = 1,
SC_BOTTOM = 1<<1, SC_BOTTOM = 1<<1,
SC_NOTVISIBLE = 1<<2,
// other flags // other flags
SC_PRECIP = 1<<2, SC_PRECIP = 1<<3,
SC_LINKDRAW = 1<<3, SC_LINKDRAW = 1<<4,
SC_FULLBRIGHT = 1<<4, SC_FULLBRIGHT = 1<<5,
SC_SEMIBRIGHT = 1<<5, SC_SEMIBRIGHT = 1<<6,
SC_FULLDARK = 1<<6, SC_FULLDARK = 1<<7,
SC_VFLIP = 1<<7, SC_VFLIP = 1<<8,
SC_ISSCALED = 1<<8, SC_ISSCALED = 1<<9,
SC_ISROTATED = 1<<9, SC_ISROTATED = 1<<10,
SC_SHADOW = 1<<10, SC_SHADOW = 1<<11,
SC_SHEAR = 1<<11, SC_SHEAR = 1<<12,
SC_SPLAT = 1<<12, SC_SPLAT = 1<<13,
SC_BBOX = 1<<13, SC_BBOX = 1<<14,
// masks // masks
SC_CUTMASK = SC_TOP|SC_BOTTOM, SC_CUTMASK = SC_TOP|SC_BOTTOM|SC_NOTVISIBLE,
SC_FLAGMASK = ~SC_CUTMASK SC_FLAGMASK = ~SC_CUTMASK
} spritecut_e; } spritecut_e;
@ -219,7 +220,7 @@ typedef struct vissprite_s
INT32 dispoffset; // copy of mobj->dispoffset, affects ordering but not drawing INT32 dispoffset; // copy of mobj->dispoffset, affects ordering but not drawing
} vissprite_t; } vissprite_t;
extern UINT32 visspritecount; extern UINT32 visspritecount, numvisiblesprites;
void R_ClipSprites(drawseg_t* dsstart, portal_t* portal); void R_ClipSprites(drawseg_t* dsstart, portal_t* portal);

View file

@ -90,7 +90,7 @@ typedef LPVOID (WINAPI *p_MapViewOfFile) (HANDLE, DWORD, DWORD, DWORD, SIZE_T);
#include <kvm.h> #include <kvm.h>
#endif #endif
#include <nlist.h> #include <nlist.h>
#include <sys/vmmeter.h> #include <sys/sysctl.h>
#endif #endif
#endif #endif
@ -259,10 +259,10 @@ UINT8 keyboard_started = false;
#ifdef UNIXBACKTRACE #ifdef UNIXBACKTRACE
#define STDERR_WRITE(string) if (fd != -1) I_OutputMsg("%s", string) #define STDERR_WRITE(string) if (fd != -1) I_OutputMsg("%s", string)
#define CRASHLOG_WRITE(string) if (fd != -1) write(fd, string, strlen(string)) #define CRASHLOG_WRITE(string) if (fd != -1) junk = write(fd, string, strlen(string))
#define CRASHLOG_STDERR_WRITE(string) \ #define CRASHLOG_STDERR_WRITE(string) \
if (fd != -1)\ if (fd != -1)\
write(fd, string, strlen(string));\ junk = write(fd, string, strlen(string));\
I_OutputMsg("%s", string) I_OutputMsg("%s", string)
static void write_backtrace(INT32 signal) static void write_backtrace(INT32 signal)
@ -271,6 +271,7 @@ static void write_backtrace(INT32 signal)
size_t size; size_t size;
time_t rawtime; time_t rawtime;
struct tm timeinfo; struct tm timeinfo;
ssize_t junk;
enum { BT_SIZE = 1024, STR_SIZE = 32 }; enum { BT_SIZE = 1024, STR_SIZE = 32 };
void *array[BT_SIZE]; void *array[BT_SIZE];
@ -314,7 +315,7 @@ static void write_backtrace(INT32 signal)
backtrace_symbols_fd(array, size, STDERR_FILENO); backtrace_symbols_fd(array, size, STDERR_FILENO);
CRASHLOG_WRITE("\n"); // Write another newline to the log so it looks nice :) CRASHLOG_WRITE("\n"); // Write another newline to the log so it looks nice :)
(void)junk;
close(fd); close(fd);
} }
#undef STDERR_WRITE #undef STDERR_WRITE
@ -325,8 +326,10 @@ static void write_backtrace(INT32 signal)
static void I_ReportSignal(int num, int coredumped) static void I_ReportSignal(int num, int coredumped)
{ {
//static char msg[] = "oh no! back to reality!\r\n"; //static char msg[] = "oh no! back to reality!\r\n";
const char *sigmsg, *sigttl; const char *sigmsg, *signame;
char ttl[128]; char ttl[128];
char sigttl[512] = "Process killed by signal: ";
const char *reportmsg = "\n\nTo help us figure out the cause, you can visit our official Discord server\nwhere you will find more instructions on how to submit a crash report.\n\nSorry for the inconvenience!";
switch (num) switch (num)
{ {
@ -335,16 +338,16 @@ static void I_ReportSignal(int num, int coredumped)
// sigmsg = "SRB2 was interrupted prematurely by the user."; // sigmsg = "SRB2 was interrupted prematurely by the user.";
// break; // break;
case SIGILL: case SIGILL:
sigmsg = "SRB2 has attempted to execute an illegal instruction and needs to close. %s"; sigmsg = "SRB2 has attempted to execute an illegal instruction and needs to close.";
sigttl = "SIGILL"; // illegal instruction - invalid function image signame = "SIGILL"; // illegal instruction - invalid function image
break; break;
case SIGFPE: case SIGFPE:
sigmsg = "SRB2 has encountered a mathematical exception and needs to close. %s"; sigmsg = "SRB2 has encountered a mathematical exception and needs to close.";
sigttl = "SIGFPE"; // mathematical exception signame = "SIGFPE"; // mathematical exception
break; break;
case SIGSEGV: case SIGSEGV:
sigmsg = "SRB2 has attempted to access a memory location that it shouldn't and needs to close. %s"; sigmsg = "SRB2 has attempted to access a memory location that it shouldn't and needs to close.";
sigttl = "SIGSEGV"; // segment violation signame = "SIGSEGV"; // segment violation
break; break;
// case SIGTERM: // case SIGTERM:
// sigmsg = "SRB2 was terminated by a kill signal."; // sigmsg = "SRB2 was terminated by a kill signal.";
@ -355,34 +358,31 @@ static void I_ReportSignal(int num, int coredumped)
// sigttl = "SIGBREAK" // Ctrl-Break sequence // sigttl = "SIGBREAK" // Ctrl-Break sequence
// break; // break;
case SIGABRT: case SIGABRT:
sigmsg = "SRB2 was terminated by an abort signal. %s"; sigmsg = "SRB2 was terminated by an abort signal.";
sigttl = "SIGABRT"; // abnormal termination triggered by abort call signame = "SIGABRT"; // abnormal termination triggered by abort call
break; break;
default: default:
sigmsg = "SRB2 was terminated by an unknown signal. %s"; sigmsg = "SRB2 was terminated by an unknown signal.";
sprintf(ttl, "number %d", num); sprintf(ttl, "number %d", num);
if (coredumped) if (coredumped)
sigttl = 0; signame = 0;
else else
sigttl = ttl; signame = ttl;
} }
if (coredumped) if (coredumped)
{ {
if (sigttl) if (signame)
sprintf(ttl, "%s (core dumped)", sigttl); sprintf(ttl, "%s (core dumped)", signame);
else else
strcat(ttl, " (core dumped)"); strcat(ttl, " (core dumped)");
sigttl = ttl; signame = ttl;
} }
sprintf(ttl, "Process killed by signal: %s", sigttl); strcat(sigttl, signame);
I_OutputMsg("%s\n", sigttl);
sigttl = ttl;
I_OutputMsg("\n%s\n\n", sigttl);
if (M_CheckParm("-dedicated")) if (M_CheckParm("-dedicated"))
return; return;
@ -396,8 +396,7 @@ static void I_ReportSignal(int num, int coredumped)
SDL_MESSAGEBOX_ERROR, /* .flags */ SDL_MESSAGEBOX_ERROR, /* .flags */
NULL, /* .window */ NULL, /* .window */
sigttl, /* .title */ sigttl, /* .title */
va(sigmsg, va("%s %s", sigmsg, reportmsg), /* .message */
"\n\nTo help us figure out the cause, you can visit our official Discord server\nwhere you will find more instructions on how to submit a crash report.\n\nSorry for the inconvenience!"), /* .message */
SDL_arraysize(buttons), /* .numbuttons */ SDL_arraysize(buttons), /* .numbuttons */
buttons, /* .buttons */ buttons, /* .buttons */
NULL /* .colorScheme */ NULL /* .colorScheme */
@ -407,8 +406,10 @@ static void I_ReportSignal(int num, int coredumped)
SDL_ShowMessageBox(&messageboxdata, &buttonid); SDL_ShowMessageBox(&messageboxdata, &buttonid);
#if SDL_VERSION_ATLEAST(2,0,14)
if (buttonid == 1) if (buttonid == 1)
SDL_OpenURL("https://www.srb2.org/discord"); SDL_OpenURL("https://www.srb2.org/discord");
#endif
} }
#ifndef NEWSIGNALHANDLER #ifndef NEWSIGNALHANDLER
@ -2264,7 +2265,7 @@ void I_Sleep(UINT32 ms)
} }
#ifdef NEWSIGNALHANDLER #ifdef NEWSIGNALHANDLER
static void newsignalhandler_Warn(const char *pr) ATTRNORETURN static FUNCNORETURN void newsignalhandler_Warn(const char *pr)
{ {
char text[128]; char text[128];
@ -3035,40 +3036,17 @@ static long get_entry(const char* name, const char* buf)
size_t I_GetFreeMem(size_t *total) size_t I_GetFreeMem(size_t *total)
{ {
#ifdef FREEBSD #ifdef FREEBSD
struct vmmeter sum; u_int v_free_count, v_page_size, v_page_count;
kvm_t *kd; size_t size = sizeof(v_free_count);
struct nlist namelist[] = sysctlbyname("vm.stats.vm.v_free_count", &v_free_count, &size, NULL, 0);
{ size = sizeof(v_page_size);
#define X_SUM 0 sysctlbyname("vm.stats.vm.v_page_size", &v_page_size, &size, NULL, 0);
{"_cnt"}, size = sizeof(v_page_count);
{NULL} sysctlbyname("vm.stats.vm.v_page_count", &v_page_count, &size, NULL, 0);
};
if ((kd = kvm_open(NULL, NULL, NULL, O_RDONLY, "kvm_open")) == NULL)
{
if (total)
*total = 0L;
return 0;
}
if (kvm_nlist(kd, namelist) != 0)
{
kvm_close (kd);
if (total)
*total = 0L;
return 0;
}
if (kvm_read(kd, namelist[X_SUM].n_value, &sum,
sizeof (sum)) != sizeof (sum))
{
kvm_close(kd);
if (total)
*total = 0L;
return 0;
}
kvm_close(kd);
if (total) if (total)
*total = sum.v_page_count * sum.v_page_size; *total = v_page_count * v_page_size;
return sum.v_free_count * sum.v_page_size; return v_free_count * v_page_size;
#elif defined (SOLARIS) #elif defined (SOLARIS)
/* Just guess */ /* Just guess */
if (total) if (total)

View file

@ -1593,7 +1593,6 @@ boolean VID_CheckRenderer(void)
else if (vid.glstate == VID_GL_LIBRARY_ERROR) else if (vid.glstate == VID_GL_LIBRARY_ERROR)
rendererchanged = false; rendererchanged = false;
} }
else
#endif #endif
if (!contextcreated) if (!contextcreated)

View file

@ -170,7 +170,7 @@ static huddrawlist_h luahuddrawlist_titlecard;
skincolornum_t linkColor[3][NUMLINKCOLORS] = { skincolornum_t linkColor[3][NUMLINKCOLORS] = {
{SKINCOLOR_SHAMROCK, SKINCOLOR_AQUA, SKINCOLOR_SKY, SKINCOLOR_BLUE, SKINCOLOR_PURPLE, SKINCOLOR_MAGENTA, {SKINCOLOR_SHAMROCK, SKINCOLOR_AQUA, SKINCOLOR_SKY, SKINCOLOR_BLUE, SKINCOLOR_PURPLE, SKINCOLOR_MAGENTA,
SKINCOLOR_ROSY, SKINCOLOR_RED, SKINCOLOR_ORANGE, SKINCOLOR_GOLD, SKINCOLOR_YELLOW, SKINCOLOR_PERIDOT}, SKINCOLOR_ROSY, SKINCOLOR_RED, SKINCOLOR_ORANGE, SKINCOLOR_GOLD, SKINCOLOR_YELLOW, SKINCOLOR_PERIDOT},
{SKINCOLOR_EMERALD, SKINCOLOR_AQUAMARINE, SKINCOLOR_WAVE, SKINCOLOR_SAPPHIRE, SKINCOLOR_GALAXY, SKINCOLOR_CRYSTAL, {SKINCOLOR_EMERALD, SKINCOLOR_OCEAN, SKINCOLOR_AQUAMARINE, SKINCOLOR_SAPPHIRE, SKINCOLOR_GALAXY, SKINCOLOR_SIBERITE,
SKINCOLOR_TAFFY, SKINCOLOR_RUBY, SKINCOLOR_GARNET, SKINCOLOR_TOPAZ, SKINCOLOR_LEMON, SKINCOLOR_LIME}, SKINCOLOR_TAFFY, SKINCOLOR_RUBY, SKINCOLOR_GARNET, SKINCOLOR_TOPAZ, SKINCOLOR_LEMON, SKINCOLOR_LIME},
{SKINCOLOR_ISLAND, SKINCOLOR_TURQUOISE, SKINCOLOR_DREAM, SKINCOLOR_DAYBREAK, SKINCOLOR_VAPOR, SKINCOLOR_FUCHSIA, {SKINCOLOR_ISLAND, SKINCOLOR_TURQUOISE, SKINCOLOR_DREAM, SKINCOLOR_DAYBREAK, SKINCOLOR_VAPOR, SKINCOLOR_FUCHSIA,
SKINCOLOR_VIOLET, SKINCOLOR_EVENTIDE, SKINCOLOR_KETCHUP, SKINCOLOR_FOUNDATION, SKINCOLOR_HEADLIGHT, SKINCOLOR_CHARTREUSE}}; SKINCOLOR_VIOLET, SKINCOLOR_EVENTIDE, SKINCOLOR_KETCHUP, SKINCOLOR_FOUNDATION, SKINCOLOR_HEADLIGHT, SKINCOLOR_CHARTREUSE}};
@ -2535,6 +2535,8 @@ num:
static INT32 ST_drawEmeraldHuntIcon(mobj_t *hunt, patch_t **patches, INT32 offset) static INT32 ST_drawEmeraldHuntIcon(mobj_t *hunt, patch_t **patches, INT32 offset)
{ {
INT32 interval, i; INT32 interval, i;
if (stplyr->mo == NULL)
return 0; // player just joined after spectating, can happen on custom gamemodes.
UINT32 dist = ((UINT32)P_AproxDistance(P_AproxDistance(stplyr->mo->x - hunt->x, stplyr->mo->y - hunt->y), stplyr->mo->z - hunt->z))>>FRACBITS; UINT32 dist = ((UINT32)P_AproxDistance(P_AproxDistance(stplyr->mo->x - hunt->x, stplyr->mo->y - hunt->y), stplyr->mo->z - hunt->z))>>FRACBITS;
if (dist < 128) if (dist < 128)

View file

@ -15,7 +15,7 @@
#include <string.h> #include <string.h>
#include "doomdef.h" #include "doomdef.h"
#if !defined (__APPLE__) #ifndef SRB2_HAVE_STRLCPY
// Like the OpenBSD version, but it doesn't check for src not being a valid // Like the OpenBSD version, but it doesn't check for src not being a valid
// C string. // C string.

View file

@ -1,4 +1,4 @@
#define SRB2VERSION "2.2.11"/* this must be the first line, for cmake !! */ #define SRB2VERSION "2.2.13"/* this must be the first line, for cmake !! */
// The Modification ID; must be obtained from a Master Server Admin ( https://mb.srb2.org/members/?key=ms_admin ). // The Modification ID; must be obtained from a Master Server Admin ( https://mb.srb2.org/members/?key=ms_admin ).
// DO NOT try to set this otherwise, or your modification will be unplayable through the Master Server. // DO NOT try to set this otherwise, or your modification will be unplayable through the Master Server.
@ -9,7 +9,7 @@
// it's only for detection of the version the player is using so the MS can alert them of an update. // it's only for detection of the version the player is using so the MS can alert them of an update.
// Only set it higher, not lower, obviously. // Only set it higher, not lower, obviously.
// Note that we use this to help keep internal testing in check; this is why v2.2.0 is not version "1". // Note that we use this to help keep internal testing in check; this is why v2.2.0 is not version "1".
#define MODVERSION 52 #define MODVERSION 54
// Define this as a prerelease version suffix (pre#, RC#) // Define this as a prerelease version suffix (pre#, RC#)
//#define BETAVERSION "pre1" //#define BETAVERSION "pre1"

View file

@ -77,8 +77,8 @@ END
#include "../doomdef.h" // Needed for version string #include "../doomdef.h" // Needed for version string
VS_VERSION_INFO VERSIONINFO VS_VERSION_INFO VERSIONINFO
FILEVERSION 2,2,11,0 FILEVERSION 2,2,13,0
PRODUCTVERSION 2,2,11,0 PRODUCTVERSION 2,2,13,0
FILEFLAGSMASK 0x3fL FILEFLAGSMASK 0x3fL
#ifdef _DEBUG #ifdef _DEBUG
FILEFLAGS 0x1L FILEFLAGS 0x1L

View file

@ -991,8 +991,7 @@ void Y_Ticker(void)
if (paused || P_AutoPause()) if (paused || P_AutoPause())
return; return;
LUA_HookBool(intertype == int_spec && stagefailed, LUA_HookBool(stagefailed, HOOK(IntermissionThinker));
HOOK(IntermissionThinker));
intertic++; intertic++;
@ -1455,10 +1454,10 @@ void Y_StartIntermission(void)
if (players[consoleplayer].charflags & SF_SUPER) if (players[consoleplayer].charflags & SF_SUPER)
{ {
strcpy(data.spec.passed3, "can now become"); strcpy(data.spec.passed3, "can now become");
snprintf(data.spec.passed4, if (strlen(skins[players[consoleplayer].skin].supername) > 20) //too long, use generic
sizeof data.spec.passed4, "Super %s", strcpy(data.spec.passed4, "their super form");
skins[players[consoleplayer].skin].realname); else
data.spec.passed4[sizeof data.spec.passed4 - 1] = '\0'; strcpy(data.spec.passed4, skins[players[consoleplayer].skin].supername);
} }
} }
else else