mirror of
https://git.do.srb2.org/STJr/SRB2.git
synced 2024-12-13 14:20:59 +00:00
Merge branch 'master' into improve-backtrace
This commit is contained in:
commit
11fc21e7ec
205 changed files with 12891 additions and 15587 deletions
|
@ -1,9 +1,9 @@
|
|||
version: 2
|
||||
jobs:
|
||||
build:
|
||||
working_directory: /root/SRB2
|
||||
working_directory: /home/circleci/SRB2
|
||||
docker:
|
||||
- image: debian:stretch
|
||||
- image: cimg/base:current
|
||||
environment:
|
||||
CC: ccache gcc -m32
|
||||
PKG_CONFIG_LIBDIR: /usr/lib/i386-linux-gnu/pkgconfig
|
||||
|
@ -11,7 +11,7 @@ jobs:
|
|||
LIBGME_LDFLAGS: -lgme
|
||||
CCACHE_COMPRESS: true
|
||||
WFLAGS: -Wno-unsuffixed-float-constants
|
||||
GCC49: true
|
||||
GCC81: true
|
||||
#- image: ubuntu:trusty
|
||||
# environment:
|
||||
# CC: ccache gcc -m32
|
||||
|
@ -25,39 +25,42 @@ jobs:
|
|||
steps:
|
||||
- run:
|
||||
name: Add i386 arch
|
||||
command: dpkg --add-architecture i386
|
||||
command: sudo dpkg --add-architecture i386
|
||||
- run:
|
||||
name: Add STJr PPA
|
||||
command: |
|
||||
apt-get -qq update
|
||||
apt-get -qq -y install dirmngr
|
||||
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
|
||||
sudo apt-get -qq update
|
||||
sudo apt-get -qq -y install dirmngr
|
||||
sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 0B1702D71499D9C25F986507F240F4449D3B0EC6
|
||||
echo "deb http://ppa.launchpad.net/stjr/srb2/ubuntu trusty main" | sudo tee -a /etc/apt/sources.list
|
||||
- run:
|
||||
name: Make APT cache folder
|
||||
command: mkdir -p /root/.cache/apt/archives/partial
|
||||
command: mkdir -p /home/circleci/.cache/apt/archives/partial
|
||||
- run:
|
||||
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:
|
||||
name: Update APT listing
|
||||
command: apt-get -qq update
|
||||
command: sudo apt-get -qq update
|
||||
- run:
|
||||
name: Support S3 upload
|
||||
command: apt-get -qq -y install ca-certificates
|
||||
command: sudo apt-get -qq -y install ca-certificates
|
||||
- restore_cache:
|
||||
keys:
|
||||
- v1-SRB2-APT
|
||||
- run:
|
||||
name: Install SDK
|
||||
command: apt-get -o Dir::Cache="/root/.cache/apt" -qq -y --no-install-recommends install git build-essential nasm 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
|
||||
name: Uninstall amd64 SDK
|
||||
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:
|
||||
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:
|
||||
key: v1-SRB2-APT-{{ checksum "/root/.cache/apt_archives.md5" }}
|
||||
key: v1-SRB2-APT-{{ checksum "/home/circleci/.cache/apt_archives.md5" }}
|
||||
paths:
|
||||
- /root/.cache/apt
|
||||
- /home/circleci/.cache/apt
|
||||
- checkout
|
||||
- run:
|
||||
name: Compile without network support
|
||||
|
@ -78,9 +81,9 @@ jobs:
|
|||
name: Compile
|
||||
command: make -C src LINUX=1 ERRORMODE=1 -k -j4
|
||||
- store_artifacts:
|
||||
path: /root/SRB2/bin/
|
||||
path: /home/circleci/SRB2/bin/
|
||||
destination: bin
|
||||
- save_cache:
|
||||
key: v1-SRB2-{{ .Branch }}-{{ checksum "make/linux/SDL.deps" }}
|
||||
paths:
|
||||
- /root/.ccache
|
||||
- /home/circleci/.ccache
|
||||
|
|
4
.gitattributes
vendored
4
.gitattributes
vendored
|
@ -1,15 +1,17 @@
|
|||
#Source code
|
||||
/Makefile text=auto
|
||||
/src/*.c text=auto
|
||||
/src/*.h text=auto
|
||||
/src/*.s text=auto
|
||||
/src/*.m text=auto
|
||||
/src/*.xpm text=auto
|
||||
/src/Makefile text=auto
|
||||
/tools/Makefile text=auto
|
||||
/src/Make*.cfg text=auto
|
||||
/src/CMakeLists.txt text=auto
|
||||
*.mk -whitespace text=auto
|
||||
# Windows EOL
|
||||
*.cs -crlf -whitespace
|
||||
*.mk -crlf -whitespace
|
||||
*.bat -crlf -whitespace
|
||||
*.dev -crlf -whitespace
|
||||
*.dsp -crlf -whitespace
|
||||
|
|
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -22,4 +22,5 @@ Win32_LIB_ASM_Release
|
|||
/make
|
||||
/bin
|
||||
/build
|
||||
/build.*
|
||||
/build/*
|
||||
/CMakeUserPresets.json
|
434
.gitlab-ci.yml
Normal file
434
.gitlab-ci.yml
Normal 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
|
|
@ -53,11 +53,15 @@ else()
|
|||
set(SRB2_CONFIG_SYSTEM_LIBRARIES_DEFAULT OFF)
|
||||
endif()
|
||||
|
||||
# Clang tidy options will be ignored if CMAKE_<LANG>_CLANG_TIDY are set.
|
||||
option(SRB2_CONFIG_ENABLE_CLANG_TIDY_C "Enable default clang-tidy check configuration for C" OFF)
|
||||
option(SRB2_CONFIG_ENABLE_CLANG_TIDY_CXX "Enable default clang-tidy check configuration for C++" OFF)
|
||||
option(
|
||||
SRB2_CONFIG_SYSTEM_LIBRARIES
|
||||
"Link dependencies using CMake's find_package and do not use internal builds"
|
||||
${SRB2_CONFIG_SYSTEM_LIBRARIES_DEFAULT}
|
||||
)
|
||||
option(SRB2_CONFIG_ENABLE_TESTS "Build the test suite" ON)
|
||||
# This option isn't recommended for distribution builds and probably won't work (yet).
|
||||
cmake_dependent_option(
|
||||
SRB2_CONFIG_SHARED_INTERNAL_LIBRARIES
|
||||
|
@ -76,6 +80,25 @@ option(SRB2_CONFIG_ZDEBUG "Compile with ZDEBUG defined." OFF)
|
|||
option(SRB2_CONFIG_PROFILEMODE "Compile for profiling (GCC only)." OFF)
|
||||
set(SRB2_CONFIG_ASSET_DIRECTORY "" CACHE PATH "Path to directory that contains all asset files for the installer. If set, assets will be part of installation and cpack.")
|
||||
|
||||
if(SRB2_CONFIG_ENABLE_TESTS)
|
||||
# https://github.com/catchorg/Catch2
|
||||
CPMAddPackage(
|
||||
NAME Catch2
|
||||
VERSION 3.4.0
|
||||
GITHUB_REPOSITORY catchorg/Catch2
|
||||
OPTIONS
|
||||
"CATCH_INSTALL_DOCS OFF"
|
||||
)
|
||||
list(APPEND CMAKE_MODULE_PATH "${Catch2_SOURCE_DIR}/extras")
|
||||
include(CTest)
|
||||
include(Catch)
|
||||
add_executable(srb2tests)
|
||||
# To add tests, use target_sources to add individual test files to the target in subdirs.
|
||||
target_link_libraries(srb2tests PRIVATE Catch2::Catch2 Catch2::Catch2WithMain)
|
||||
target_compile_features(srb2tests PRIVATE c_std_11 cxx_std_17)
|
||||
catch_discover_tests(srb2tests)
|
||||
endif()
|
||||
|
||||
# Enable CCache
|
||||
# (Set USE_CCACHE=ON to use, CCACHE_OPTIONS for options)
|
||||
if("${CMAKE_HOST_SYSTEM_NAME}" STREQUAL Windows)
|
||||
|
@ -108,7 +131,11 @@ if("${SRB2_CONFIG_SYSTEM_LIBRARIES}")
|
|||
find_package(SDL2_mixer REQUIRED)
|
||||
find_package(CURL REQUIRED)
|
||||
find_package(OPENMPT REQUIRED)
|
||||
find_package(GME REQUIRED)
|
||||
|
||||
# libgme defaults to "Nuked" YM2612 emulator, which is
|
||||
# very SLOW. The system library probably uses the
|
||||
# default so just always build it.
|
||||
#find_package(GME REQUIRED)
|
||||
endif()
|
||||
|
||||
if(${PROJECT_SOURCE_DIR} MATCHES ${PROJECT_BINARY_DIR})
|
||||
|
@ -119,13 +146,6 @@ if ((${SRB2_USE_CCACHE}) AND (${CMAKE_C_COMPILER} MATCHES "clang"))
|
|||
message(WARNING "Using clang and CCache: You may want to set environment variable CCACHE_CPP2=yes to prevent include errors during compile.")
|
||||
endif()
|
||||
|
||||
# Add sources from Sourcefile
|
||||
function(target_sourcefile type)
|
||||
file(STRINGS Sourcefile list
|
||||
REGEX "[-0-9A-Za-z_]+\.${type}")
|
||||
target_sources(SRB2SDL2 PRIVATE ${list})
|
||||
endfunction()
|
||||
|
||||
# bitness check
|
||||
set(SRB2_SYSTEM_BITS 0)
|
||||
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||
|
@ -144,7 +164,8 @@ set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin")
|
|||
set(CMAKE_PDB_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin")
|
||||
|
||||
# Set EXE names so the assets CMakeLists can refer to its target
|
||||
set(SRB2_SDL2_EXE_NAME srb2 CACHE STRING "Executable binary output name")
|
||||
set(SRB2_SDL2_EXE_NAME "" CACHE STRING "Override executable binary output name")
|
||||
set(SRB2_SDL2_EXE_SUFFIX "" CACHE STRING "Optional executable suffix, separated by an underscore")
|
||||
|
||||
include_directories(${CMAKE_CURRENT_BINARY_DIR}/src)
|
||||
|
||||
|
@ -152,11 +173,37 @@ add_subdirectory(src)
|
|||
add_subdirectory(assets)
|
||||
|
||||
|
||||
## config.h generation
|
||||
set(GIT_EXECUTABLE "git" CACHE FILEPATH "Path to git binary")
|
||||
include(GitUtilities)
|
||||
git_latest_commit(SRB2_COMP_COMMIT "${CMAKE_SOURCE_DIR}")
|
||||
git_current_branch(SRB2_GIT_BRANCH "${CMAKE_SOURCE_DIR}")
|
||||
set(SRB2_COMP_BRANCH "${SRB2_GIT_BRANCH}")
|
||||
set(SRB2_COMP_REVISION "${SRB2_COMP_COMMIT}")
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/src/config.h.in ${CMAKE_CURRENT_BINARY_DIR}/src/config.h)
|
||||
|
||||
if("${SRB2_SDL2_EXE_NAME}" STREQUAL "")
|
||||
# cause a reconfigure if the branch changes
|
||||
get_git_dir(SRB2_GIT_DIR)
|
||||
configure_file("${SRB2_GIT_DIR}/HEAD" HEAD COPYONLY)
|
||||
|
||||
git_current_branch(SRB2_GIT_REVISION)
|
||||
|
||||
if("${SRB2_GIT_REVISION}" STREQUAL "")
|
||||
# use abbreviated commit hash if on detached HEAD
|
||||
git_latest_commit(SRB2_GIT_REVISION)
|
||||
endif()
|
||||
|
||||
if("${CMAKE_SYSTEM_NAME}" MATCHES "Windows")
|
||||
list(APPEND EXE_NAME_PARTS "srb2win")
|
||||
elseif("${CMAKE_SYSTEM_NAME}" MATCHES "Linux")
|
||||
list(APPEND EXE_NAME_PARTS "lsdlsrb2")
|
||||
else()
|
||||
list(APPEND EXE_NAME_PARTS "srb2")
|
||||
endif()
|
||||
|
||||
if(NOT "${SRB2_GIT_REVISION}" STREQUAL "master")
|
||||
list(APPEND EXE_NAME_PARTS ${SRB2_GIT_REVISION})
|
||||
endif()
|
||||
else()
|
||||
list(APPEND EXE_NAME_PARTS ${SRB2_SDL2_EXE_NAME})
|
||||
endif()
|
||||
|
||||
list(APPEND EXE_NAME_PARTS ${SRB2_SDL2_EXE_SUFFIX})
|
||||
|
||||
list(JOIN EXE_NAME_PARTS "_" EXE_NAME)
|
||||
set_target_properties(SRB2SDL2 PROPERTIES OUTPUT_NAME ${EXE_NAME})
|
||||
|
|
29
CMakePresets.json
Normal file
29
CMakePresets.json
Normal file
|
@ -0,0 +1,29 @@
|
|||
{
|
||||
"version": 3,
|
||||
"configurePresets": [
|
||||
{
|
||||
"name": "default",
|
||||
"description": "Build using default generator",
|
||||
"binaryDir": "build",
|
||||
"cacheVariables": {
|
||||
"CMAKE_C_FLAGS": "-fdiagnostics-color",
|
||||
"CMAKE_CXX_FLAGS": "-fdiagnostics-color",
|
||||
"CMAKE_BUILD_TYPE": "RelWithDebInfo"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "debug",
|
||||
"description": "Build for development (no optimizations)",
|
||||
"inherits": "default",
|
||||
"cacheVariables": {
|
||||
"CMAKE_BUILD_TYPE": "Debug"
|
||||
}
|
||||
}
|
||||
],
|
||||
"buildPresets": [
|
||||
{
|
||||
"name": "default",
|
||||
"configurePreset": "default"
|
||||
}
|
||||
]
|
||||
}
|
|
@ -8,7 +8,6 @@
|
|||
[Sonic Robo Blast 2](https://srb2.org/) is a 3D Sonic the Hedgehog fangame based on a modified version of [Doom Legacy](http://doomlegacy.sourceforge.net/).
|
||||
|
||||
## Dependencies
|
||||
- NASM (x86 builds only)
|
||||
- SDL2 (Linux/OS X only)
|
||||
- SDL2-Mixer (Linux/OS X only)
|
||||
- libupnp (Linux/OS X only)
|
||||
|
|
18
SRB2.cbp
18
SRB2.cbp
|
@ -1992,24 +1992,6 @@ HW3SOUND for 3D hardware sound support
|
|||
<Option compilerVar="CC" />
|
||||
</Unit>
|
||||
<Unit filename="src/v_video.h" />
|
||||
<Unit filename="src/vid_copy.s">
|
||||
<Option compilerVar="CC" />
|
||||
<Option compiler="avrgcc" use="1" buildCommand="$compiler $options -x assembler-with-cpp -c $file -o $object" />
|
||||
<Option compiler="gnu_gcc_compiler_for_mingw32" use="1" buildCommand="$compiler $options -x assembler-with-cpp -c $file -o $object" />
|
||||
<Option compiler="gnu_gcc_compiler_for_mingw64" use="1" buildCommand="$compiler $options -x assembler-with-cpp -c $file -o $object" />
|
||||
<Option compiler="armelfgcc" use="1" buildCommand="$compiler $options -x assembler-with-cpp -c $file -o $object" />
|
||||
<Option compiler="tricoregcc" use="1" buildCommand="$compiler $options -x assembler-with-cpp -c $file -o $object" />
|
||||
<Option compiler="ppcgcc" use="1" buildCommand="$compiler $options -x assembler-with-cpp -c $file -o $object" />
|
||||
<Option compiler="gcc" use="1" buildCommand="$compiler $options -x assembler-with-cpp -c $file -o $object" />
|
||||
<Option target="Debug Native/SDL" />
|
||||
<Option target="Release Native/SDL" />
|
||||
<Option target="Debug Linux/SDL" />
|
||||
<Option target="Release Linux/SDL" />
|
||||
<Option target="Debug Mingw/SDL" />
|
||||
<Option target="Release Mingw/SDL" />
|
||||
<Option target="Debug Mingw/DirectX" />
|
||||
<Option target="Release Mingw/DirectX" />
|
||||
</Unit>
|
||||
<Unit filename="src/w_wad.c">
|
||||
<Option compilerVar="CC" />
|
||||
</Unit>
|
||||
|
|
|
@ -25,9 +25,6 @@
|
|||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(PlatformTarget)'=='x86'">
|
||||
<ClCompile>
|
||||
<PreprocessorDefinitions>USEASM;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
|
||||
</Link>
|
||||
|
|
52
Srb2.dev
52
Srb2.dev
|
@ -5,7 +5,7 @@ Ver=3
|
|||
IsCpp=0
|
||||
Type=0
|
||||
UnitCount=279
|
||||
Folders=A_Asm,B_Bot,BLUA,D_Doom,F_Frame,G_Game,H_Hud,Hw_Hardware,Hw_Hardware/r_opengl,I_Interface,I_Interface/Dummy,I_Interface/SDL,I_Interface/Win32,LUA,M_Misc,P_Play,R_Rend,S_Sounds,W_Wad
|
||||
Folders=B_Bot,BLUA,D_Doom,F_Frame,G_Game,H_Hud,Hw_Hardware,Hw_Hardware/r_opengl,I_Interface,I_Interface/Dummy,I_Interface/SDL,I_Interface/Win32,LUA,M_Misc,P_Play,R_Rend,S_Sounds,W_Wad
|
||||
CommandLine=
|
||||
CompilerSettings=00000000000100000111e1
|
||||
PchHead=-1
|
||||
|
@ -1473,36 +1473,6 @@ Priority=1000
|
|||
OverrideBuildCmd=0
|
||||
BuildCmd=
|
||||
|
||||
[Unit149]
|
||||
FileName=src\tmap.nas
|
||||
Folder=A_Asm
|
||||
Compile=0
|
||||
CompileCpp=0
|
||||
Link=0
|
||||
Priority=1000
|
||||
OverrideBuildCmd=1
|
||||
BuildCmd=nasm.exe -g -o $@ -f win32 src/tmap.nas
|
||||
|
||||
[Unit150]
|
||||
FileName=src\asm_defs.inc
|
||||
Folder=A_Asm
|
||||
Compile=0
|
||||
CompileCpp=0
|
||||
Link=0
|
||||
Priority=1000
|
||||
OverrideBuildCmd=0
|
||||
BuildCmd=
|
||||
|
||||
[Unit151]
|
||||
FileName=src\vid_copy.s
|
||||
Folder=A_Asm
|
||||
Compile=1
|
||||
CompileCpp=0
|
||||
Link=1
|
||||
Priority=1000
|
||||
OverrideBuildCmd=1
|
||||
BuildCmd=$(CC) $(CFLAGS) -x assembler-with-cpp -c src/vid_copy.s -o $@
|
||||
|
||||
[Unit152]
|
||||
FileName=src\y_inter.h
|
||||
Folder=H_Hud
|
||||
|
@ -1543,26 +1513,6 @@ Priority=1000
|
|||
OverrideBuildCmd=0
|
||||
BuildCmd=
|
||||
|
||||
[Unit156]
|
||||
FileName=src\p5prof.h
|
||||
Folder=A_Asm
|
||||
Compile=1
|
||||
CompileCpp=0
|
||||
Link=1
|
||||
Priority=1000
|
||||
OverrideBuildCmd=0
|
||||
BuildCmd=
|
||||
|
||||
[Unit157]
|
||||
FileName=src\tmap_mmx.nas
|
||||
Folder=A_Asm
|
||||
Compile=0
|
||||
CompileCpp=0
|
||||
Link=0
|
||||
Priority=1000
|
||||
OverrideBuildCmd=1
|
||||
BuildCmd=nasm.exe -g -o $@ -f win32 src/tmap_mmx.nas
|
||||
|
||||
[Unit159]
|
||||
FileName=src\lzf.h
|
||||
Folder=W_Wad
|
||||
|
|
29
alias-bootstrap.sh
Executable file
29
alias-bootstrap.sh
Executable file
|
@ -0,0 +1,29 @@
|
|||
#!/usr/bin/env sh
|
||||
|
||||
# All these commands can be run from anywhere in the git
|
||||
# tree, not just the top level.
|
||||
|
||||
# Usage: git cmake
|
||||
#
|
||||
# Same usage as standard CMake command.
|
||||
#
|
||||
git config 'alias.cmake' '!cmake'
|
||||
|
||||
# Usage: git build <build preset> [options]
|
||||
# Usage: git build [options]
|
||||
#
|
||||
# In the second usage, when no preset is given, the
|
||||
# "default" build preset is used.
|
||||
#
|
||||
# Available options can be found by running:
|
||||
#
|
||||
# git cmake --build
|
||||
#
|
||||
git config 'alias.build' '!p="${1##-*}"; [ "$p" ] && shift; git cmake --build --preset "${p:-default}"'
|
||||
|
||||
# Usage: git crossmake
|
||||
#
|
||||
# Shortcut to i686-w64-mingw32-cmake (CMake cross
|
||||
# compiler)
|
||||
#
|
||||
git config 'alias.crossmake' '!i686-w64-mingw32-cmake'
|
10
appveyor.yml
10
appveyor.yml
|
@ -1,4 +1,4 @@
|
|||
version: 2.2.10.{branch}-{build}
|
||||
version: 2.2.13.{branch}-{build}
|
||||
os: MinGW
|
||||
|
||||
environment:
|
||||
|
@ -7,8 +7,6 @@ environment:
|
|||
# c:\mingw-w64 i686 has gcc 6.3.0, so use c:\msys64 7.3.0 instead
|
||||
MINGW_SDK: c:\msys64\mingw32
|
||||
CFLAGS: -Wno-implicit-fallthrough
|
||||
NASM_ZIP: nasm-2.12.01
|
||||
NASM_URL: http://www.nasm.us/pub/nasm/releasebuilds/2.12.01/win64/nasm-2.12.01-win64.zip
|
||||
UPX_ZIP: upx391w
|
||||
UPX_URL: http://upx.sourceforge.net/download/upx391w.zip
|
||||
CCACHE_EXE: ccache.exe
|
||||
|
@ -40,17 +38,12 @@ environment:
|
|||
ASSET_CLEAN: 0
|
||||
|
||||
cache:
|
||||
- nasm-2.12.01.zip
|
||||
- upx391w.zip
|
||||
- ccache.exe
|
||||
- C:\Users\appveyor\.ccache
|
||||
- C:\Users\appveyor\srb2_cache
|
||||
|
||||
install:
|
||||
- if not exist "%NASM_ZIP%.zip" appveyor DownloadFile "%NASM_URL%" -FileName "%NASM_ZIP%.zip"
|
||||
- 7z x -y "%NASM_ZIP%.zip" -o%TMP% >null
|
||||
- robocopy /S /xx /ns /nc /nfl /ndl /np /njh /njs "%TMP%\%NASM_ZIP%" "%MINGW_SDK%\bin" nasm.exe || exit 0
|
||||
|
||||
- if not exist "%UPX_ZIP%.zip" appveyor DownloadFile "%UPX_URL%" -FileName "%UPX_ZIP%.zip"
|
||||
- 7z x -y "%UPX_ZIP%.zip" -o%TMP% >null
|
||||
- robocopy /S /xx /ns /nc /nfl /ndl /np /njh /njs "%TMP%\%UPX_ZIP%" "%MINGW_SDK%\bin" upx.exe || exit 0
|
||||
|
@ -65,7 +58,6 @@ configuration:
|
|||
before_build:
|
||||
- set "Path=%MINGW_SDK%\bin;%Path%"
|
||||
- mingw32-make --version
|
||||
- nasm -v
|
||||
- if not [%NOUPX%] == [1] ( upx -V )
|
||||
- ccache -V
|
||||
- ccache -s
|
||||
|
|
|
@ -29,6 +29,7 @@ set(SRB2_ASSETS_GAME
|
|||
"srb2.pk3"
|
||||
"player.dta"
|
||||
"zones.pk3"
|
||||
"patch.pk3"
|
||||
"music.dta"
|
||||
"models.dat"
|
||||
)
|
||||
|
|
32
cmake/Comptime.cmake
Normal file
32
cmake/Comptime.cmake
Normal file
|
@ -0,0 +1,32 @@
|
|||
cmake_minimum_required(VERSION 3.3 FATAL_ERROR)
|
||||
|
||||
set(CMAKE_BINARY_DIR "${BINARY_DIR}")
|
||||
set(CMAKE_CURRENT_BINARY_DIR "${BINARY_DIR}")
|
||||
|
||||
# Set up CMAKE path
|
||||
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules/")
|
||||
|
||||
include(GitUtilities)
|
||||
|
||||
git_current_branch(SRB2_COMP_BRANCH)
|
||||
git_working_tree_dirty(SRB2_COMP_UNCOMMITTED)
|
||||
|
||||
git_latest_commit(SRB2_COMP_REVISION)
|
||||
git_subject(subject)
|
||||
string(REGEX REPLACE "([\"\\])" "\\\\\\1" SRB2_COMP_NOTE "${subject}")
|
||||
|
||||
if("${CMAKE_BUILD_TYPE}" STREQUAL "")
|
||||
set(CMAKE_BUILD_TYPE None)
|
||||
endif()
|
||||
|
||||
# These build types enable optimizations of some kind by default.
|
||||
set(optimized_build_types "MINSIZEREL;RELEASE;RELWITHDEBINFO")
|
||||
|
||||
string(TOUPPER "${CMAKE_BUILD_TYPE}" build_type)
|
||||
if("${build_type}" IN_LIST optimized_build_types)
|
||||
set(SRB2_COMP_OPTIMIZED TRUE)
|
||||
else()
|
||||
set(SRB2_COMP_OPTIMIZED FALSE)
|
||||
endif()
|
||||
|
||||
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/src/config.h.in" "${CMAKE_CURRENT_BINARY_DIR}/src/config.h")
|
|
@ -1,46 +0,0 @@
|
|||
|
||||
#=============================================================================
|
||||
# Copyright 2010 Kitware, Inc.
|
||||
#
|
||||
# Distributed under the OSI-approved BSD License (the "License");
|
||||
# see accompanying file Copyright.txt for details.
|
||||
#
|
||||
# This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
# See the License for more information.
|
||||
#=============================================================================
|
||||
# (To distribute this file outside of CMake, substitute the full
|
||||
# License text for the above reference.)
|
||||
|
||||
# support for the yasm assembler
|
||||
|
||||
set(CMAKE_ASM_YASM_SOURCE_FILE_EXTENSIONS nasm yasm asm)
|
||||
|
||||
if(NOT CMAKE_ASM_YASM_OBJECT_FORMAT)
|
||||
if(WIN32)
|
||||
if(CMAKE_C_SIZEOF_DATA_PTR EQUAL 8)
|
||||
set(CMAKE_ASM_YASM_OBJECT_FORMAT win64)
|
||||
else()
|
||||
set(CMAKE_ASM_YASM_OBJECT_FORMAT win32)
|
||||
endif()
|
||||
elseif(APPLE)
|
||||
if(CMAKE_C_SIZEOF_DATA_PTR EQUAL 8)
|
||||
set(CMAKE_ASM_YASM_OBJECT_FORMAT macho64)
|
||||
else()
|
||||
set(CMAKE_ASM_YASM_OBJECT_FORMAT macho)
|
||||
endif()
|
||||
else()
|
||||
if(CMAKE_C_SIZEOF_DATA_PTR EQUAL 8)
|
||||
set(CMAKE_ASM_YASM_OBJECT_FORMAT elf64)
|
||||
else()
|
||||
set(CMAKE_ASM_YASM_OBJECT_FORMAT elf)
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
set(CMAKE_ASM_YASM_COMPILE_OBJECT "<CMAKE_ASM_YASM_COMPILER> <FLAGS> -f ${CMAKE_ASM_YASM_OBJECT_FORMAT} -o <OBJECT> <SOURCE>")
|
||||
|
||||
# Load the generic ASMInformation file:
|
||||
set(ASM_DIALECT "_YASM")
|
||||
include(CMakeASMInformation)
|
||||
set(ASM_DIALECT)
|
|
@ -1,27 +0,0 @@
|
|||
|
||||
#=============================================================================
|
||||
# Copyright 2010 Kitware, Inc.
|
||||
#
|
||||
# Distributed under the OSI-approved BSD License (the "License");
|
||||
# see accompanying file Copyright.txt for details.
|
||||
#
|
||||
# This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
# See the License for more information.
|
||||
#=============================================================================
|
||||
# (To distribute this file outside of CMake, substitute the full
|
||||
# License text for the above reference.)
|
||||
|
||||
# Find the nasm assembler. yasm (http://www.tortall.net/projects/yasm/) is nasm compatible
|
||||
|
||||
set(CMAKE_ASM_YASM_COMPILER_LIST nasm yasm)
|
||||
|
||||
if(NOT CMAKE_ASM_YASM_COMPILER)
|
||||
find_program(CMAKE_ASM_YASM_COMPILER yasm
|
||||
"$ENV{ProgramFiles}/YASM")
|
||||
endif()
|
||||
|
||||
# Load the generic DetermineASM compiler file with the DIALECT set properly:
|
||||
set(ASM_DIALECT "_YASM")
|
||||
include(CMakeDetermineASMCompiler)
|
||||
set(ASM_DIALECT)
|
|
@ -1,23 +0,0 @@
|
|||
|
||||
#=============================================================================
|
||||
# Copyright 2010 Kitware, Inc.
|
||||
#
|
||||
# Distributed under the OSI-approved BSD License (the "License");
|
||||
# see accompanying file Copyright.txt for details.
|
||||
#
|
||||
# This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
# See the License for more information.
|
||||
#=============================================================================
|
||||
# (To distribute this file outside of CMake, substitute the full
|
||||
# License text for the above reference.)
|
||||
|
||||
# This file is used by EnableLanguage in cmGlobalGenerator to
|
||||
# determine that the selected ASM_NASM "compiler" works.
|
||||
# For assembler this can only check whether the compiler has been found,
|
||||
# because otherwise there would have to be a separate assembler source file
|
||||
# for each assembler on every architecture.
|
||||
|
||||
set(ASM_DIALECT "_YASM")
|
||||
include(CMakeTestASMCompiler)
|
||||
set(ASM_DIALECT)
|
|
@ -6,38 +6,54 @@ endif()
|
|||
|
||||
set(__GitUtilities ON)
|
||||
|
||||
function(git_describe variable path)
|
||||
execute_process(COMMAND "${GIT_EXECUTABLE}" "describe"
|
||||
WORKING_DIRECTORY "${path}"
|
||||
RESULT_VARIABLE result
|
||||
macro(_git_command)
|
||||
execute_process(
|
||||
COMMAND "${GIT_EXECUTABLE}" ${ARGN}
|
||||
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
|
||||
OUTPUT_VARIABLE output
|
||||
ERROR_QUIET
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
)
|
||||
endmacro()
|
||||
|
||||
macro(_git_easy_command)
|
||||
_git_command(${ARGN})
|
||||
set(${variable} "${output}" PARENT_SCOPE)
|
||||
endmacro()
|
||||
|
||||
function(git_current_branch variable)
|
||||
_git_command(symbolic-ref -q --short HEAD)
|
||||
|
||||
# If a detached head, a ref could still be resolved.
|
||||
if("${output}" STREQUAL "")
|
||||
_git_command(describe --all --exact-match)
|
||||
|
||||
# Get the ref, in the form heads/master or
|
||||
# remotes/origin/master so isolate the final part.
|
||||
string(REGEX REPLACE ".*/" "" output "${output}")
|
||||
endif()
|
||||
|
||||
set(${variable} "${output}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
function(git_current_branch variable path)
|
||||
execute_process(COMMAND ${GIT_EXECUTABLE} "symbolic-ref" "--short" "HEAD"
|
||||
WORKING_DIRECTORY "${path}"
|
||||
RESULT_VARIABLE result
|
||||
OUTPUT_VARIABLE output
|
||||
ERROR_QUIET
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
)
|
||||
|
||||
set(${variable} "${output}" PARENT_SCOPE)
|
||||
function(git_latest_commit variable)
|
||||
_git_easy_command(rev-parse --short HEAD)
|
||||
endfunction()
|
||||
|
||||
function(git_latest_commit variable path)
|
||||
execute_process(COMMAND ${GIT_EXECUTABLE} "rev-parse" "--short" "HEAD"
|
||||
WORKING_DIRECTORY "${path}"
|
||||
RESULT_VARIABLE result
|
||||
OUTPUT_VARIABLE output
|
||||
ERROR_QUIET
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
)
|
||||
function(git_working_tree_dirty variable)
|
||||
_git_command(status --porcelain -uno)
|
||||
|
||||
set(${variable} "${output}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
if(output STREQUAL "")
|
||||
set(${variable} FALSE PARENT_SCOPE)
|
||||
else()
|
||||
set(${variable} TRUE PARENT_SCOPE)
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
function(git_subject variable)
|
||||
_git_easy_command(log -1 --format=%s)
|
||||
endfunction()
|
||||
|
||||
function(get_git_dir variable)
|
||||
_git_easy_command(rev-parse --git-dir)
|
||||
endfunction()
|
||||
|
|
21
cmake/Modules/clang-tidy-default.cmake
Normal file
21
cmake/Modules/clang-tidy-default.cmake
Normal file
|
@ -0,0 +1,21 @@
|
|||
find_program(CLANG_TIDY clang-tidy)
|
||||
|
||||
# Note: Apple Clang does not ship with clang tools. If you want clang-tidy on
|
||||
# macOS, it's best to install the Homebrew llvm bottle and set CLANG_TIDY
|
||||
# in your build directory. The llvm package is keg-only, so it will not
|
||||
# collide with Apple Clang.
|
||||
|
||||
function(target_set_default_clang_tidy target lang checks)
|
||||
if("${CLANG_TIDY}" STREQUAL "CLANG_TIDY-NOTFOUND")
|
||||
return()
|
||||
endif()
|
||||
|
||||
get_target_property(c_clang_tidy_prop SRB2SDL2 C_CLANG_TIDY)
|
||||
if(NOT ("${c_clang_tidy_prop}" STREQUAL "c_clang_tidy_prop-NOTFOUND"))
|
||||
return()
|
||||
endif()
|
||||
|
||||
set_target_properties("${target}" PROPERTIES
|
||||
${lang}_CLANG_TIDY "${CLANG_TIDY};-checks=${checks}"
|
||||
)
|
||||
endfunction()
|
|
@ -3,12 +3,12 @@ ifdef ComSpec
|
|||
COMSPEC=$(ComSpec)
|
||||
endif
|
||||
ifdef COMSPEC
|
||||
OBJCOPY=objcopy.exe
|
||||
OBJDUMP=objdump.exe
|
||||
OBJCOPY?=objcopy.exe
|
||||
OBJDUMP?=objdump.exe
|
||||
GZIP?=gzip.exe
|
||||
else
|
||||
OBJCOPY=objcopy
|
||||
OBJDUMP=objdump
|
||||
OBJCOPY?=objcopy
|
||||
OBJDUMP?=objdump
|
||||
GZIP?=gzip
|
||||
endif
|
||||
DBGNAME=$(BIN).debug
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -15,7 +15,7 @@ common
|
|||
ignoredextensions = "wad pk3 pk7 bak backup1 backup2 backup3 zip rar 7z";
|
||||
|
||||
// Default testing parameters
|
||||
testparameters = "-file \"%AP\" \"%F\" -warp %L";
|
||||
testparameters = "-folder \"%AF\" -file \"%AA\" \"%F\" -warp %L";
|
||||
testshortpaths = true;
|
||||
|
||||
// Action special help
|
||||
|
@ -26,7 +26,7 @@ common
|
|||
generalizedsectors = true;
|
||||
|
||||
// Maximum safe map size check (0 means skip check)
|
||||
safeboundary = 1;
|
||||
safeboundary = 0;
|
||||
|
||||
// Map boundaries. Map objects can only be placed within these boundaries
|
||||
leftboundary = -32768;
|
||||
|
@ -40,6 +40,8 @@ common
|
|||
defaultflatscale = 1.0f;
|
||||
scaledtextureoffsets = true;
|
||||
|
||||
maxcolormapalpha = 25;
|
||||
|
||||
// Thing number for start position in 3D Mode
|
||||
start3dmode = 3328;
|
||||
|
||||
|
@ -68,137 +70,6 @@ common
|
|||
}
|
||||
}
|
||||
|
||||
mapformat_doom
|
||||
{
|
||||
// The format interface handles the map data format
|
||||
formatinterface = "DoomMapSetIO";
|
||||
|
||||
// Default nodebuilder configurations
|
||||
defaultsavecompiler = "zennode_normal";
|
||||
defaulttestcompiler = "zennode_fast";
|
||||
|
||||
/*
|
||||
GAME DETECT PATTERN
|
||||
Used to guess the game for which a WAD file is made.
|
||||
|
||||
1 = One of these lumps must exist
|
||||
2 = None of these lumps must exist
|
||||
3 = All of these lumps must exist
|
||||
*/
|
||||
|
||||
gamedetect
|
||||
{
|
||||
EXTENDED = 2;
|
||||
|
||||
|
||||
BEHAVIOR = 2;
|
||||
|
||||
E#M# = 2;
|
||||
|
||||
MAP?? = 1;
|
||||
}
|
||||
|
||||
/*
|
||||
MAP LUMP NAMES
|
||||
Map lumps are loaded with the map as long as they are right after each other. When the editor
|
||||
meets a lump which is not defined in this list it will ignore the map if not satisfied.
|
||||
The order of items defines the order in which lumps will be written to WAD file on save.
|
||||
To indicate the map header lump, use ~MAP
|
||||
|
||||
Legenda:
|
||||
required = Lump is required to exist.
|
||||
blindcopy = Lump will be copied along with the map blindly. (usefull for lumps Doom Builder doesn't use)
|
||||
nodebuild = The nodebuilder generates this lump.
|
||||
allowempty = The nodebuilder is allowed to leave this lump empty.
|
||||
script = This lump is a text-based script. Specify the filename of the script configuration to use.
|
||||
*/
|
||||
|
||||
maplumpnames
|
||||
{
|
||||
include("SRB222_misc.cfg", "doommaplumpnames");
|
||||
}
|
||||
|
||||
// When this is set to true, sectors with the same tag will light up when a line is highlighted
|
||||
linetagindicatesectors = true;
|
||||
|
||||
// Special linedefs
|
||||
include("SRB222_misc.cfg", "speciallinedefs");
|
||||
|
||||
// Default flags for first new thing
|
||||
defaultthingflags
|
||||
{
|
||||
}
|
||||
|
||||
// DEFAULT SECTOR BRIGHTNESS LEVELS
|
||||
sectorbrightness
|
||||
{
|
||||
include("SRB222_misc.cfg", "sectorbrightness");
|
||||
}
|
||||
|
||||
// SECTOR TYPES
|
||||
sectortypes
|
||||
{
|
||||
include("SRB222_sectors.cfg", "sectortypes");
|
||||
}
|
||||
|
||||
// GENERALISED SECTOR TYPES
|
||||
gen_sectortypes
|
||||
{
|
||||
include("SRB222_sectors.cfg", "gen_sectortypes");
|
||||
}
|
||||
|
||||
// LINEDEF FLAGS
|
||||
linedefflags
|
||||
{
|
||||
include("SRB222_misc.cfg", "linedefflags");
|
||||
}
|
||||
|
||||
// Linedef flags UDMF translation table
|
||||
// This is needed for copy/paste and prefabs to work properly
|
||||
// When the UDMF field name is prefixed with ! it is inverted
|
||||
linedefflagstranslation
|
||||
{
|
||||
include("SRB222_misc.cfg", "linedefflagstranslation");
|
||||
}
|
||||
|
||||
// LINEDEF ACTIVATIONS
|
||||
linedefactivations
|
||||
{
|
||||
}
|
||||
|
||||
// LINEDEF TYPES
|
||||
linedeftypes
|
||||
{
|
||||
include("SRB222_linedefs.cfg", "doom");
|
||||
}
|
||||
|
||||
// THING FLAGS
|
||||
thingflags
|
||||
{
|
||||
include("SRB222_misc.cfg", "thingflags");
|
||||
}
|
||||
|
||||
// Thing flags UDMF translation table
|
||||
// This is needed for copy/paste and prefabs to work properly
|
||||
// When the UDMF field name is prefixed with ! it is inverted
|
||||
thingflagstranslation
|
||||
{
|
||||
include("SRB222_misc.cfg", "thingflagstranslation");
|
||||
}
|
||||
|
||||
// THING FLAGS ERROR MASK
|
||||
// Mask for the thing flags which indicates the options
|
||||
// that make the same thing appear in the same modes
|
||||
thingflagsmask1 = 7; // 1 + 2 + 4
|
||||
thingflagsmask2 = 0;
|
||||
|
||||
// THING TYPES
|
||||
thingtypes
|
||||
{
|
||||
include("SRB222_things.cfg", "doom");
|
||||
}
|
||||
}
|
||||
|
||||
mapformat_udmf
|
||||
{
|
||||
// The format interface handles the map data format
|
||||
|
@ -222,9 +93,17 @@ mapformat_udmf
|
|||
{
|
||||
include("SRB222_misc.cfg", "universalfields");
|
||||
}
|
||||
|
||||
// Disable Doom-related modes that don't make sense for SRB2
|
||||
soundsupport = false;
|
||||
automapsupport = false;
|
||||
|
||||
// When this is set to true, sectors with the same tag will light up when a line is highlighted
|
||||
linetagindicatesectors = false;
|
||||
localsidedeftextureoffsets = true;
|
||||
distinctfloorandceilingbrightness = true;
|
||||
|
||||
planeequationsupport = true;
|
||||
|
||||
// Special linedefs
|
||||
include("SRB222_misc.cfg", "speciallinedefs_udmf");
|
||||
|
@ -240,6 +119,11 @@ mapformat_udmf
|
|||
include("SRB222_misc.cfg", "sectorflags");
|
||||
}
|
||||
|
||||
sectorflagscategories
|
||||
{
|
||||
include("SRB222_misc.cfg", "sectorflagscategories");
|
||||
}
|
||||
|
||||
// DEFAULT SECTOR BRIGHTNESS LEVELS
|
||||
sectorbrightness
|
||||
{
|
||||
|
@ -247,6 +131,7 @@ mapformat_udmf
|
|||
}
|
||||
|
||||
damagetypes = "Generic Water Fire Lava Electric Spike DeathPitTilt DeathPitNoTilt Instakill SpecialStage";
|
||||
triggerertypes = "Player AllPlayers Mobj";
|
||||
|
||||
// LINEDEF FLAGS
|
||||
linedefflags
|
||||
|
@ -282,7 +167,6 @@ mapformat_udmf
|
|||
// How to compare thing flags (for the stuck things error checker)
|
||||
thingflagscompare
|
||||
{
|
||||
include("UDMF_misc.cfg", "thingflagscompare");
|
||||
}
|
||||
|
||||
// THING TYPES
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,24 +1,3 @@
|
|||
linedefflags
|
||||
{
|
||||
1 = "[0] Impassable";
|
||||
2 = "[1] Block Enemies";
|
||||
4 = "[2] Double-Sided";
|
||||
8 = "[3] Upper Unpegged";
|
||||
16 = "[4] Lower Unpegged";
|
||||
32 = "[5] Slope Skew (E1)";
|
||||
64 = "[6] Not Climbable";
|
||||
128 = "[7] No Midtexture Skew (E2)";
|
||||
256 = "[8] Peg Midtexture (E3)";
|
||||
512 = "[9] Solid Midtexture (E4)";
|
||||
1024 = "[10] Repeat Midtexture (E5)";
|
||||
2048 = "[11] Netgame Only";
|
||||
4096 = "[12] No Netgame";
|
||||
8192 = "[13] Effect 6";
|
||||
16384 = "[14] Bouncy Wall";
|
||||
32768 = "[15] Transfer Line";
|
||||
}
|
||||
|
||||
|
||||
// Linedef flags UDMF translation table
|
||||
// This is needed for copy/paste and prefabs to work properly
|
||||
// When the UDMF field name is prefixed with ! it is inverted
|
||||
|
@ -42,7 +21,6 @@ linedefflagstranslation
|
|||
32768 = "transfer";
|
||||
}
|
||||
|
||||
|
||||
linedefflags_udmf
|
||||
{
|
||||
blocking = "Impassable";
|
||||
|
@ -74,19 +52,13 @@ linedefrenderstyles
|
|||
|
||||
sectorflags
|
||||
{
|
||||
colormapfog = "Fog Planes in Colormap";
|
||||
colormapfadesprites = "Fade Fullbright in Colormap";
|
||||
colormapprotected = "Protected Colormap";
|
||||
flipspecial_nofloor = "No Trigger on Floor Touch";
|
||||
flipspecial_ceiling = "Trigger on Ceiling Touch";
|
||||
triggerspecial_touch = "Trigger on Edge Touch";
|
||||
triggerspecial_headbump = "Trigger on Headbump";
|
||||
triggerline_plane = "Linedef Trigger Requires Plane Touch";
|
||||
triggerline_mobj = "Non-Pushables Can Trigger Linedef";
|
||||
invertprecip = "Invert Precipitation";
|
||||
gravityflip = "Flip Objects in Reverse Gravity";
|
||||
heatwave = "Heat Wave";
|
||||
noclipcamera = "Intangible to the Camera";
|
||||
colormapfog = "Fog Planes";
|
||||
colormapfadesprites = "Fade Fullbright";
|
||||
colormapprotected = "Protected from Tagging";
|
||||
outerspace = "Space Countdown";
|
||||
doublestepup = "Ramp Sector (double step-up/down)";
|
||||
nostepdown = "Non-Ramp Sector (No step-down)";
|
||||
|
@ -104,23 +76,59 @@ sectorflags
|
|||
zoomtubeend = "Zoom Tube End";
|
||||
finishline = "Circuit Finish Line";
|
||||
ropehang = "Rope Hang";
|
||||
jumpflip = "Flip Gravity on Jump";
|
||||
gravityoverride = "Make Reverse Gravity Temporary";
|
||||
flipspecial_nofloor = "No Trigger on Floor Touch";
|
||||
flipspecial_ceiling = "Trigger on Ceiling Touch";
|
||||
triggerspecial_touch = "Trigger on Edge Touch";
|
||||
triggerspecial_headbump = "Trigger on Headbump";
|
||||
triggerline_plane = "Linedef Trigger Requires Plane Touch";
|
||||
triggerline_mobj = "Non-Pushables Can Trigger Linedef";
|
||||
}
|
||||
|
||||
thingflags
|
||||
sectorflagscategories
|
||||
{
|
||||
1 = "[1] Extra";
|
||||
2 = "[2] Flip";
|
||||
4 = "[4] Special";
|
||||
8 = "[8] Ambush";
|
||||
invertprecip = "regular";
|
||||
gravityflip = "regular";
|
||||
heatwave = "regular";
|
||||
noclipcamera = "regular";
|
||||
colormapfog = "colormap";
|
||||
colormapfadesprites = "colormap";
|
||||
colormapprotected = "colormap";
|
||||
outerspace = "special";
|
||||
doublestepup = "special";
|
||||
nostepdown = "special";
|
||||
speedpad = "special";
|
||||
starpostactivator = "special";
|
||||
exit = "special";
|
||||
specialstagepit = "special";
|
||||
returnflag = "special";
|
||||
redteambase = "special";
|
||||
blueteambase = "special";
|
||||
fan = "special";
|
||||
supertransform = "special";
|
||||
forcespin = "special";
|
||||
zoomtubestart = "special";
|
||||
zoomtubeend = "special";
|
||||
finishline = "special";
|
||||
ropehang = "special";
|
||||
jumpflip = "special";
|
||||
gravityoverride = "special";
|
||||
flipspecial_nofloor = "trigger";
|
||||
flipspecial_ceiling = "trigger";
|
||||
triggerspecial_touch = "trigger";
|
||||
triggerspecial_headbump = "trigger";
|
||||
triggerline_plane = "trigger";
|
||||
triggerline_mobj = "trigger";
|
||||
}
|
||||
|
||||
// THING FLAGS
|
||||
thingflags_udmf
|
||||
{
|
||||
flip = "Flip";
|
||||
absolutez = "Absolute Z height";
|
||||
}
|
||||
|
||||
|
||||
// Thing flags UDMF translation table
|
||||
// This is needed for copy/paste and prefabs to work properly
|
||||
// When the UDMF field name is prefixed with ! it is inverted
|
||||
|
@ -130,9 +138,9 @@ thingflagstranslation
|
|||
2 = "flip";
|
||||
4 = "special";
|
||||
8 = "ambush";
|
||||
16 = "absolutez";
|
||||
}
|
||||
|
||||
|
||||
// DEFAULT SECTOR BRIGHTNESS LEVELS
|
||||
sectorbrightness
|
||||
{
|
||||
|
@ -171,6 +179,8 @@ sectorbrightness
|
|||
0;
|
||||
}
|
||||
|
||||
numbrightnesslevels = 32;
|
||||
|
||||
/*
|
||||
TEXTURES AND FLAT SOURCES
|
||||
This tells Doom Builder where to find the information for textures
|
||||
|
@ -221,145 +231,18 @@ universalfields
|
|||
{
|
||||
sector
|
||||
{
|
||||
lightalpha
|
||||
{
|
||||
type = 0;
|
||||
default = 25;
|
||||
}
|
||||
|
||||
fadealpha
|
||||
{
|
||||
type = 0;
|
||||
default = 25;
|
||||
}
|
||||
|
||||
fadestart
|
||||
{
|
||||
type = 0;
|
||||
default = 0;
|
||||
}
|
||||
|
||||
fadeend
|
||||
{
|
||||
type = 0;
|
||||
default = 33;
|
||||
}
|
||||
|
||||
foglighting
|
||||
{
|
||||
type = 3;
|
||||
default = false;
|
||||
}
|
||||
|
||||
friction
|
||||
{
|
||||
type = 1;
|
||||
default = 0.90625;
|
||||
}
|
||||
|
||||
triggertag
|
||||
{
|
||||
type = 15;
|
||||
default = 0;
|
||||
}
|
||||
|
||||
triggerer
|
||||
{
|
||||
type = 2;
|
||||
default = "Player";
|
||||
}
|
||||
}
|
||||
|
||||
linedef
|
||||
{
|
||||
arg5
|
||||
{
|
||||
type = 0;
|
||||
default = 0;
|
||||
}
|
||||
arg6
|
||||
{
|
||||
type = 0;
|
||||
default = 0;
|
||||
}
|
||||
arg7
|
||||
{
|
||||
type = 0;
|
||||
default = 0;
|
||||
}
|
||||
arg8
|
||||
{
|
||||
type = 0;
|
||||
default = 0;
|
||||
}
|
||||
arg9
|
||||
{
|
||||
type = 0;
|
||||
default = 0;
|
||||
}
|
||||
stringarg0
|
||||
{
|
||||
type = 2;
|
||||
default = "";
|
||||
}
|
||||
stringarg1
|
||||
{
|
||||
type = 2;
|
||||
default = "";
|
||||
}
|
||||
executordelay
|
||||
{
|
||||
type = 0;
|
||||
default = 0;
|
||||
}
|
||||
}
|
||||
|
||||
sidedef
|
||||
{
|
||||
repeatcnt
|
||||
{
|
||||
type = 0;
|
||||
default = 0;
|
||||
}
|
||||
}
|
||||
|
||||
thing
|
||||
{
|
||||
arg5
|
||||
{
|
||||
type = 0;
|
||||
default = 0;
|
||||
}
|
||||
arg6
|
||||
{
|
||||
type = 0;
|
||||
default = 0;
|
||||
}
|
||||
arg7
|
||||
{
|
||||
type = 0;
|
||||
default = 0;
|
||||
}
|
||||
arg8
|
||||
{
|
||||
type = 0;
|
||||
default = 0;
|
||||
}
|
||||
arg9
|
||||
{
|
||||
type = 0;
|
||||
default = 0;
|
||||
}
|
||||
stringarg0
|
||||
{
|
||||
type = 2;
|
||||
default = "";
|
||||
}
|
||||
stringarg1
|
||||
{
|
||||
type = 2;
|
||||
default = "";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -378,87 +261,6 @@ allowempty = The nodebuilder is allowed to leave this lump empty.
|
|||
scriptbuild = This lump is a text-based script, which should be compiled using current script compiler;
|
||||
script = This lump is a text-based script. Specify the filename of the script configuration to use.
|
||||
*/
|
||||
|
||||
doommaplumpnames
|
||||
{
|
||||
~MAP
|
||||
{
|
||||
required = true;
|
||||
blindcopy = true;
|
||||
nodebuild = false;
|
||||
}
|
||||
|
||||
THINGS
|
||||
{
|
||||
required = true;
|
||||
nodebuild = true;
|
||||
allowempty = true;
|
||||
}
|
||||
|
||||
LINEDEFS
|
||||
{
|
||||
required = true;
|
||||
nodebuild = true;
|
||||
allowempty = false;
|
||||
}
|
||||
|
||||
SIDEDEFS
|
||||
{
|
||||
required = true;
|
||||
nodebuild = true;
|
||||
allowempty = false;
|
||||
}
|
||||
|
||||
VERTEXES
|
||||
{
|
||||
required = true;
|
||||
nodebuild = true;
|
||||
allowempty = false;
|
||||
}
|
||||
|
||||
SEGS
|
||||
{
|
||||
required = false;
|
||||
nodebuild = true;
|
||||
allowempty = false;
|
||||
}
|
||||
|
||||
SSECTORS
|
||||
{
|
||||
required = false;
|
||||
nodebuild = true;
|
||||
allowempty = false;
|
||||
}
|
||||
|
||||
NODES
|
||||
{
|
||||
required = false;
|
||||
nodebuild = true;
|
||||
allowempty = false;
|
||||
}
|
||||
|
||||
SECTORS
|
||||
{
|
||||
required = true;
|
||||
nodebuild = true;
|
||||
allowempty = false;
|
||||
}
|
||||
|
||||
REJECT
|
||||
{
|
||||
required = false;
|
||||
nodebuild = true;
|
||||
allowempty = false;
|
||||
}
|
||||
|
||||
BLOCKMAP
|
||||
{
|
||||
required = false;
|
||||
nodebuild = true;
|
||||
allowempty = true;
|
||||
}
|
||||
}
|
||||
|
||||
udmfmaplumpnames
|
||||
{
|
||||
ZNODES
|
||||
|
@ -682,48 +484,32 @@ thingsfilters
|
|||
|
||||
}
|
||||
|
||||
//filter3
|
||||
//{
|
||||
// name = "Normal Gravity";
|
||||
// category = "";
|
||||
// type = -1;
|
||||
//
|
||||
// fields
|
||||
// {
|
||||
// 2 = false;
|
||||
// }
|
||||
//}
|
||||
|
||||
filter3
|
||||
{
|
||||
name = "Normal Gravity";
|
||||
category = "";
|
||||
type = -1;
|
||||
|
||||
fields
|
||||
{
|
||||
2 = false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
filter4
|
||||
{
|
||||
name = "Reverse Gravity";
|
||||
category = "";
|
||||
type = -1;
|
||||
|
||||
fields
|
||||
{
|
||||
2 = true;
|
||||
}
|
||||
|
||||
}
|
||||
//filter4
|
||||
//{
|
||||
// name = "Reverse Gravity";
|
||||
// category = "";
|
||||
// type = -1;
|
||||
//
|
||||
// fields
|
||||
// {
|
||||
// 2 = true;
|
||||
// }
|
||||
//}
|
||||
}
|
||||
|
||||
// Special linedefs
|
||||
speciallinedefs
|
||||
{
|
||||
soundlinedefflag = 64; // See linedefflags
|
||||
singlesidedflag = 1; // See linedefflags
|
||||
doublesidedflag = 4; // See linedefflags
|
||||
impassableflag = 1;
|
||||
upperunpeggedflag = 8;
|
||||
lowerunpeggedflag = 16;
|
||||
repeatmidtextureflag = 1024;
|
||||
pegmidtextureflag = 256;
|
||||
}
|
||||
|
||||
speciallinedefs_udmf
|
||||
{
|
||||
soundlinedefflag = "noclimb";
|
||||
|
@ -734,6 +520,8 @@ speciallinedefs_udmf
|
|||
lowerunpeggedflag = "dontpegbottom";
|
||||
repeatmidtextureflag = "wrapmidtex";
|
||||
pegmidtextureflag = "midpeg";
|
||||
slopeskewflag = "skewtd";
|
||||
nomidtextureskewflag = "noskew";
|
||||
}
|
||||
|
||||
scriptlumpnames
|
||||
|
|
|
@ -1,107 +0,0 @@
|
|||
sectortypes
|
||||
{
|
||||
0 = "Normal";
|
||||
1 = "Damage";
|
||||
2 = "Damage (Water)";
|
||||
3 = "Damage (Fire)";
|
||||
4 = "Damage (Electrical)";
|
||||
5 = "Spikes";
|
||||
6 = "Death Pit (Camera Tilt)";
|
||||
7 = "Death Pit (No Camera Tilt)";
|
||||
8 = "Instant Kill";
|
||||
9 = "Ring Drainer (Floor Touch)";
|
||||
10 = "Ring Drainer (Anywhere in Sector)";
|
||||
11 = "Special Stage Damage";
|
||||
12 = "Space Countdown";
|
||||
13 = "Ramp Sector (double step-up/down)";
|
||||
14 = "Non-Ramp Sector (no step-down)";
|
||||
15 = "Bouncy FOF <deprecated>";
|
||||
16 = "Trigger Line Ex. (Pushable Objects)";
|
||||
32 = "Trigger Line Ex. (Anywhere, All Players)";
|
||||
48 = "Trigger Line Ex. (Floor Touch, All Players)";
|
||||
64 = "Trigger Line Ex. (Anywhere in Sector)";
|
||||
80 = "Trigger Line Ex. (Floor Touch)";
|
||||
96 = "Trigger Line Ex. (Emerald Check) <deprecated>";
|
||||
112 = "Trigger Line Ex. (NiGHTS Mare) <deprecated>";
|
||||
128 = "Check for Linedef Executor on FOFs";
|
||||
144 = "Egg Capsule";
|
||||
160 = "Special Stage Time/Spheres Parameters <deprecated>";
|
||||
176 = "Custom Global Gravity <deprecated>";
|
||||
1280 = "Speed Pad";
|
||||
1536 = "Flip Gravity on Jump";
|
||||
4096 = "Star Post Activator";
|
||||
8192 = "Exit/Special Stage Pit/Return Flag";
|
||||
12288 = "CTF Red Team Base";
|
||||
16384 = "CTF Blue Team Base";
|
||||
20480 = "Fan Sector";
|
||||
24576 = "Super Sonic Transform";
|
||||
28672 = "Force Spin";
|
||||
32768 = "Zoom Tube Start";
|
||||
36864 = "Zoom Tube End";
|
||||
40960 = "Circuit Finish Line";
|
||||
45056 = "Rope Hang";
|
||||
49152 = "Intangible to the Camera";
|
||||
}
|
||||
|
||||
gen_sectortypes
|
||||
{
|
||||
first
|
||||
{
|
||||
0 = "Normal";
|
||||
1 = "Damage";
|
||||
2 = "Damage (Water)";
|
||||
3 = "Damage (Fire)";
|
||||
4 = "Damage (Electrical)";
|
||||
5 = "Spikes";
|
||||
6 = "Death Pit (Camera Tilt)";
|
||||
7 = "Death Pit (No Camera Tilt)";
|
||||
8 = "Instant Kill";
|
||||
9 = "Ring Drainer (Floor Touch)";
|
||||
10 = "Ring Drainer (Anywhere in Sector)";
|
||||
11 = "Special Stage Damage";
|
||||
12 = "Space Countdown";
|
||||
13 = "Ramp Sector (double step-up/down)";
|
||||
14 = "Non-Ramp Sector (no step-down)";
|
||||
15 = "Bouncy FOF <deprecated>";
|
||||
}
|
||||
|
||||
second
|
||||
{
|
||||
0 = "Normal";
|
||||
16 = "Trigger Line Ex. (Pushable Objects)";
|
||||
32 = "Trigger Line Ex. (Anywhere, All Players)";
|
||||
48 = "Trigger Line Ex. (Floor Touch, All Players)";
|
||||
64 = "Trigger Line Ex. (Anywhere in Sector)";
|
||||
80 = "Trigger Line Ex. (Floor Touch)";
|
||||
96 = "Trigger Line Ex. (Emerald Check) <deprecated>";
|
||||
112 = "Trigger Line Ex. (NiGHTS Mare) <deprecated>";
|
||||
128 = "Check for Linedef Executor on FOFs";
|
||||
144 = "Egg Capsule";
|
||||
160 = "Special Stage Time/Spheres Parameters <deprecated>";
|
||||
176 = "Custom Global Gravity <deprecated>";
|
||||
}
|
||||
|
||||
third
|
||||
{
|
||||
0 = "Normal";
|
||||
1280 = "Speed Pad";
|
||||
1536 = "Flip Gravity on Jump";
|
||||
}
|
||||
|
||||
fourth
|
||||
{
|
||||
0 = "Normal";
|
||||
4096 = "Star Post Activator";
|
||||
8192 = "Exit/Special Stage Pit/Return Flag";
|
||||
12288 = "CTF Red Team Base";
|
||||
16384 = "CTF Blue Team Base";
|
||||
20480 = "Fan Sector";
|
||||
24576 = "Super Sonic Transform";
|
||||
28672 = "Force Spin";
|
||||
32768 = "Zoom Tube Start";
|
||||
36864 = "Zoom Tube End";
|
||||
40960 = "Circuit Finish Line";
|
||||
45056 = "Rope Hang";
|
||||
49152 = "Intangible to the Camera";
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load diff
|
@ -1,32 +0,0 @@
|
|||
/************************************************************************\
|
||||
Ultimate Doom Builder Game Configuration for Sonic Robo Blast 2 Version 2.2
|
||||
\************************************************************************/
|
||||
|
||||
// This is required to prevent accidental use of a different configuration
|
||||
type = "Doom Builder 2 Game Configuration";
|
||||
|
||||
// This is the title to show for this game
|
||||
game = "Sonic Robo Blast 2 - 2.2 (Doom format)";
|
||||
|
||||
// This is the simplified game engine/sourceport name
|
||||
engine = "zdoom";
|
||||
|
||||
// Settings common to all games and all map formats
|
||||
include("Includes\\SRB222_common.cfg", "common");
|
||||
|
||||
// Settings common to Doom map format
|
||||
include("Includes\\SRB222_common.cfg", "mapformat_doom");
|
||||
|
||||
include("Includes\\Game_SRB222.cfg");
|
||||
|
||||
// Script lumps detection
|
||||
scriptlumpnames
|
||||
{
|
||||
include("Includes\\SRB222_misc.cfg", "scriptlumpnames");
|
||||
}
|
||||
|
||||
//Default things filters
|
||||
thingsfilters
|
||||
{
|
||||
include("Includes\\SRB222_misc.cfg", "thingsfilters");
|
||||
}
|
|
@ -76,7 +76,7 @@ LOCAL_SRC_FILES := am_map.c \
|
|||
android/i_system.c \
|
||||
android/i_video.c
|
||||
|
||||
LOCAL_CFLAGS += -DPLATFORM_ANDROID -DNONX86 -DLINUX -DDEBUGMODE -DNOASM -DNOPIX -DUNIXCOMMON -DNOTERMIOS
|
||||
LOCAL_CFLAGS += -DPLATFORM_ANDROID -DNONX86 -DLINUX -DDEBUGMODE -DNOPIX -DUNIXCOMMON -DNOTERMIOS
|
||||
|
||||
LOCAL_MODULE := libsrb2
|
||||
|
||||
|
|
|
@ -1,23 +1,150 @@
|
|||
add_executable(SRB2SDL2 MACOSX_BUNDLE WIN32)
|
||||
include(clang-tidy-default)
|
||||
|
||||
if("${CMAKE_COMPILER_IS_GNUCC}" AND "${CMAKE_SYSTEM_NAME}" MATCHES "Windows" AND NOT "${SRB2_CONFIG_SYSTEM_LIBRARIES}" AND NOT "${SRB2_CONFIG_SHARED_INTERNAL_LIBRARIES}")
|
||||
# On MinGW with internal libraries, link the standard library statically
|
||||
target_link_options(SRB2SDL2 PRIVATE "-static")
|
||||
add_executable(SRB2SDL2 MACOSX_BUNDLE WIN32
|
||||
comptime.c
|
||||
md5.c
|
||||
config.h.in
|
||||
string.c
|
||||
d_main.c
|
||||
d_clisrv.c
|
||||
d_net.c
|
||||
d_netfil.c
|
||||
d_netcmd.c
|
||||
dehacked.c
|
||||
deh_soc.c
|
||||
deh_lua.c
|
||||
deh_tables.c
|
||||
z_zone.c
|
||||
f_finale.c
|
||||
f_wipe.c
|
||||
g_demo.c
|
||||
g_game.c
|
||||
g_input.c
|
||||
am_map.c
|
||||
command.c
|
||||
console.c
|
||||
hu_stuff.c
|
||||
i_time.c
|
||||
y_inter.c
|
||||
st_stuff.c
|
||||
m_aatree.c
|
||||
m_anigif.c
|
||||
m_argv.c
|
||||
m_bbox.c
|
||||
m_cheat.c
|
||||
m_cond.c
|
||||
m_easing.c
|
||||
m_fixed.c
|
||||
m_menu.c
|
||||
m_misc.c
|
||||
m_perfstats.c
|
||||
m_random.c
|
||||
m_queue.c
|
||||
info.c
|
||||
p_ceilng.c
|
||||
p_enemy.c
|
||||
p_floor.c
|
||||
p_inter.c
|
||||
p_lights.c
|
||||
p_map.c
|
||||
p_maputl.c
|
||||
p_mobj.c
|
||||
p_polyobj.c
|
||||
p_saveg.c
|
||||
p_setup.c
|
||||
p_sight.c
|
||||
p_spec.c
|
||||
p_telept.c
|
||||
p_tick.c
|
||||
p_user.c
|
||||
p_slopes.c
|
||||
tables.c
|
||||
r_bsp.c
|
||||
r_data.c
|
||||
r_draw.c
|
||||
r_fps.c
|
||||
r_main.c
|
||||
r_plane.c
|
||||
r_segs.c
|
||||
r_skins.c
|
||||
r_sky.c
|
||||
r_splats.c
|
||||
r_things.c
|
||||
r_bbox.c
|
||||
r_textures.c
|
||||
r_patch.c
|
||||
r_patchrotation.c
|
||||
r_picformats.c
|
||||
r_portal.c
|
||||
screen.c
|
||||
taglist.c
|
||||
v_video.c
|
||||
s_sound.c
|
||||
sounds.c
|
||||
w_wad.c
|
||||
filesrch.c
|
||||
mserv.c
|
||||
http-mserv.c
|
||||
i_tcp.c
|
||||
lzf.c
|
||||
b_bot.c
|
||||
u_list.c
|
||||
lua_script.c
|
||||
lua_baselib.c
|
||||
lua_mathlib.c
|
||||
lua_hooklib.c
|
||||
lua_consolelib.c
|
||||
lua_infolib.c
|
||||
lua_mobjlib.c
|
||||
lua_playerlib.c
|
||||
lua_skinlib.c
|
||||
lua_thinkerlib.c
|
||||
lua_maplib.c
|
||||
lua_taglib.c
|
||||
lua_polyobjlib.c
|
||||
lua_blockmaplib.c
|
||||
lua_hudlib.c
|
||||
lua_hudlib_drawlist.c
|
||||
lua_inputlib.c
|
||||
)
|
||||
|
||||
# This updates the modification time for comptime.c at the
|
||||
# end of building so when the build system is ran next time,
|
||||
# that file gets flagged. comptime.c will always be rebuilt.
|
||||
#
|
||||
# This begs the question, why always rebuild comptime.c?
|
||||
# Some things like the git commit must be checked each time
|
||||
# the program is built. But the build system determines which
|
||||
# files should be rebuilt before anything else. So
|
||||
# comptime.c, which only needs to be rebuilt based on
|
||||
# information known at build time, must be told to rebuild
|
||||
# before that information can be ascertained.
|
||||
add_custom_command(
|
||||
TARGET SRB2SDL2
|
||||
POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E touch_nocreate ${CMAKE_CURRENT_SOURCE_DIR}/comptime.c
|
||||
)
|
||||
|
||||
# config.h is generated by this command. It should be done at
|
||||
# build time for accurate git information and before anything
|
||||
# that needs it, obviously.
|
||||
add_custom_target(_SRB2_reconf ALL
|
||||
COMMAND ${CMAKE_COMMAND} -DGIT_EXECUTABLE=${GIT_EXECUTABLE} -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} -DBINARY_DIR=${CMAKE_CURRENT_BINARY_DIR}/.. -P ${CMAKE_CURRENT_SOURCE_DIR}/../cmake/Comptime.cmake
|
||||
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/.."
|
||||
)
|
||||
add_dependencies(SRB2SDL2 _SRB2_reconf)
|
||||
|
||||
if("${CMAKE_COMPILER_IS_GNUCC}" AND "${CMAKE_SYSTEM_NAME}" MATCHES "Windows")
|
||||
target_link_options(SRB2SDL2 PRIVATE "-Wl,--disable-dynamicbase")
|
||||
if(NOT "${SRB2_CONFIG_SYSTEM_LIBRARIES}" AND NOT "${SRB2_CONFIG_SHARED_INTERNAL_LIBRARIES}")
|
||||
# On MinGW with internal libraries, link the standard library statically
|
||||
target_link_options(SRB2SDL2 PRIVATE "-static")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Core sources
|
||||
target_sourcefile(c)
|
||||
target_sources(SRB2SDL2 PRIVATE comptime.c md5.c config.h.in)
|
||||
|
||||
set(SRB2_ASM_SOURCES vid_copy.s)
|
||||
|
||||
set(SRB2_NASM_SOURCES tmap_mmx.nas tmap.nas)
|
||||
target_compile_features(SRB2SDL2 PRIVATE c_std_11 cxx_std_17)
|
||||
|
||||
### Configuration
|
||||
set(SRB2_CONFIG_USEASM OFF CACHE BOOL
|
||||
"Enable NASM tmap implementation for software mode speedup.")
|
||||
set(SRB2_CONFIG_YASM OFF CACHE BOOL
|
||||
"Use YASM in place of NASM.")
|
||||
set(SRB2_CONFIG_DEV_BUILD OFF CACHE BOOL
|
||||
"Compile a development build of SRB2.")
|
||||
|
||||
|
@ -74,33 +201,6 @@ if("${SRB2_CONFIG_HWRENDER}")
|
|||
endif()
|
||||
endif()
|
||||
|
||||
if(${SRB2_CONFIG_USEASM})
|
||||
#SRB2_ASM_FLAGS can be used to pass flags to either nasm or yasm.
|
||||
if("${CMAKE_SYSTEM_NAME}" MATCHES "Linux")
|
||||
set(SRB2_ASM_FLAGS "-DLINUX ${SRB2_ASM_FLAGS}")
|
||||
endif()
|
||||
|
||||
if(${SRB2_CONFIG_YASM})
|
||||
set(CMAKE_ASM_YASM_SOURCE_FILE_EXTENSIONS ${CMAKE_ASM_YASM_SOURCE_FILE_EXTENSIONS} nas)
|
||||
set(CMAKE_ASM_YASM_FLAGS "${SRB2_ASM_FLAGS}" CACHE STRING "Flags used by the assembler during all build types.")
|
||||
enable_language(ASM_YASM)
|
||||
else()
|
||||
set(CMAKE_ASM_NASM_SOURCE_FILE_EXTENSIONS ${CMAKE_ASM_NASM_SOURCE_FILE_EXTENSIONS} nas)
|
||||
set(CMAKE_ASM_NASM_FLAGS "${SRB2_ASM_FLAGS}" CACHE STRING "Flags used by the assembler during all build types.")
|
||||
enable_language(ASM_NASM)
|
||||
endif()
|
||||
|
||||
set(SRB2_USEASM ON)
|
||||
target_compile_definitions(SRB2SDL2 PRIVATE -DUSEASM)
|
||||
target_compile_options(SRB2SDL2 PRIVATE -msse3 -mfpmath=sse)
|
||||
|
||||
target_sources(SRB2SDL2 PRIVATE ${SRB2_ASM_SOURCES}
|
||||
${SRB2_NASM_SOURCES})
|
||||
else()
|
||||
set(SRB2_USEASM OFF)
|
||||
target_compile_definitions(SRB2SDL2 PRIVATE -DNONX86 -DNORUSEASM)
|
||||
endif()
|
||||
|
||||
# Targets
|
||||
|
||||
# If using CCACHE, then force it.
|
||||
|
@ -289,6 +389,9 @@ if(SRB2_CONFIG_PROFILEMODE AND "${CMAKE_C_COMPILER_ID}" STREQUAL "GNU")
|
|||
endif()
|
||||
|
||||
add_subdirectory(sdl)
|
||||
if(SRB2_CONFIG_ENABLE_TESTS)
|
||||
add_subdirectory(tests)
|
||||
endif()
|
||||
|
||||
# strip debug symbols into separate file when using gcc.
|
||||
# to be consistent with Makefile, don't generate for OS X.
|
||||
|
@ -329,3 +432,11 @@ if("${CMAKE_SYSTEM_NAME}" STREQUAL Windows AND NOT "${SRB2_CONFIG_INTERNAL_LIBRA
|
|||
COMMENT "Copying runtime DLLs"
|
||||
)
|
||||
endif()
|
||||
|
||||
# Setup clang-tidy
|
||||
if(SRB2_CONFIG_ENABLE_CLANG_TIDY_C)
|
||||
target_set_default_clang_tidy(SRB2SDL2 C "-*,clang-analyzer-*,-clang-analyzer-cplusplus-*")
|
||||
endif()
|
||||
if(SRB2_CONFIG_ENABLE_CLANG_TIDY_CXX)
|
||||
target_set_default_clang_tidy(SRB2SDL2 CXX "-*,clang-analyzer-*,modernize-*")
|
||||
endif()
|
||||
|
|
31
src/Makefile
31
src/Makefile
|
@ -47,8 +47,6 @@
|
|||
# HAVE_MINIUPNPC=1 - Enable automated port forwarding.
|
||||
# Already enabled by default for 32-bit
|
||||
# Windows.
|
||||
# NOASM=1 - Disable hand optimized assembly code for the
|
||||
# Software renderer.
|
||||
# NOPNG=1 - Disable PNG graphics support. (TODO: double
|
||||
# check netplay compatible.)
|
||||
# NOCURL=1 - Disable libcurl--HTTP capability.
|
||||
|
@ -88,7 +86,6 @@
|
|||
# executable.
|
||||
# WINDOWSHELL=1 - Use Windows commands.
|
||||
# PREFIX= - Prefix to many commands, for cross compiling.
|
||||
# YASM=1 - Use Yasm instead of NASM assembler.
|
||||
# STABS=1 - ?
|
||||
# ECHO=1 - Print out each command in the build process.
|
||||
# NOECHOFILENAMES=1 - Don't print out each that is being
|
||||
|
@ -144,25 +141,9 @@ endif
|
|||
|
||||
OBJDUMP_OPTS?=--wide --source --line-numbers
|
||||
|
||||
OBJCOPY:=$(call Prefix,objcopy)
|
||||
OBJDUMP:=$(call Prefix,objdump)
|
||||
WINDRES:=$(call Prefix,windres)
|
||||
|
||||
ifdef YASM
|
||||
NASM?=yasm
|
||||
else
|
||||
NASM?=nasm
|
||||
endif
|
||||
|
||||
ifdef YASM
|
||||
ifdef STABS
|
||||
NASMOPTS?=-g stabs
|
||||
else
|
||||
NASMOPTS?=-g dwarf2
|
||||
endif
|
||||
else
|
||||
NASMOPTS?=-g
|
||||
endif
|
||||
OBJCOPY?=$(call Prefix,objcopy)
|
||||
OBJDUMP?=$(call Prefix,objdump)
|
||||
WINDRES?=$(call Prefix,windres)
|
||||
|
||||
GZIP?=gzip
|
||||
GZIP_OPTS?=-9 -f -n
|
||||
|
@ -187,8 +168,6 @@ makedir:=../make
|
|||
opts:=-DCOMPVERSION -g
|
||||
libs:=
|
||||
|
||||
nasm_format:=
|
||||
|
||||
# This is a list of variables names, of which if defined,
|
||||
# also defines the name as a macro to the compiler.
|
||||
passthru_opts:=
|
||||
|
@ -316,7 +295,6 @@ endif
|
|||
|
||||
LD:=$(CC)
|
||||
cc:=$(cc) $(opts)
|
||||
nasm=$(NASM) $(NASMOPTS) -f $(nasm_format)
|
||||
ifdef UPX
|
||||
upx=$(UPX) $(UPX_OPTS)
|
||||
endif
|
||||
|
@ -393,7 +371,6 @@ $(objdir)/%.$(1) : %.$(2) | $$$$(@D)/
|
|||
endef
|
||||
|
||||
$(eval $(call _recipe,o,c,$(cc) -c -o $$@ $$<))
|
||||
$(eval $(call _recipe,o,nas,$(nasm) -o $$@ $$<))
|
||||
$(eval $(call _recipe,o,s,$(cc) $(asflags) -c -o $$@ $$<))
|
||||
$(eval $(call _recipe,res,rc,$(windres) -i $$< -o $$@))
|
||||
|
||||
|
@ -414,3 +391,5 @@ ifdef WINDOWSHELL
|
|||
else
|
||||
@:
|
||||
endif
|
||||
|
||||
#$(warning The handwritten GNU Makefile for SRB2 is deprecated, and may be removed in the future. Please consider switching to CMake.)
|
||||
|
|
|
@ -56,15 +56,18 @@ endif
|
|||
|
||||
# This must have high to low order.
|
||||
gcc_versions:=\
|
||||
102 101\
|
||||
93 92 91\
|
||||
84 83 82 81\
|
||||
75 74 73 72 71\
|
||||
64 63 62 61\
|
||||
55 54 53 52 51\
|
||||
132 131 130\
|
||||
123 122 121 120\
|
||||
114 113 112 111 110\
|
||||
105 104 103 102 101 100\
|
||||
95 94 93 92 91 90\
|
||||
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
|
||||
|
||||
latest_gcc_version:=10.2
|
||||
latest_gcc_version:=13.2
|
||||
|
||||
# Automatically set version flag, but not if one was
|
||||
# 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
|
||||
# also gcc outputs the information to stderr, so I had to do 2>&1
|
||||
# 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
|
||||
ifneq (,$(findstring gcc version,$(version)))
|
||||
|
||||
# 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
|
||||
v:=$(subst ., ,$(version))
|
||||
|
|
|
@ -1,75 +1,72 @@
|
|||
#
|
||||
# Makefile for feature flags.
|
||||
#
|
||||
|
||||
passthru_opts+=\
|
||||
NONET NO_IPV6 NOHW NOMD5 NOPOSTPROCESSING\
|
||||
MOBJCONSISTANCY PACKETDROP ZDEBUG\
|
||||
HAVE_MINIUPNPC\
|
||||
|
||||
# build with debugging information
|
||||
ifdef DEBUGMODE
|
||||
PACKETDROP=1
|
||||
opts+=-DPARANOIA -DRANGECHECK
|
||||
endif
|
||||
|
||||
ifndef NOHW
|
||||
opts+=-DHWRENDER
|
||||
sources+=$(call List,hardware/Sourcefile)
|
||||
endif
|
||||
|
||||
ifndef NOASM
|
||||
ifndef NONX86
|
||||
sources+=tmap.nas tmap_mmx.nas
|
||||
opts+=-DUSEASM
|
||||
endif
|
||||
endif
|
||||
|
||||
ifndef NOMD5
|
||||
sources+=md5.c
|
||||
endif
|
||||
|
||||
ifndef NOZLIB
|
||||
ifndef NOPNG
|
||||
ifdef PNG_PKGCONFIG
|
||||
$(eval $(call Use_pkg_config,PNG_PKGCONFIG))
|
||||
else
|
||||
PNG_CONFIG?=$(call Prefix,libpng-config)
|
||||
$(eval $(call Configure,PNG,$(PNG_CONFIG) \
|
||||
$(if $(PNG_STATIC),--static),,--ldflags))
|
||||
endif
|
||||
ifdef LINUX
|
||||
opts+=-D_LARGEFILE64_SOURCE
|
||||
endif
|
||||
opts+=-DHAVE_PNG
|
||||
sources+=apng.c
|
||||
endif
|
||||
endif
|
||||
|
||||
ifndef NONET
|
||||
ifndef NOCURL
|
||||
CURLCONFIG?=curl-config
|
||||
$(eval $(call Configure,CURL,$(CURLCONFIG)))
|
||||
opts+=-DHAVE_CURL
|
||||
endif
|
||||
endif
|
||||
|
||||
ifdef HAVE_MINIUPNPC
|
||||
libs+=-lminiupnpc
|
||||
endif
|
||||
|
||||
# (Valgrind is a memory debugger.)
|
||||
ifdef VALGRIND
|
||||
VALGRIND_PKGCONFIG?=valgrind
|
||||
$(eval $(call Use_pkg_config,VALGRIND))
|
||||
ZDEBUG=1
|
||||
opts+=-DHAVE_VALGRIND
|
||||
endif
|
||||
|
||||
default_packages:=\
|
||||
GME/libgme/LIBGME\
|
||||
OPENMPT/libopenmpt/LIBOPENMPT\
|
||||
ZLIB/zlib\
|
||||
|
||||
$(foreach p,$(default_packages),\
|
||||
$(eval $(call Check_pkg_config,$(p))))
|
||||
#
|
||||
# Makefile for feature flags.
|
||||
#
|
||||
|
||||
passthru_opts+=\
|
||||
NONET NO_IPV6 NOHW NOMD5 NOPOSTPROCESSING\
|
||||
MOBJCONSISTANCY PACKETDROP ZDEBUG\
|
||||
HAVE_MINIUPNPC\
|
||||
|
||||
# build with debugging information
|
||||
ifdef DEBUGMODE
|
||||
PACKETDROP=1
|
||||
opts+=-DPARANOIA -DRANGECHECK
|
||||
endif
|
||||
|
||||
ifndef NOHW
|
||||
opts+=-DHWRENDER
|
||||
sources+=$(call List,hardware/Sourcefile)
|
||||
endif
|
||||
|
||||
ifdef NONET
|
||||
NOCURL=1
|
||||
endif
|
||||
|
||||
ifndef NOMD5
|
||||
sources+=md5.c
|
||||
endif
|
||||
|
||||
ifndef NOZLIB
|
||||
ifndef NOPNG
|
||||
ifdef PNG_PKGCONFIG
|
||||
$(eval $(call Use_pkg_config,PNG_PKGCONFIG))
|
||||
else
|
||||
PNG_CONFIG?=$(call Prefix,libpng-config)
|
||||
$(eval $(call Configure,PNG,$(PNG_CONFIG) \
|
||||
$(if $(PNG_STATIC),--static),,--ldflags))
|
||||
endif
|
||||
ifdef LINUX
|
||||
opts+=-D_LARGEFILE64_SOURCE
|
||||
endif
|
||||
opts+=-DHAVE_PNG
|
||||
sources+=apng.c
|
||||
endif
|
||||
endif
|
||||
|
||||
ifndef NONET
|
||||
ifndef NOCURL
|
||||
CURLCONFIG?=curl-config
|
||||
$(eval $(call Configure,CURL,$(CURLCONFIG)))
|
||||
opts+=-DHAVE_CURL
|
||||
endif
|
||||
endif
|
||||
|
||||
ifdef HAVE_MINIUPNPC
|
||||
libs+=-lminiupnpc
|
||||
endif
|
||||
|
||||
# (Valgrind is a memory debugger.)
|
||||
ifdef VALGRIND
|
||||
VALGRIND_PKGCONFIG?=valgrind
|
||||
$(eval $(call Use_pkg_config,VALGRIND))
|
||||
ZDEBUG=1
|
||||
opts+=-DHAVE_VALGRIND
|
||||
endif
|
||||
|
||||
default_packages:=\
|
||||
GME/libgme/LIBGME\
|
||||
OPENMPT/libopenmpt/LIBOPENMPT\
|
||||
ZLIB/zlib\
|
||||
|
||||
$(foreach p,$(default_packages),\
|
||||
$(eval $(call Check_pkg_config,$(p))))
|
||||
|
|
|
@ -9,10 +9,6 @@ opts+=-DUNIXCOMMON -DLUA_USE_POSIX
|
|||
# instead of addresses
|
||||
libs+=-lm -rdynamic
|
||||
|
||||
ifndef nasm_format
|
||||
nasm_format:=elf -DLINUX
|
||||
endif
|
||||
|
||||
ifndef NOHW
|
||||
opts+=-I/usr/X11R6/include
|
||||
libs+=-L/usr/X11R6/lib
|
||||
|
@ -29,13 +25,12 @@ endif
|
|||
# Tested by Steel, as of release 2.2.8.
|
||||
ifdef FREEBSD
|
||||
opts+=-I/usr/X11R6/include -DLINUX -DFREEBSD
|
||||
libs+=-L/usr/X11R6/lib -lipx -lkvm
|
||||
libs+=-L/usr/X11R6/lib -lkvm -lexecinfo
|
||||
endif
|
||||
|
||||
# FIXME: UNTESTED
|
||||
#ifdef SOLARIS
|
||||
#NOIPX=1
|
||||
#NOASM=1
|
||||
#opts+=-I/usr/local/include -I/opt/sfw/include \
|
||||
# -DSOLARIS -DINADDR_NONE=INADDR_ANY -DBSD_COMP
|
||||
#libs+=-L/opt/sfw/lib -lsocket -lnsl
|
||||
|
|
|
@ -39,7 +39,6 @@ else ifdef SOLARIS # FIXME: UNTESTED
|
|||
UNIX=1
|
||||
platform=solaris
|
||||
else ifdef CYGWIN32 # FIXME: UNTESTED
|
||||
nasm_format=win32
|
||||
platform=cygwin
|
||||
else ifdef MINGW
|
||||
ifdef MINGW64
|
||||
|
|
|
@ -56,13 +56,6 @@ SDL_LDFLAGS?=$(shell $(SDL_CONFIG) \
|
|||
$(eval $(call Propogate_flags,SDL))
|
||||
endif
|
||||
|
||||
# use the x86 asm code
|
||||
ifndef CYGWIN32
|
||||
ifndef NOASM
|
||||
USEASM=1
|
||||
endif
|
||||
endif
|
||||
|
||||
ifdef MINGW
|
||||
ifndef NOSDLMAIN
|
||||
SDLMAIN=1
|
||||
|
|
|
@ -17,8 +17,6 @@ sources+=win32/Srb2win.rc
|
|||
opts+=-DSTDC_HEADERS
|
||||
libs+=-ladvapi32 -lkernel32 -lmsvcrt -luser32
|
||||
|
||||
nasm_format:=win32
|
||||
|
||||
SDL?=1
|
||||
|
||||
ifndef NOHW
|
||||
|
|
|
@ -64,6 +64,7 @@ r_skins.c
|
|||
r_sky.c
|
||||
r_splats.c
|
||||
r_things.c
|
||||
r_bbox.c
|
||||
r_textures.c
|
||||
r_patch.c
|
||||
r_patchrotation.c
|
||||
|
@ -80,8 +81,8 @@ mserv.c
|
|||
http-mserv.c
|
||||
i_tcp.c
|
||||
lzf.c
|
||||
vid_copy.s
|
||||
b_bot.c
|
||||
u_list.c
|
||||
lua_script.c
|
||||
lua_baselib.c
|
||||
lua_mathlib.c
|
||||
|
|
|
@ -24,7 +24,7 @@ static INT64 start_time; // as microseconds since the epoch
|
|||
|
||||
// I should probably return how much memory is remaining
|
||||
// for this process, considering Android's process memory limit.
|
||||
UINT32 I_GetFreeMem(UINT32 *total)
|
||||
size_t I_GetFreeMem(size_t *total)
|
||||
{
|
||||
// what the heck? sysinfo() is partially missing in bionic?
|
||||
/* struct sysinfo si; */
|
||||
|
@ -278,4 +278,26 @@ char *I_ClipboardPaste(void)
|
|||
|
||||
void I_RegisterSysCommands(void) {}
|
||||
|
||||
// This is identical to the SDL implementation.
|
||||
size_t I_GetRandomBytes(char *destination, size_t count)
|
||||
{
|
||||
FILE *rndsource;
|
||||
size_t actual_bytes;
|
||||
|
||||
if (!(rndsource = fopen("/dev/urandom", "r")))
|
||||
if (!(rndsource = fopen("/dev/random", "r")))
|
||||
actual_bytes = 0;
|
||||
|
||||
if (rndsource)
|
||||
{
|
||||
actual_bytes = fread(destination, 1, count, rndsource);
|
||||
fclose(rndsource);
|
||||
}
|
||||
|
||||
if (actual_bytes == 0)
|
||||
I_OutputMsg("I_GetRandomBytes(): couldn't get any random bytes");
|
||||
|
||||
return actual_bytes;
|
||||
}
|
||||
|
||||
#include "../sdl/dosstr.c"
|
||||
|
|
|
@ -1,43 +0,0 @@
|
|||
// SONIC ROBO BLAST 2
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
||||
// Copyright (C) 1999-2023 by Sonic Team Junior.
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
// See the 'LICENSE' file for more details.
|
||||
//-----------------------------------------------------------------------------
|
||||
/// \file asm_defs.inc
|
||||
/// \brief must match the C structures
|
||||
|
||||
#ifndef __ASM_DEFS__
|
||||
#define __ASM_DEFS__
|
||||
|
||||
// this makes variables more noticable,
|
||||
// and make the label match with C code
|
||||
|
||||
// Linux, unlike DOS, has no "_" 19990119 by Kin
|
||||
// and nasm needs .data code segs under linux 20010210 by metzgermeister
|
||||
// FIXME: nasm ignores these settings, so I put the macros into the makefile
|
||||
#ifdef __ELF__
|
||||
#define C(label) label
|
||||
#define CODE_SEG .data
|
||||
#else
|
||||
#define C(label) _##label
|
||||
#define CODE_SEG .text
|
||||
#endif
|
||||
|
||||
/* This is a more readable way to access the arguments passed from C code */
|
||||
/* PLEASE NOTE: it is supposed that all arguments passed from C code are */
|
||||
/* 32bit integer (INT32, long, and most *pointers) */
|
||||
#define ARG1 8(%ebp)
|
||||
#define ARG2 12(%ebp)
|
||||
#define ARG3 16(%ebp)
|
||||
#define ARG4 20(%ebp)
|
||||
#define ARG5 24(%ebp)
|
||||
#define ARG6 28(%ebp)
|
||||
#define ARG7 32(%ebp)
|
||||
#define ARG8 36(%ebp)
|
||||
#define ARG9 40(%ebp) //(c)tm ... Allegro by Shawn Hargreaves.
|
||||
|
||||
#endif
|
|
@ -631,7 +631,8 @@ void B_HandleFlightIndicator(player_t *player)
|
|||
}
|
||||
|
||||
// otherwise, update its visibility
|
||||
if (P_IsLocalPlayer(player->botleader))
|
||||
tails->hnext->drawonlyforplayer = player->botleader; // Hide it from the other player in splitscreen, and yourself when spectating
|
||||
if (P_IsLocalPlayer(player->botleader)) // Only display it on your own view. Don't display it for spectators
|
||||
tails->hnext->flags2 &= ~MF2_DONTDRAW;
|
||||
else
|
||||
tails->hnext->flags2 |= MF2_DONTDRAW;
|
||||
|
|
|
@ -1 +1,28 @@
|
|||
target_sourcefile(c)
|
||||
target_sources(SRB2SDL2 PRIVATE
|
||||
lapi.c
|
||||
lbaselib.c
|
||||
ldo.c
|
||||
lfunc.c
|
||||
linit.c
|
||||
liolib.c
|
||||
llex.c
|
||||
lmem.c
|
||||
lobject.c
|
||||
lstate.c
|
||||
lstrlib.c
|
||||
ltablib.c
|
||||
lundump.c
|
||||
lzio.c
|
||||
lauxlib.c
|
||||
lcode.c
|
||||
ldebug.c
|
||||
ldump.c
|
||||
lgc.c
|
||||
lopcodes.c
|
||||
lparser.c
|
||||
lstring.c
|
||||
ltable.c
|
||||
ltm.c
|
||||
lvm.c
|
||||
loslib.c
|
||||
)
|
||||
|
|
|
@ -23,3 +23,4 @@ lstring.c
|
|||
ltable.c
|
||||
ltm.c
|
||||
lvm.c
|
||||
loslib.c
|
||||
|
|
|
@ -18,6 +18,7 @@ static const luaL_Reg lualibs[] = {
|
|||
{"", luaopen_base},
|
||||
{LUA_TABLIBNAME, luaopen_table},
|
||||
{LUA_IOLIBNAME, luaopen_io},
|
||||
{LUA_OSLIBNAME, luaopen_os},
|
||||
{LUA_STRLIBNAME, luaopen_string},
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
|
167
src/blua/loslib.c
Normal file
167
src/blua/loslib.c
Normal file
|
@ -0,0 +1,167 @@
|
|||
/*
|
||||
** $Id: loslib.c,v 1.19.1.3 2008/01/18 16:38:18 roberto Exp $
|
||||
** Standard Operating System library
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
|
||||
|
||||
#include <errno.h>
|
||||
#include <locale.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
#define loslib_c
|
||||
#define LUA_LIB
|
||||
|
||||
#include "lua.h"
|
||||
|
||||
#include "lauxlib.h"
|
||||
#include "lualib.h"
|
||||
|
||||
|
||||
static int os_clock (lua_State *L) {
|
||||
lua_pushnumber(L, ((lua_Number)clock())/(lua_Number)CLOCKS_PER_SEC);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** {======================================================
|
||||
** Time/Date operations
|
||||
** { year=%Y, month=%m, day=%d, hour=%H, min=%M, sec=%S,
|
||||
** wday=%w+1, yday=%j, isdst=? }
|
||||
** =======================================================
|
||||
*/
|
||||
|
||||
static void setfield (lua_State *L, const char *key, int value) {
|
||||
lua_pushinteger(L, value);
|
||||
lua_setfield(L, -2, key);
|
||||
}
|
||||
|
||||
static void setboolfield (lua_State *L, const char *key, int value) {
|
||||
if (value < 0) /* undefined? */
|
||||
return; /* does not set field */
|
||||
lua_pushboolean(L, value);
|
||||
lua_setfield(L, -2, key);
|
||||
}
|
||||
|
||||
static int getboolfield (lua_State *L, const char *key) {
|
||||
int res;
|
||||
lua_getfield(L, -1, key);
|
||||
res = lua_isnil(L, -1) ? -1 : lua_toboolean(L, -1);
|
||||
lua_pop(L, 1);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
static int getfield (lua_State *L, const char *key, int d) {
|
||||
int res;
|
||||
lua_getfield(L, -1, key);
|
||||
if (lua_isnumber(L, -1))
|
||||
res = (int)lua_tointeger(L, -1);
|
||||
else {
|
||||
if (d < 0)
|
||||
return luaL_error(L, "field " LUA_QS " missing in date table", key);
|
||||
res = d;
|
||||
}
|
||||
lua_pop(L, 1);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
static int os_date (lua_State *L) {
|
||||
const char *s = luaL_optstring(L, 1, "%c");
|
||||
time_t t = luaL_opt(L, (time_t)luaL_checknumber, 2, time(NULL));
|
||||
struct tm *stm;
|
||||
if (*s == '!') { /* UTC? */
|
||||
stm = gmtime(&t);
|
||||
s++; /* skip `!' */
|
||||
}
|
||||
else
|
||||
stm = localtime(&t);
|
||||
if (stm == NULL) /* invalid date? */
|
||||
lua_pushnil(L);
|
||||
else if (strcmp(s, "*t") == 0) {
|
||||
lua_createtable(L, 0, 9); /* 9 = number of fields */
|
||||
setfield(L, "sec", stm->tm_sec);
|
||||
setfield(L, "min", stm->tm_min);
|
||||
setfield(L, "hour", stm->tm_hour);
|
||||
setfield(L, "day", stm->tm_mday);
|
||||
setfield(L, "month", stm->tm_mon+1);
|
||||
setfield(L, "year", stm->tm_year+1900);
|
||||
setfield(L, "wday", stm->tm_wday+1);
|
||||
setfield(L, "yday", stm->tm_yday+1);
|
||||
setboolfield(L, "isdst", stm->tm_isdst);
|
||||
}
|
||||
else {
|
||||
char cc[3];
|
||||
luaL_Buffer b;
|
||||
cc[0] = '%'; cc[2] = '\0';
|
||||
luaL_buffinit(L, &b);
|
||||
for (; *s; s++) {
|
||||
if (*s != '%' || *(s + 1) == '\0') /* no conversion specifier? */
|
||||
luaL_addchar(&b, *s);
|
||||
else {
|
||||
size_t reslen;
|
||||
char buff[200]; /* should be big enough for any conversion result */
|
||||
cc[1] = *(++s);
|
||||
reslen = strftime(buff, sizeof(buff), cc, stm);
|
||||
luaL_addlstring(&b, buff, reslen);
|
||||
}
|
||||
}
|
||||
luaL_pushresult(&b);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static int os_time (lua_State *L) {
|
||||
time_t t;
|
||||
if (lua_isnoneornil(L, 1)) /* called without args? */
|
||||
t = time(NULL); /* get current time */
|
||||
else {
|
||||
struct tm ts;
|
||||
luaL_checktype(L, 1, LUA_TTABLE);
|
||||
lua_settop(L, 1); /* make sure table is at the top */
|
||||
ts.tm_sec = getfield(L, "sec", 0);
|
||||
ts.tm_min = getfield(L, "min", 0);
|
||||
ts.tm_hour = getfield(L, "hour", 12);
|
||||
ts.tm_mday = getfield(L, "day", -1);
|
||||
ts.tm_mon = getfield(L, "month", -1) - 1;
|
||||
ts.tm_year = getfield(L, "year", -1) - 1900;
|
||||
ts.tm_isdst = getboolfield(L, "isdst");
|
||||
t = mktime(&ts);
|
||||
}
|
||||
if (t == (time_t)(-1))
|
||||
lua_pushnil(L);
|
||||
else
|
||||
lua_pushnumber(L, (lua_Number)t);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static int os_difftime (lua_State *L) {
|
||||
lua_pushnumber(L, difftime((time_t)(luaL_checknumber(L, 1)),
|
||||
(time_t)(luaL_optnumber(L, 2, 0))));
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* }====================================================== */
|
||||
|
||||
static const luaL_Reg syslib[] = {
|
||||
{"clock", os_clock},
|
||||
{"date", os_date},
|
||||
{"difftime", os_difftime},
|
||||
{"time", os_time},
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
/* }====================================================== */
|
||||
|
||||
|
||||
|
||||
LUALIB_API int luaopen_os (lua_State *L) {
|
||||
luaL_register(L, LUA_OSLIBNAME, syslib);
|
||||
return 1;
|
||||
}
|
|
@ -24,6 +24,9 @@ LUALIB_API int (luaopen_table) (lua_State *L);
|
|||
#define LUA_IOLIBNAME "io"
|
||||
LUALIB_API int (luaopen_io) (lua_State *L);
|
||||
|
||||
#define LUA_OSLIBNAME "os"
|
||||
LUALIB_API int (luaopen_os) (lua_State *L);
|
||||
|
||||
#define LUA_STRLIBNAME "string"
|
||||
LUALIB_API int (luaopen_string) (lua_State *L);
|
||||
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
#include "lua_script.h"
|
||||
#include "d_netfil.h" // findfile
|
||||
#include "r_data.h" // Color_cons_t
|
||||
#include "d_main.h" // D_IsPathAllowed
|
||||
|
||||
//========
|
||||
// protos.
|
||||
|
@ -75,6 +76,7 @@ CV_PossibleValue_t CV_OnOff[] = {{0, "Off"}, {1, "On"}, {0, NULL}};
|
|||
CV_PossibleValue_t CV_YesNo[] = {{0, "No"}, {1, "Yes"}, {0, NULL}};
|
||||
CV_PossibleValue_t CV_Unsigned[] = {{0, "MIN"}, {999999999, "MAX"}, {0, NULL}};
|
||||
CV_PossibleValue_t CV_Natural[] = {{1, "MIN"}, {999999999, "MAX"}, {0, NULL}};
|
||||
CV_PossibleValue_t CV_TrueFalse[] = {{0, "False"}, {1, "True"}, {0, NULL}};
|
||||
|
||||
// Filter consvars by EXECVERSION
|
||||
// First implementation is 26 (2.1.21), so earlier configs default at 25 (2.1.20)
|
||||
|
@ -679,25 +681,58 @@ static void COM_ExecuteString(char *ptext)
|
|||
// SCRIPT COMMANDS
|
||||
// =========================================================================
|
||||
|
||||
static void print_alias(void)
|
||||
{
|
||||
cmdalias_t *a;
|
||||
|
||||
CONS_Printf("\x82""Current alias commands:\n");
|
||||
for (a = com_alias; a; a = a->next)
|
||||
{
|
||||
CONS_Printf("%s : %s", a->name, a->value);
|
||||
}
|
||||
}
|
||||
|
||||
static void add_alias(char *newname, char *newcmd)
|
||||
{
|
||||
cmdalias_t *a;
|
||||
|
||||
// Check for existing aliases first
|
||||
for (a = com_alias; a; a = a->next)
|
||||
{
|
||||
if (!stricmp(newname, a->name))
|
||||
{
|
||||
Z_Free(a->value); // Free old cmd
|
||||
a->value = newcmd;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// No alias found, add it instead
|
||||
a = ZZ_Alloc(sizeof *a);
|
||||
a->next = com_alias;
|
||||
com_alias = a;
|
||||
|
||||
a->name = newname;
|
||||
a->value = newcmd;
|
||||
}
|
||||
|
||||
/** Creates a command name that replaces another command.
|
||||
*/
|
||||
static void COM_Alias_f(void)
|
||||
{
|
||||
cmdalias_t *a;
|
||||
char *name;
|
||||
char *zcmd;
|
||||
char cmd[1024];
|
||||
size_t i, c;
|
||||
|
||||
if (COM_Argc() < 3)
|
||||
{
|
||||
CONS_Printf(M_GetText("alias <name> <command>: create a shortcut command that executes other command(s)\n"));
|
||||
print_alias();
|
||||
return;
|
||||
}
|
||||
|
||||
a = ZZ_Alloc(sizeof *a);
|
||||
a->next = com_alias;
|
||||
com_alias = a;
|
||||
|
||||
a->name = Z_StrDup(COM_Argv(1));
|
||||
name = Z_StrDup(COM_Argv(1));
|
||||
|
||||
// copy the rest of the command line
|
||||
cmd[0] = 0; // start out with a null string
|
||||
|
@ -709,8 +744,8 @@ static void COM_Alias_f(void)
|
|||
strcat(cmd, " ");
|
||||
}
|
||||
strcat(cmd, "\n");
|
||||
|
||||
a->value = Z_StrDup(cmd);
|
||||
zcmd = Z_StrDup(cmd);
|
||||
add_alias(name, zcmd);
|
||||
}
|
||||
|
||||
/** Prints a line of text to the console.
|
||||
|
@ -781,6 +816,9 @@ static void COM_Exec_f(void)
|
|||
return;
|
||||
}
|
||||
|
||||
if (!D_CheckPathAllowed(COM_Argv(1), "tried to exec"))
|
||||
return;
|
||||
|
||||
// load file
|
||||
// Try with Argv passed verbatim first, for back compat
|
||||
FIL_ReadFile(COM_Argv(1), &buf);
|
||||
|
@ -859,9 +897,11 @@ static void COM_Help_f(void)
|
|||
{
|
||||
CONS_Printf(" Possible values:\n");
|
||||
if (cvar->PossibleValue == CV_YesNo)
|
||||
CONS_Printf(" Yes or No (On or Off, 1 or 0)\n");
|
||||
CONS_Printf(" Yes or No (On or Off, True or False, 1 or 0)\n");
|
||||
else if (cvar->PossibleValue == CV_OnOff)
|
||||
CONS_Printf(" On or Off (Yes or No, 1 or 0)\n");
|
||||
CONS_Printf(" On or Off (Yes or No, True or False, 1 or 0)\n");
|
||||
else if (cvar->PossibleValue == CV_TrueFalse)
|
||||
CONS_Printf(" True or False (On or Off, Yes or No, 1 or 0)\n");
|
||||
else if (cvar->PossibleValue == Color_cons_t)
|
||||
{
|
||||
for (i = 1; i < numskincolors; ++i)
|
||||
|
@ -1012,7 +1052,7 @@ static void COM_Toggle_f(void)
|
|||
if (CV_Immutable(cvar))
|
||||
return;
|
||||
|
||||
if (!(cvar->PossibleValue == CV_YesNo || cvar->PossibleValue == CV_OnOff))
|
||||
if (!(cvar->PossibleValue == CV_YesNo || cvar->PossibleValue == CV_OnOff || cvar->PossibleValue == CV_TrueFalse))
|
||||
{
|
||||
CONS_Alert(CONS_NOTICE, M_GetText("%s is not a boolean value\n"), COM_Argv(1));
|
||||
return;
|
||||
|
@ -1503,12 +1543,12 @@ static void Setvalue(consvar_t *var, const char *valstr, boolean stealth)
|
|||
goto found;
|
||||
}
|
||||
// Not found ... but wait, there's hope!
|
||||
if (var->PossibleValue == CV_OnOff || var->PossibleValue == CV_YesNo)
|
||||
if (var->PossibleValue == CV_OnOff || var->PossibleValue == CV_YesNo || var->PossibleValue == CV_TrueFalse)
|
||||
{
|
||||
overrideval = -1;
|
||||
if (!stricmp(valstr, "on") || !stricmp(valstr, "yes"))
|
||||
if (!stricmp(valstr, "on") || !stricmp(valstr, "yes") || !stricmp(valstr, "true"))
|
||||
overrideval = 1;
|
||||
else if (!stricmp(valstr, "off") || !stricmp(valstr, "no"))
|
||||
else if (!stricmp(valstr, "off") || !stricmp(valstr, "no") || !stricmp(valstr, "false"))
|
||||
overrideval = 0;
|
||||
|
||||
if (overrideval != -1)
|
||||
|
|
|
@ -177,6 +177,7 @@ extern CV_PossibleValue_t CV_OnOff[];
|
|||
extern CV_PossibleValue_t CV_YesNo[];
|
||||
extern CV_PossibleValue_t CV_Unsigned[];
|
||||
extern CV_PossibleValue_t CV_Natural[];
|
||||
extern CV_PossibleValue_t CV_TrueFalse[];
|
||||
|
||||
// Filter consvars by version
|
||||
extern consvar_t cv_execversion;
|
||||
|
|
|
@ -11,6 +11,9 @@
|
|||
#include "config.h"
|
||||
const char *compbranch = SRB2_COMP_BRANCH;
|
||||
const char *comprevision = SRB2_COMP_REVISION;
|
||||
const char *compnote = SRB2_COMP_NOTE;
|
||||
const char *comptype = CMAKE_BUILD_TYPE;
|
||||
const int compoptimized = SRB2_COMP_OPTIMIZED;
|
||||
|
||||
#elif (defined(COMPVERSION))
|
||||
#include "comptime.h"
|
||||
|
@ -21,5 +24,12 @@ const char *comprevision = "illegal";
|
|||
|
||||
#endif
|
||||
|
||||
const int compuncommitted =
|
||||
#if (defined(COMPVERSION_UNCOMMITTED))
|
||||
1;
|
||||
#else
|
||||
0;
|
||||
#endif
|
||||
|
||||
const char *compdate = __DATE__;
|
||||
const char *comptime = __TIME__;
|
||||
|
|
|
@ -11,8 +11,18 @@
|
|||
|
||||
#ifdef CMAKECONFIG
|
||||
|
||||
#define SRB2_COMP_REVISION "${SRB2_COMP_REVISION}"
|
||||
#define SRB2_COMP_BRANCH "${SRB2_COMP_BRANCH}"
|
||||
#define SRB2_COMP_REVISION "${SRB2_COMP_REVISION}"
|
||||
#define SRB2_COMP_BRANCH "${SRB2_COMP_BRANCH}"
|
||||
#define SRB2_COMP_NOTE "${SRB2_COMP_NOTE}"
|
||||
// This is done with configure_file instead of defines in order to avoid
|
||||
// recompiling the whole target whenever the working directory state changes
|
||||
#cmakedefine SRB2_COMP_UNCOMMITTED
|
||||
#ifdef SRB2_COMP_UNCOMMITTED
|
||||
#define COMPVERSION_UNCOMMITTED
|
||||
#endif
|
||||
|
||||
#define CMAKE_BUILD_TYPE "${CMAKE_BUILD_TYPE}"
|
||||
#cmakedefine01 SRB2_COMP_OPTIMIZED
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -27,12 +37,15 @@
|
|||
* Last updated 2020 / 10 / 02 - v2.2.8 - patch.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 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_ZONES_PK3 "86ae55cae4e0a93ceda868635706a093"
|
||||
#define ASSET_HASH_ZONES_PK3 "1c8adf8d079ecb87d00081f158acf3c7"
|
||||
#define ASSET_HASH_PLAYER_DTA "2e7aaae8a6b1b77d90ffe7606ceadb6c"
|
||||
#ifdef USE_PATCH_DTA
|
||||
#define ASSET_HASH_PATCH_PK3 "7d467a883f7887b3c311798ee2f56b6a"
|
||||
#define ASSET_HASH_PATCH_PK3 "3c7b73f34af7e9a7bceb2d5260f76172"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
143
src/console.c
143
src/console.c
|
@ -61,7 +61,7 @@ static boolean con_started = false; // console has been initialised
|
|||
static boolean con_forcepic = true; // at startup toggle console translucency when first off
|
||||
boolean con_recalc; // set true when screen size has changed
|
||||
|
||||
static tic_t con_tick; // console ticker for anim or blinking prompt cursor
|
||||
static tic_t con_tick; // console ticker for blinking prompt cursor
|
||||
// con_scrollup should use time (currenttime - lasttime)..
|
||||
|
||||
static boolean consoletoggle; // true when console key pushed, ticker will handle
|
||||
|
@ -72,8 +72,8 @@ static INT32 con_curlines; // vid lines currently used by console
|
|||
|
||||
INT32 con_clipviewtop; // (useless)
|
||||
|
||||
static INT32 con_hudlines; // number of console heads up message lines
|
||||
static INT32 con_hudtime[MAXHUDLINES]; // remaining time of display for hud msg lines
|
||||
static UINT8 con_hudlines; // number of console heads up message lines
|
||||
static UINT32 con_hudtime[MAXHUDLINES]; // remaining time of display for hud msg lines
|
||||
|
||||
INT32 con_clearlines; // top screen lines to refresh when view reduced
|
||||
boolean con_hudupdate; // when messages scroll, we need a backgrnd refresh
|
||||
|
@ -110,6 +110,7 @@ static void CON_RecalcSize(void);
|
|||
static void CON_ChangeHeight(void);
|
||||
|
||||
static void CON_DrawBackpic(void);
|
||||
static void CONS_height_Change(void);
|
||||
static void CONS_hudlines_Change(void);
|
||||
static void CONS_backcolor_Change(void);
|
||||
|
||||
|
@ -125,10 +126,13 @@ static void CONS_backcolor_Change(void);
|
|||
static char con_buffer[CON_BUFFERSIZE];
|
||||
|
||||
// how many seconds the hud messages lasts on the screen
|
||||
static consvar_t cons_msgtimeout = CVAR_INIT ("con_hudtime", "5", CV_SAVE, CV_Unsigned, NULL);
|
||||
// CV_Unsigned can overflow when multiplied by TICRATE later, so let's use a 3-year limit instead
|
||||
static CV_PossibleValue_t hudtime_cons_t[] = {{0, "MIN"}, {99999999, "MAX"}, {0, NULL}};
|
||||
static consvar_t cons_hudtime = CVAR_INIT ("con_hudtime", "5", CV_SAVE, hudtime_cons_t, NULL);
|
||||
|
||||
// number of lines displayed on the HUD
|
||||
static consvar_t cons_hudlines = CVAR_INIT ("con_hudlines", "5", CV_CALL|CV_SAVE, CV_Unsigned, CONS_hudlines_Change);
|
||||
static CV_PossibleValue_t hudlines_cons_t[] = {{0, "MIN"}, {MAXHUDLINES, "MAX"}, {0, NULL}};
|
||||
static consvar_t cons_hudlines = CVAR_INIT ("con_hudlines", "5", CV_CALL|CV_SAVE, hudlines_cons_t, CONS_hudlines_Change);
|
||||
|
||||
// number of lines console move per frame
|
||||
// (con_speed needs a limit, apparently)
|
||||
|
@ -136,7 +140,7 @@ static CV_PossibleValue_t speed_cons_t[] = {{0, "MIN"}, {64, "MAX"}, {0, NULL}};
|
|||
static consvar_t cons_speed = CVAR_INIT ("con_speed", "8", CV_SAVE, speed_cons_t, NULL);
|
||||
|
||||
// percentage of screen height to use for console
|
||||
static consvar_t cons_height = CVAR_INIT ("con_height", "50", CV_SAVE, CV_Unsigned, NULL);
|
||||
static consvar_t cons_height = CVAR_INIT ("con_height", "50", CV_CALL|CV_SAVE, CV_Unsigned, CONS_height_Change);
|
||||
|
||||
static CV_PossibleValue_t backpic_cons_t[] = {{0, "translucent"}, {1, "picture"}, {0, NULL}};
|
||||
// whether to use console background picture, or translucent mode
|
||||
|
@ -156,6 +160,18 @@ consvar_t cons_backcolor = CVAR_INIT ("con_backcolor", "Green", CV_CALL|CV_SAVE,
|
|||
|
||||
static void CON_Print(char *msg);
|
||||
|
||||
// Change the console height on demand
|
||||
//
|
||||
static void CONS_height_Change(void)
|
||||
{
|
||||
Lock_state();
|
||||
|
||||
if (con_destlines > 0 && !con_startup) // If the console is open (as in, not using "bind")...
|
||||
CON_ChangeHeight(); // ...update its height now, not only when it's closed and re-opened
|
||||
|
||||
Unlock_state();
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
static void CONS_hudlines_Change(void)
|
||||
|
@ -168,11 +184,6 @@ static void CONS_hudlines_Change(void)
|
|||
for (i = 0; i < con_hudlines; i++)
|
||||
con_hudtime[i] = 0;
|
||||
|
||||
if (cons_hudlines.value < 1)
|
||||
cons_hudlines.value = 1;
|
||||
else if (cons_hudlines.value > MAXHUDLINES)
|
||||
cons_hudlines.value = MAXHUDLINES;
|
||||
|
||||
con_hudlines = cons_hudlines.value;
|
||||
|
||||
Unlock_state();
|
||||
|
@ -382,16 +393,16 @@ static void CON_SetupColormaps(void)
|
|||
|
||||
// 0x1 0x3 0x9 0xF
|
||||
colset(magentamap, 177, 177, 178, 178, 178, 180, 180, 180, 182, 182, 182, 182, 184, 184, 184, 185);
|
||||
colset(yellowmap, 82, 82, 73, 73, 73, 64, 64, 64, 66, 66, 66, 66, 67, 67, 67, 68);
|
||||
colset(lgreenmap, 96, 96, 98, 98, 98, 101, 101, 101, 104, 104, 104, 104, 106, 106, 106, 107);
|
||||
colset(bluemap, 146, 146, 147, 147, 147, 149, 149, 149, 152, 152, 152, 152, 155, 155, 155, 157);
|
||||
colset(redmap, 32, 32, 33, 33, 33, 35, 35, 35, 39, 39, 39, 39, 42, 42, 42, 44);
|
||||
colset(yellowmap, 82, 82, 73, 73, 73, 74, 74, 74, 66, 66, 66, 66, 67, 67, 67, 68);
|
||||
colset(lgreenmap, 96, 96, 98, 98, 98, 100, 100, 100, 103, 103, 103, 103, 105, 105, 105, 107);
|
||||
colset(bluemap, 146, 146, 147, 147, 147, 148, 148, 148, 149, 149, 149, 149, 150, 150, 150, 151);
|
||||
colset(redmap, 32, 32, 33, 33, 33, 34, 34, 34, 35, 35, 35, 35, 37, 37, 37, 39);
|
||||
colset(graymap, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23);
|
||||
colset(orangemap, 50, 50, 52, 52, 52, 54, 54, 54, 56, 56, 56, 56, 59, 59, 59, 60);
|
||||
colset(skymap, 129, 129, 130, 130, 130, 131, 131, 131, 133, 133, 133, 133, 135, 135, 135, 136);
|
||||
colset(purplemap, 160, 160, 161, 161, 161, 162, 162, 162, 163, 163, 163, 163, 164, 164, 164, 165);
|
||||
colset(aquamap, 120, 120, 121, 121, 121, 122, 122, 122, 123, 123, 123, 123, 124, 124, 124, 125);
|
||||
colset(peridotmap, 72, 72, 188, 188, 189, 189, 189, 189, 190, 190, 190, 190, 191, 191, 191, 94);
|
||||
colset(peridotmap, 73, 73, 188, 188, 188, 189, 189, 189, 190, 190, 190, 190, 191, 191, 191, 94);
|
||||
colset(azuremap, 144, 144, 145, 145, 145, 146, 146, 146, 170, 170, 170, 170, 171, 171, 171, 172);
|
||||
colset(brownmap, 219, 219, 221, 221, 221, 222, 222, 222, 224, 224, 224, 224, 227, 227, 227, 229);
|
||||
colset(rosymap, 200, 200, 201, 201, 201, 202, 202, 202, 203, 203, 203, 203, 204, 204, 204, 205);
|
||||
|
@ -464,7 +475,7 @@ void CON_Init(void)
|
|||
|
||||
Unlock_state();
|
||||
|
||||
CV_RegisterVar(&cons_msgtimeout);
|
||||
CV_RegisterVar(&cons_hudtime);
|
||||
CV_RegisterVar(&cons_hudlines);
|
||||
CV_RegisterVar(&cons_speed);
|
||||
CV_RegisterVar(&cons_height);
|
||||
|
@ -643,33 +654,39 @@ static void CON_ChangeHeight(void)
|
|||
//
|
||||
static void CON_MoveConsole(void)
|
||||
{
|
||||
fixed_t conspeed;
|
||||
static fixed_t fracmovement = 0;
|
||||
|
||||
Lock_state();
|
||||
|
||||
conspeed = FixedDiv(cons_speed.value*vid.fdupy, FRACUNIT);
|
||||
|
||||
// instant
|
||||
if (!cons_speed.value)
|
||||
{
|
||||
con_curlines = con_destlines;
|
||||
Unlock_state();
|
||||
return;
|
||||
}
|
||||
|
||||
// up/down move to dest
|
||||
if (con_curlines < con_destlines)
|
||||
// Not instant - Increment fracmovement fractionally
|
||||
fracmovement += FixedMul(cons_speed.value*vid.fdupy, renderdeltatics);
|
||||
|
||||
if (con_curlines < con_destlines) // Move the console downwards
|
||||
{
|
||||
con_curlines += FixedInt(conspeed);
|
||||
if (con_curlines > con_destlines)
|
||||
con_curlines = con_destlines;
|
||||
con_curlines += FixedInt(fracmovement); // Move by fracmovement's integer value
|
||||
if (con_curlines > con_destlines) // If we surpassed the destination...
|
||||
con_curlines = con_destlines; // ...clamp to it!
|
||||
}
|
||||
else if (con_curlines > con_destlines)
|
||||
else // Move the console upwards
|
||||
{
|
||||
con_curlines -= FixedInt(conspeed);
|
||||
con_curlines -= FixedInt(fracmovement);
|
||||
if (con_curlines < con_destlines)
|
||||
con_curlines = con_destlines;
|
||||
|
||||
if (con_destlines == 0) // If the console is being closed, not just moved up...
|
||||
con_tick = 0; // ...don't show the blinking cursor
|
||||
}
|
||||
|
||||
fracmovement %= FRACUNIT; // Reset fracmovement's integer value, but keep the fraction
|
||||
|
||||
Unlock_state();
|
||||
}
|
||||
|
||||
|
@ -752,10 +769,6 @@ void CON_Ticker(void)
|
|||
CON_ChangeHeight();
|
||||
}
|
||||
|
||||
// console movement
|
||||
if (con_destlines != con_curlines)
|
||||
CON_MoveConsole();
|
||||
|
||||
// clip the view, so that the part under the console is not drawn
|
||||
con_clipviewtop = -1;
|
||||
if (cons_backpic.value) // clip only when using an opaque background
|
||||
|
@ -777,9 +790,8 @@ void CON_Ticker(void)
|
|||
// make overlay messages disappear after a while
|
||||
for (i = 0; i < con_hudlines; i++)
|
||||
{
|
||||
con_hudtime[i]--;
|
||||
if (con_hudtime[i] < 0)
|
||||
con_hudtime[i] = 0;
|
||||
if (con_hudtime[i])
|
||||
con_hudtime[i]--;
|
||||
}
|
||||
|
||||
Unlock_state();
|
||||
|
@ -1328,7 +1340,8 @@ boolean CON_Responder(event_t *ev)
|
|||
static void CON_Linefeed(void)
|
||||
{
|
||||
// set time for heads up messages
|
||||
con_hudtime[con_cy%con_hudlines] = cons_msgtimeout.value*TICRATE;
|
||||
if (con_hudlines)
|
||||
con_hudtime[con_cy%con_hudlines] = cons_hudtime.value*TICRATE;
|
||||
|
||||
con_cy++;
|
||||
con_cx = 0;
|
||||
|
@ -1684,7 +1697,7 @@ static void CON_DrawHudlines(void)
|
|||
INT32 charwidth = 8 * con_scalefactor;
|
||||
INT32 charheight = 8 * con_scalefactor;
|
||||
|
||||
if (con_hudlines <= 0)
|
||||
if (!con_hudlines)
|
||||
return;
|
||||
|
||||
if (chat_on && OLDCHAT)
|
||||
|
@ -1692,7 +1705,7 @@ static void CON_DrawHudlines(void)
|
|||
else
|
||||
y = 0;
|
||||
|
||||
for (i = con_cy - con_hudlines+1; i <= con_cy; i++)
|
||||
for (i = con_cy - con_hudlines; i <= con_cy; i++)
|
||||
{
|
||||
size_t c;
|
||||
INT32 x;
|
||||
|
@ -1809,41 +1822,41 @@ static void CON_DrawConsole(void)
|
|||
}
|
||||
|
||||
// draw console text lines from top to bottom
|
||||
if (con_curlines < minheight)
|
||||
return;
|
||||
|
||||
i = con_cy - con_scrollup;
|
||||
|
||||
// skip the last empty line due to the cursor being at the start of a new line
|
||||
i--;
|
||||
|
||||
i -= (con_curlines - minheight) / charheight;
|
||||
|
||||
if (rendermode == render_none) return;
|
||||
|
||||
for (y = (con_curlines-minheight) % charheight; y <= con_curlines-minheight; y += charheight, i++)
|
||||
if (con_curlines >= minheight)
|
||||
{
|
||||
INT32 x;
|
||||
size_t c;
|
||||
i = con_cy - con_scrollup;
|
||||
|
||||
p = (UINT8 *)&con_buffer[((i > 0 ? i : 0)%con_totallines)*con_width];
|
||||
// skip the last empty line due to the cursor being at the start of a new line
|
||||
i--;
|
||||
|
||||
for (c = 0, x = charwidth; c < con_width; c++, x += charwidth, p++)
|
||||
i -= (con_curlines - minheight) / charheight;
|
||||
|
||||
if (rendermode == render_none) return;
|
||||
|
||||
for (y = (con_curlines-minheight) % charheight; y <= con_curlines-minheight; y += charheight, i++)
|
||||
{
|
||||
while (*p & 0x80)
|
||||
INT32 x;
|
||||
size_t c;
|
||||
|
||||
p = (UINT8 *)&con_buffer[((i > 0 ? i : 0)%con_totallines)*con_width];
|
||||
|
||||
for (c = 0, x = charwidth; c < con_width; c++, x += charwidth, p++)
|
||||
{
|
||||
charflags = (*p & 0x7f) << V_CHARCOLORSHIFT;
|
||||
p++;
|
||||
c++;
|
||||
while (*p & 0x80)
|
||||
{
|
||||
charflags = (*p & 0x7f) << V_CHARCOLORSHIFT;
|
||||
p++;
|
||||
c++;
|
||||
}
|
||||
if (c >= con_width)
|
||||
break;
|
||||
V_DrawCharacter(x, y, (INT32)(*p) | charflags | cv_constextsize.value | V_NOSCALESTART, true);
|
||||
}
|
||||
if (c >= con_width)
|
||||
break;
|
||||
V_DrawCharacter(x, y, (INT32)(*p) | charflags | cv_constextsize.value | V_NOSCALESTART, true);
|
||||
}
|
||||
}
|
||||
|
||||
// draw prompt if enough place (not while game startup)
|
||||
if ((con_curlines == con_destlines) && (con_curlines >= minheight) && !con_startup)
|
||||
if ((con_curlines >= (minheight-charheight)) && !con_startup)
|
||||
CON_DrawInput();
|
||||
}
|
||||
|
||||
|
@ -1866,11 +1879,15 @@ void CON_Drawer(void)
|
|||
CON_ClearHUD();
|
||||
}
|
||||
|
||||
// console movement
|
||||
if (con_curlines != con_destlines)
|
||||
CON_MoveConsole();
|
||||
|
||||
if (con_curlines > 0)
|
||||
CON_DrawConsole();
|
||||
else if (gamestate == GS_LEVEL
|
||||
|| gamestate == GS_INTERMISSION || gamestate == GS_ENDING || gamestate == GS_CUTSCENE
|
||||
|| gamestate == GS_CREDITS || gamestate == GS_EVALUATION)
|
||||
|| gamestate == GS_CREDITS || gamestate == GS_EVALUATION || gamestate == GS_WAITINGPLAYERS)
|
||||
CON_DrawHudlines();
|
||||
|
||||
Unlock_state();
|
||||
|
|
329
src/d_clisrv.c
329
src/d_clisrv.c
|
@ -120,6 +120,8 @@ UINT8 hu_redownloadinggamestate = 0;
|
|||
// true when a player is connecting or disconnecting so that the gameplay has stopped in its tracks
|
||||
boolean hu_stopped = false;
|
||||
|
||||
consvar_t cv_dedicatedidletime = CVAR_INIT ("dedicatedidletime", "10", CV_SAVE, CV_Unsigned, NULL);
|
||||
|
||||
UINT8 adminpassmd5[16];
|
||||
boolean adminpasswordset = false;
|
||||
|
||||
|
@ -1293,6 +1295,7 @@ static boolean CL_AskFileList(INT32 firstfile)
|
|||
static boolean CL_SendJoin(void)
|
||||
{
|
||||
UINT8 localplayers = 1;
|
||||
char const *player2name;
|
||||
if (netgame)
|
||||
CONS_Printf(M_GetText("Sending join request...\n"));
|
||||
netbuffer->packettype = PT_CLIENTJOIN;
|
||||
|
@ -1309,18 +1312,23 @@ static boolean CL_SendJoin(void)
|
|||
CleanupPlayerName(consoleplayer, cv_playername.zstring);
|
||||
if (splitscreen)
|
||||
CleanupPlayerName(1, cv_playername2.zstring);/* 1 is a HACK? oh no */
|
||||
// Avoid empty string on bots to avoid softlocking in singleplayer
|
||||
if (botingame)
|
||||
player2name = strcmp(cv_playername.zstring, "Tails") == 0 ? "Tail" : "Tails";
|
||||
else
|
||||
player2name = cv_playername2.zstring;
|
||||
|
||||
strncpy(netbuffer->u.clientcfg.names[0], cv_playername.zstring, MAXPLAYERNAME);
|
||||
strncpy(netbuffer->u.clientcfg.names[1], cv_playername2.zstring, MAXPLAYERNAME);
|
||||
strncpy(netbuffer->u.clientcfg.names[1], player2name, MAXPLAYERNAME);
|
||||
|
||||
return HSendPacket(servernode, true, 0, sizeof (clientconfig_pak));
|
||||
}
|
||||
|
||||
static INT32 FindRejoinerNum(SINT8 node)
|
||||
{
|
||||
char strippednodeaddress[64];
|
||||
char addressbuffer[64];
|
||||
const char *nodeaddress;
|
||||
char *port;
|
||||
const char *strippednodeaddress;
|
||||
INT32 i;
|
||||
|
||||
// Make sure there is no dead dress before proceeding to the stripping
|
||||
|
@ -1331,10 +1339,8 @@ static INT32 FindRejoinerNum(SINT8 node)
|
|||
return -1;
|
||||
|
||||
// Strip the address of its port
|
||||
strcpy(strippednodeaddress, nodeaddress);
|
||||
port = strchr(strippednodeaddress, ':');
|
||||
if (port)
|
||||
*port = '\0';
|
||||
strcpy(addressbuffer, nodeaddress);
|
||||
strippednodeaddress = I_NetSplitAddress(addressbuffer, NULL);
|
||||
|
||||
// Check if any player matches the stripped address
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
|
@ -1506,6 +1512,7 @@ static boolean SV_SendServerConfig(INT32 node)
|
|||
netbuffer->u.servercfg.gamestate = (UINT8)gamestate;
|
||||
netbuffer->u.servercfg.gametype = (UINT8)gametype;
|
||||
netbuffer->u.servercfg.modifiedgame = (UINT8)modifiedgame;
|
||||
netbuffer->u.servercfg.usedCheats = (UINT8)usedCheats;
|
||||
|
||||
memcpy(netbuffer->u.servercfg.server_context, server_context, 8);
|
||||
|
||||
|
@ -2486,7 +2493,7 @@ static boolean CL_ServerConnectionTicker(const char *tmpsave, tic_t *oldtic, tic
|
|||
{
|
||||
if (!snake)
|
||||
{
|
||||
F_MenuPresTicker(true); // title sky
|
||||
F_MenuPresTicker(); // title sky
|
||||
F_TitleScreenTicker(true);
|
||||
F_TitleScreenDrawer();
|
||||
}
|
||||
|
@ -2601,6 +2608,8 @@ static void CL_ConnectToServer(void)
|
|||
}
|
||||
while (!(cl_mode == CL_CONNECTED && (client || (server && nodewaited <= pnumnodes))));
|
||||
|
||||
if (netgame)
|
||||
F_StartWaitingPlayers();
|
||||
DEBFILE(va("Synchronisation Finished\n"));
|
||||
|
||||
displayplayer = consoleplayer;
|
||||
|
@ -2734,7 +2743,6 @@ static void Command_ClearBans(void)
|
|||
static void Ban_Load_File(boolean warning)
|
||||
{
|
||||
FILE *f;
|
||||
size_t i;
|
||||
const char *address, *mask;
|
||||
char buffer[MAX_WADPATH];
|
||||
|
||||
|
@ -2752,7 +2760,7 @@ static void Ban_Load_File(boolean warning)
|
|||
|
||||
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");
|
||||
mask = strtok(NULL, " \t\r\n");
|
||||
|
@ -3644,6 +3652,9 @@ void SV_ResetServer(void)
|
|||
|
||||
CV_RevertNetVars();
|
||||
|
||||
// Ensure synched when creating a new server
|
||||
M_CopyGameData(serverGamedata, clientGamedata);
|
||||
|
||||
DEBFILE("\n-=-=-=-=-=-=-= Server Reset =-=-=-=-=-=-=-\n\n");
|
||||
}
|
||||
|
||||
|
@ -3767,14 +3778,13 @@ static void Got_AddPlayer(UINT8 **p, INT32 playernum)
|
|||
|
||||
if (server && I_GetNodeAddress)
|
||||
{
|
||||
char addressbuffer[64];
|
||||
const char *address = I_GetNodeAddress(node);
|
||||
char *port = NULL;
|
||||
if (address) // MI: fix msvcrt.dll!_mbscat crash?
|
||||
{
|
||||
strcpy(playeraddress[newplayernum], address);
|
||||
port = strchr(playeraddress[newplayernum], ':');
|
||||
if (port)
|
||||
*port = '\0';
|
||||
strcpy(addressbuffer, address);
|
||||
strcpy(playeraddress[newplayernum],
|
||||
I_NetSplitAddress(addressbuffer, NULL));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4406,6 +4416,8 @@ static void HandlePacketFromAwayNode(SINT8 node)
|
|||
maketic = gametic = neededtic = (tic_t)LONG(netbuffer->u.servercfg.gametic);
|
||||
G_SetGametype(netbuffer->u.servercfg.gametype);
|
||||
modifiedgame = netbuffer->u.servercfg.modifiedgame;
|
||||
if (netbuffer->u.servercfg.usedCheats)
|
||||
G_SetUsedCheats(true);
|
||||
memcpy(server_context, netbuffer->u.servercfg.server_context, 8);
|
||||
}
|
||||
|
||||
|
@ -4515,6 +4527,7 @@ static void HandlePacketFromPlayer(SINT8 node)
|
|||
netconsole = 0;
|
||||
else
|
||||
netconsole = nodetoplayer[node];
|
||||
|
||||
#ifdef PARANOIA
|
||||
if (netconsole >= MAXPLAYERS)
|
||||
I_Error("bad table nodetoplayer: node %d player %d", doomcom->remotenode, netconsole);
|
||||
|
@ -4553,21 +4566,32 @@ static void HandlePacketFromPlayer(SINT8 node)
|
|||
// Update the nettics
|
||||
nettics[node] = realend;
|
||||
|
||||
// Don't do anything for packets of type NODEKEEPALIVE?
|
||||
if (netconsole == -1 || netbuffer->packettype == PT_NODEKEEPALIVE
|
||||
|| netbuffer->packettype == PT_NODEKEEPALIVEMIS)
|
||||
// This should probably still timeout though, as the node should always have a player 1 number
|
||||
if (netconsole == -1)
|
||||
break;
|
||||
|
||||
// As long as clients send valid ticcmds, the server can keep running, so reset the timeout
|
||||
/// \todo Use a separate cvar for that kind of timeout?
|
||||
freezetimeout[node] = I_GetTime() + connectiontimeout;
|
||||
|
||||
// Don't do anything for packets of type NODEKEEPALIVE?
|
||||
// Sryder 2018/07/01: Update the freezetimeout still!
|
||||
if (netbuffer->packettype == PT_NODEKEEPALIVE
|
||||
|| netbuffer->packettype == PT_NODEKEEPALIVEMIS)
|
||||
break;
|
||||
|
||||
// If we've alredy received a ticcmd for this tic, just submit it for the next one.
|
||||
tic_t faketic = maketic;
|
||||
if ((!!(netcmds[maketic % BACKUPTICS][netconsole].angleturn & TICCMD_RECEIVED))
|
||||
&& (maketic - firstticstosend < BACKUPTICS - 1))
|
||||
faketic++;
|
||||
|
||||
// Copy ticcmd
|
||||
G_MoveTiccmd(&netcmds[maketic%BACKUPTICS][netconsole], &netbuffer->u.clientpak.cmd, 1);
|
||||
G_MoveTiccmd(&netcmds[faketic%BACKUPTICS][netconsole], &netbuffer->u.clientpak.cmd, 1);
|
||||
|
||||
// Check ticcmd for "speed hacks"
|
||||
if (netcmds[maketic%BACKUPTICS][netconsole].forwardmove > MAXPLMOVE || netcmds[maketic%BACKUPTICS][netconsole].forwardmove < -MAXPLMOVE
|
||||
|| netcmds[maketic%BACKUPTICS][netconsole].sidemove > MAXPLMOVE || netcmds[maketic%BACKUPTICS][netconsole].sidemove < -MAXPLMOVE)
|
||||
if (netcmds[faketic%BACKUPTICS][netconsole].forwardmove > MAXPLMOVE || netcmds[faketic%BACKUPTICS][netconsole].forwardmove < -MAXPLMOVE
|
||||
|| netcmds[faketic%BACKUPTICS][netconsole].sidemove > MAXPLMOVE || netcmds[faketic%BACKUPTICS][netconsole].sidemove < -MAXPLMOVE)
|
||||
{
|
||||
CONS_Alert(CONS_WARNING, M_GetText("Illegal movement value received from node %d\n"), netconsole);
|
||||
//D_Clearticcmd(k);
|
||||
|
@ -4579,9 +4603,10 @@ static void HandlePacketFromPlayer(SINT8 node)
|
|||
// Splitscreen cmd
|
||||
if ((netbuffer->packettype == PT_CLIENT2CMD || netbuffer->packettype == PT_CLIENT2MIS)
|
||||
&& nodetoplayer2[node] >= 0)
|
||||
G_MoveTiccmd(&netcmds[maketic%BACKUPTICS][(UINT8)nodetoplayer2[node]],
|
||||
G_MoveTiccmd(&netcmds[faketic%BACKUPTICS][(UINT8)nodetoplayer2[node]],
|
||||
&netbuffer->u.client2pak.cmd2, 1);
|
||||
|
||||
|
||||
// Check player consistancy during the level
|
||||
if (realstart <= gametic && realstart + BACKUPTICS - 1 > gametic && gamestate == GS_LEVEL
|
||||
&& consistancy[realstart%BACKUPTICS] != SHORT(netbuffer->u.clientpak.consistancy)
|
||||
|
@ -4618,6 +4643,21 @@ static void HandlePacketFromPlayer(SINT8 node)
|
|||
}
|
||||
}
|
||||
break;
|
||||
case PT_BASICKEEPALIVE:
|
||||
if (client)
|
||||
break;
|
||||
|
||||
// This should probably still timeout though, as the node should always have a player 1 number
|
||||
if (netconsole == -1)
|
||||
break;
|
||||
|
||||
// If a client sends this it should mean they are done receiving the savegame
|
||||
sendingsavegame[node] = false;
|
||||
|
||||
// As long as clients send keep alives, the server can keep running, so reset the timeout
|
||||
/// \todo Use a separate cvar for that kind of timeout?
|
||||
freezetimeout[node] = I_GetTime() + connectiontimeout;
|
||||
break;
|
||||
case PT_TEXTCMD2: // splitscreen special
|
||||
netconsole = nodetoplayer2[node];
|
||||
/* FALLTHRU */
|
||||
|
@ -5044,39 +5084,66 @@ static INT16 Consistancy(void)
|
|||
return (INT16)(ret & 0xFFFF);
|
||||
}
|
||||
|
||||
// confusing, but this DOESN'T send PT_NODEKEEPALIVE, it sends PT_BASICKEEPALIVE
|
||||
// used during wipes to tell the server that a node is still connected
|
||||
static void CL_SendClientKeepAlive(void)
|
||||
{
|
||||
netbuffer->packettype = PT_BASICKEEPALIVE;
|
||||
|
||||
HSendPacket(servernode, false, 0, 0);
|
||||
}
|
||||
|
||||
static void SV_SendServerKeepAlive(void)
|
||||
{
|
||||
INT32 n;
|
||||
|
||||
for (n = 1; n < MAXNETNODES; n++)
|
||||
{
|
||||
if (nodeingame[n])
|
||||
{
|
||||
netbuffer->packettype = PT_BASICKEEPALIVE;
|
||||
HSendPacket(n, false, 0, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// send the client packet to the server
|
||||
static void CL_SendClientCmd(void)
|
||||
{
|
||||
size_t packetsize = 0;
|
||||
boolean mis = false;
|
||||
|
||||
netbuffer->packettype = PT_CLIENTCMD;
|
||||
|
||||
if (cl_packetmissed)
|
||||
netbuffer->packettype++;
|
||||
{
|
||||
netbuffer->packettype = PT_CLIENTMIS;
|
||||
mis = true;
|
||||
}
|
||||
|
||||
netbuffer->u.clientpak.resendfrom = (UINT8)(neededtic & UINT8_MAX);
|
||||
netbuffer->u.clientpak.client_tic = (UINT8)(gametic & UINT8_MAX);
|
||||
|
||||
if (gamestate == GS_WAITINGPLAYERS)
|
||||
{
|
||||
// Send PT_NODEKEEPALIVE packet
|
||||
netbuffer->packettype += 4;
|
||||
netbuffer->packettype = (mis ? PT_NODEKEEPALIVEMIS : PT_NODEKEEPALIVE);
|
||||
packetsize = sizeof (clientcmd_pak) - sizeof (ticcmd_t) - sizeof (INT16);
|
||||
HSendPacket(servernode, false, 0, packetsize);
|
||||
}
|
||||
else if (gamestate != GS_NULL && (addedtogame || dedicated))
|
||||
{
|
||||
packetsize = sizeof (clientcmd_pak);
|
||||
G_MoveTiccmd(&netbuffer->u.clientpak.cmd, &localcmds, 1);
|
||||
netbuffer->u.clientpak.consistancy = SHORT(consistancy[gametic%BACKUPTICS]);
|
||||
|
||||
// Send a special packet with 2 cmd for splitscreen
|
||||
if (splitscreen || botingame)
|
||||
{
|
||||
netbuffer->packettype += 2;
|
||||
G_MoveTiccmd(&netbuffer->u.client2pak.cmd2, &localcmds2, 1);
|
||||
netbuffer->packettype = (mis ? PT_CLIENT2MIS : PT_CLIENT2CMD);
|
||||
packetsize = sizeof (client2cmd_pak);
|
||||
G_MoveTiccmd(&netbuffer->u.client2pak.cmd2, &localcmds2, 1);
|
||||
}
|
||||
else
|
||||
packetsize = sizeof (clientcmd_pak);
|
||||
|
||||
HSendPacket(servernode, false, 0, packetsize);
|
||||
}
|
||||
|
@ -5087,7 +5154,7 @@ static void CL_SendClientCmd(void)
|
|||
if (localtextcmd[0])
|
||||
{
|
||||
netbuffer->packettype = PT_TEXTCMD;
|
||||
M_Memcpy(netbuffer->u.textcmd,localtextcmd, localtextcmd[0]+1);
|
||||
M_Memcpy(netbuffer->u.textcmd, localtextcmd, localtextcmd[0]+1);
|
||||
// All extra data have been sent
|
||||
if (HSendPacket(servernode, true, 0, localtextcmd[0]+1)) // Send can fail...
|
||||
localtextcmd[0] = 0;
|
||||
|
@ -5467,28 +5534,11 @@ static inline void PingUpdate(void)
|
|||
pingmeasurecount = 1; //Reset count
|
||||
}
|
||||
|
||||
void NetUpdate(void)
|
||||
static tic_t gametime = 0;
|
||||
|
||||
static void UpdatePingTable(void)
|
||||
{
|
||||
static tic_t gametime = 0;
|
||||
static tic_t resptime = 0;
|
||||
tic_t nowtime;
|
||||
INT32 i;
|
||||
INT32 realtics;
|
||||
|
||||
nowtime = I_GetTime();
|
||||
realtics = nowtime - gametime;
|
||||
|
||||
if (realtics <= 0) // nothing new to update
|
||||
return;
|
||||
if (realtics > 5)
|
||||
{
|
||||
if (server)
|
||||
realtics = 1;
|
||||
else
|
||||
realtics = 5;
|
||||
}
|
||||
|
||||
gametime = nowtime;
|
||||
|
||||
if (server)
|
||||
{
|
||||
|
@ -5500,6 +5550,150 @@ void NetUpdate(void)
|
|||
realpingtable[i] += G_TicsToMilliseconds(GetLag(playernode[i]));
|
||||
pingmeasurecount++;
|
||||
}
|
||||
}
|
||||
|
||||
// Handle timeouts to prevent definitive freezes from happenning
|
||||
static void HandleNodeTimeouts(void)
|
||||
{
|
||||
INT32 i;
|
||||
|
||||
if (server)
|
||||
{
|
||||
for (i = 1; i < MAXNETNODES; i++)
|
||||
if (nodeingame[i] && freezetimeout[i] < I_GetTime())
|
||||
Net_ConnectionTimeout(i);
|
||||
|
||||
// In case the cvar value was lowered
|
||||
if (joindelay)
|
||||
joindelay = min(joindelay - 1, 3 * (tic_t)cv_joindelay.value * TICRATE);
|
||||
}
|
||||
}
|
||||
|
||||
// Keep the network alive while not advancing tics!
|
||||
void NetKeepAlive(void)
|
||||
{
|
||||
tic_t nowtime;
|
||||
INT32 realtics;
|
||||
|
||||
nowtime = I_GetTime();
|
||||
realtics = nowtime - gametime;
|
||||
|
||||
// return if there's no time passed since the last call
|
||||
if (realtics <= 0) // nothing new to update
|
||||
return;
|
||||
|
||||
UpdatePingTable();
|
||||
|
||||
GetPackets();
|
||||
|
||||
#ifdef MASTERSERVER
|
||||
MasterClient_Ticker();
|
||||
#endif
|
||||
|
||||
if (client)
|
||||
{
|
||||
// send keep alive
|
||||
CL_SendClientKeepAlive();
|
||||
// No need to check for resynch because we aren't running any tics
|
||||
}
|
||||
else
|
||||
{
|
||||
SV_SendServerKeepAlive();
|
||||
}
|
||||
|
||||
// No else because no tics are being run and we can't resynch during this
|
||||
|
||||
Net_AckTicker();
|
||||
HandleNodeTimeouts();
|
||||
FileSendTicker();
|
||||
}
|
||||
|
||||
void NetUpdate(void)
|
||||
{
|
||||
static tic_t resptime = 0;
|
||||
tic_t nowtime;
|
||||
INT32 i;
|
||||
INT32 realtics;
|
||||
|
||||
nowtime = I_GetTime();
|
||||
realtics = nowtime - gametime;
|
||||
|
||||
if (realtics <= 0) // nothing new to update
|
||||
return;
|
||||
|
||||
if (realtics > 5)
|
||||
{
|
||||
if (server)
|
||||
realtics = 1;
|
||||
else
|
||||
realtics = 5;
|
||||
}
|
||||
|
||||
if (server && dedicated && gamestate == GS_LEVEL)
|
||||
{
|
||||
const tic_t dedicatedidletime = cv_dedicatedidletime.value * TICRATE;
|
||||
static tic_t dedicatedidletimeprev = 0;
|
||||
static tic_t dedicatedidle = 0;
|
||||
|
||||
if (dedicatedidletime > 0)
|
||||
{
|
||||
for (i = 1; i < MAXNETNODES; ++i)
|
||||
if (nodeingame[i])
|
||||
{
|
||||
if (dedicatedidle >= dedicatedidletime)
|
||||
{
|
||||
CONS_Printf("DEDICATED: Awakening from idle (Node %d detected...)\n", i);
|
||||
dedicatedidle = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (i == MAXNETNODES)
|
||||
{
|
||||
if (leveltime == 2)
|
||||
{
|
||||
// On next tick...
|
||||
dedicatedidle = dedicatedidletime-1;
|
||||
}
|
||||
else if (dedicatedidle >= dedicatedidletime)
|
||||
{
|
||||
if (D_GetExistingTextcmd(gametic, 0) || D_GetExistingTextcmd(gametic+1, 0))
|
||||
{
|
||||
CONS_Printf("DEDICATED: Awakening from idle (Netxcmd detected...)\n");
|
||||
dedicatedidle = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
realtics = 0;
|
||||
}
|
||||
}
|
||||
else if ((dedicatedidle += realtics) >= dedicatedidletime)
|
||||
{
|
||||
const char *idlereason = "at round start";
|
||||
if (leveltime > 3)
|
||||
idlereason = va("for %d seconds", dedicatedidle/TICRATE);
|
||||
|
||||
CONS_Printf("DEDICATED: No nodes %s, idling...\n", idlereason);
|
||||
realtics = 0;
|
||||
dedicatedidle = dedicatedidletime;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (dedicatedidletimeprev > 0 && dedicatedidle >= dedicatedidletimeprev)
|
||||
{
|
||||
CONS_Printf("DEDICATED: Awakening from idle (Idle disabled...)\n");
|
||||
}
|
||||
dedicatedidle = 0;
|
||||
}
|
||||
|
||||
dedicatedidletimeprev = dedicatedidletime;
|
||||
}
|
||||
|
||||
gametime = nowtime;
|
||||
|
||||
UpdatePingTable();
|
||||
|
||||
if (client)
|
||||
maketic = neededtic;
|
||||
|
@ -5531,25 +5725,26 @@ void NetUpdate(void)
|
|||
}
|
||||
else
|
||||
{
|
||||
if (!demoplayback)
|
||||
if (!demoplayback && realtics > 0)
|
||||
{
|
||||
INT32 counts;
|
||||
|
||||
hu_redownloadinggamestate = false;
|
||||
|
||||
firstticstosend = gametic;
|
||||
for (i = 0; i < MAXNETNODES; i++)
|
||||
if (nodeingame[i] && nettics[i] < firstticstosend)
|
||||
{
|
||||
firstticstosend = nettics[i];
|
||||
|
||||
if (maketic + 1 >= nettics[i] + BACKUPTICS)
|
||||
Net_ConnectionTimeout(i);
|
||||
}
|
||||
|
||||
// Don't erase tics not acknowledged
|
||||
counts = realtics;
|
||||
|
||||
firstticstosend = gametic;
|
||||
for (i = 0; i < MAXNETNODES; i++)
|
||||
{
|
||||
if (!nodeingame[i])
|
||||
continue;
|
||||
if (nettics[i] < firstticstosend)
|
||||
firstticstosend = nettics[i];
|
||||
if (maketic + counts >= nettics[i] + (BACKUPTICS - TICRATE))
|
||||
Net_ConnectionTimeout(i);
|
||||
}
|
||||
|
||||
if (maketic + counts >= firstticstosend + BACKUPTICS)
|
||||
counts = firstticstosend+BACKUPTICS-maketic-1;
|
||||
|
||||
|
@ -5566,20 +5761,10 @@ void NetUpdate(void)
|
|||
}
|
||||
|
||||
Net_AckTicker();
|
||||
|
||||
// Handle timeouts to prevent definitive freezes from happenning
|
||||
if (server)
|
||||
{
|
||||
for (i = 1; i < MAXNETNODES; i++)
|
||||
if (nodeingame[i] && freezetimeout[i] < I_GetTime())
|
||||
Net_ConnectionTimeout(i);
|
||||
|
||||
// In case the cvar value was lowered
|
||||
if (joindelay)
|
||||
joindelay = min(joindelay - 1, 3 * (tic_t)cv_joindelay.value * TICRATE);
|
||||
}
|
||||
HandleNodeTimeouts();
|
||||
|
||||
nowtime /= NEWTICRATERATIO;
|
||||
|
||||
if (nowtime > resptime)
|
||||
{
|
||||
resptime = nowtime;
|
||||
|
|
|
@ -77,6 +77,8 @@ typedef enum
|
|||
PT_ASKLUAFILE, // Client telling the server they don't have the file
|
||||
PT_HASLUAFILE, // Client telling the server they have the file
|
||||
|
||||
PT_BASICKEEPALIVE,// Keep the network alive during wipes, as tics aren't advanced and NetUpdate isn't called
|
||||
|
||||
// Add non-PT_CANFAIL packet types here to avoid breaking MS compatibility.
|
||||
|
||||
PT_CANFAIL, // This is kind of a priority. Anything bigger than CANFAIL
|
||||
|
@ -158,6 +160,7 @@ typedef struct
|
|||
|
||||
UINT8 gametype;
|
||||
UINT8 modifiedgame;
|
||||
UINT8 usedCheats;
|
||||
|
||||
char server_context[8]; // Unique context id, generated at server startup.
|
||||
} ATTRPACK serverconfig_pak;
|
||||
|
@ -397,6 +400,7 @@ extern tic_t servermaxping;
|
|||
extern consvar_t cv_netticbuffer, cv_allownewplayer, cv_joinnextround, cv_maxplayers, cv_joindelay, cv_rejointimeout;
|
||||
extern consvar_t cv_resynchattempts, cv_blamecfail;
|
||||
extern consvar_t cv_maxsend, cv_noticedownload, cv_downloadspeed;
|
||||
extern consvar_t cv_dedicatedidletime;
|
||||
|
||||
// Used in d_net, the only dependence
|
||||
tic_t ExpandTics(INT32 low, INT32 node);
|
||||
|
@ -411,6 +415,9 @@ void SendKick(UINT8 playernum, UINT8 msg);
|
|||
// Create any new ticcmds and broadcast to other players.
|
||||
void NetUpdate(void);
|
||||
|
||||
// Maintain connections to nodes without timing them all out.
|
||||
void NetKeepAlive(void);
|
||||
|
||||
void SV_StartSinglePlayerServer(void);
|
||||
boolean SV_SpawnServer(void);
|
||||
void SV_StopServer(void);
|
||||
|
|
146
src/d_main.c
146
src/d_main.c
|
@ -70,6 +70,8 @@
|
|||
#include "filesrch.h" // refreshdirmenu
|
||||
#include "g_input.h" // tutorial mode control scheming
|
||||
#include "m_perfstats.h"
|
||||
#include "m_random.h"
|
||||
#include "command.h"
|
||||
|
||||
#ifdef CMAKECONFIG
|
||||
#include "config.h"
|
||||
|
@ -458,6 +460,13 @@ static void D_Display(void)
|
|||
|
||||
case GS_WAITINGPLAYERS:
|
||||
// The clientconnect drawer is independent...
|
||||
if (netgame)
|
||||
{
|
||||
// I don't think HOM from nothing drawing is independent...
|
||||
F_WaitingPlayersDrawer();
|
||||
HU_Erase();
|
||||
HU_Drawer();
|
||||
}
|
||||
case GS_DEDICATEDSERVER:
|
||||
case GS_NULL:
|
||||
break;
|
||||
|
@ -1208,6 +1217,15 @@ D_ConvertVersionNumbers (void)
|
|||
#endif
|
||||
}
|
||||
|
||||
static void Command_assert(void)
|
||||
{
|
||||
#if !defined(NDEBUG) || defined(PARANOIA)
|
||||
CONS_Printf("Yes, assertions are enabled.\n");
|
||||
#else
|
||||
CONS_Printf("No, assertions are NOT enabled.\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
//
|
||||
// D_SRB2Main
|
||||
//
|
||||
|
@ -1221,6 +1239,11 @@ void D_SRB2Main(void)
|
|||
/* break the version string into version numbers, for netplay */
|
||||
D_ConvertVersionNumbers();
|
||||
|
||||
if (!strcmp(compbranch, ""))
|
||||
{
|
||||
compbranch = "detached HEAD";
|
||||
}
|
||||
|
||||
// Print GPL notice for our console users (Linux)
|
||||
CONS_Printf(
|
||||
"\n\nSonic Robo Blast 2\n"
|
||||
|
@ -1334,11 +1357,12 @@ void D_SRB2Main(void)
|
|||
snprintf(addonsdir, sizeof addonsdir, "%s%s%s", srb2home, PATHSEP, "addons");
|
||||
I_mkdir(addonsdir, 0755);
|
||||
|
||||
// rand() needs seeded regardless of password
|
||||
srand((unsigned int)time(NULL));
|
||||
rand();
|
||||
rand();
|
||||
rand();
|
||||
// seed M_Random because it is necessary; seed P_Random for scripts that
|
||||
// might want to use random numbers immediately at start
|
||||
if (!M_RandomSeedFromOS())
|
||||
M_RandomSeed((UINT32)time(NULL)); // less good but serviceable
|
||||
|
||||
P_SetRandSeed(M_RandomizedSeed());
|
||||
|
||||
if (M_CheckParm("-password") && M_IsNextParm())
|
||||
D_SetPassword(M_GetNextParm());
|
||||
|
@ -1350,9 +1374,14 @@ void D_SRB2Main(void)
|
|||
CONS_Printf("Z_Init(): Init zone memory allocation daemon. \n");
|
||||
Z_Init();
|
||||
|
||||
clientGamedata = M_NewGameDataStruct();
|
||||
serverGamedata = M_NewGameDataStruct();
|
||||
|
||||
// Do this up here so that WADs loaded through the command line can use ExecCfg
|
||||
COM_Init();
|
||||
|
||||
COM_AddCommand("assert", Command_assert, COM_LUA);
|
||||
|
||||
// Add any files specified on the command line with
|
||||
// "-file <file>" or "-folder <folder>" to the add-on list
|
||||
if (!((M_GetUrlProtocolArg() || M_CheckParm("-connect")) && !M_CheckParm("-server")))
|
||||
|
@ -1473,7 +1502,15 @@ void D_SRB2Main(void)
|
|||
//--------------------------------------------------------- CONFIG.CFG
|
||||
M_FirstLoadConfig(); // WARNING : this do a "COM_BufExecute()"
|
||||
|
||||
G_LoadGameData();
|
||||
if (M_CheckParm("-gamedata") && M_IsNextParm())
|
||||
{
|
||||
// Moved from G_LoadGameData itself, as it would cause some crazy
|
||||
// confusion issues when loading mods.
|
||||
strlcpy(gamedatafilename, M_GetNextParm(), sizeof gamedatafilename);
|
||||
}
|
||||
|
||||
G_LoadGameData(clientGamedata);
|
||||
M_CopyGameData(serverGamedata, clientGamedata);
|
||||
|
||||
#if defined (__unix__) || defined (UNIXCOMMON) || defined (HAVE_SDL)
|
||||
VID_PrepareModeList(); // Regenerate Modelist according to cv_fullscreen
|
||||
|
@ -1500,7 +1537,7 @@ void D_SRB2Main(void)
|
|||
else
|
||||
{
|
||||
if (!M_CheckParm("-server"))
|
||||
G_SetGameModified(true);
|
||||
G_SetUsedCheats(true);
|
||||
autostart = true;
|
||||
}
|
||||
}
|
||||
|
@ -1700,14 +1737,15 @@ void D_SRB2Main(void)
|
|||
// Prevent warping to nonexistent levels
|
||||
if (W_CheckNumForName(G_BuildMapName(pstartmap)) == LUMPERROR)
|
||||
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))
|
||||
I_Error("You need to unlock this level before you can warp to it!\n");
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
@ -1777,3 +1815,85 @@ const char *D_Home(void)
|
|||
if (usehome) return userhome;
|
||||
else return NULL;
|
||||
}
|
||||
|
||||
static boolean check_top_dir(const char **path, const char *top)
|
||||
{
|
||||
// empty string does NOT match
|
||||
if (!strcmp(top, ""))
|
||||
return false;
|
||||
|
||||
if (!startswith(*path, top))
|
||||
return false;
|
||||
|
||||
*path += strlen(top);
|
||||
|
||||
// if it doesn't already end with a path separator,
|
||||
// check if a separator follows
|
||||
if (!endswith(top, PATHSEP))
|
||||
{
|
||||
if (startswith(*path, PATHSEP))
|
||||
*path += strlen(PATHSEP);
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static int cmp_strlen_desc(const void *a, const void *b)
|
||||
{
|
||||
return ((int)strlen(*(const char*const*)b) - (int)strlen(*(const char*const*)a));
|
||||
}
|
||||
|
||||
boolean D_IsPathAllowed(const char *path)
|
||||
{
|
||||
const char *paths[] = {
|
||||
srb2home,
|
||||
srb2path,
|
||||
cv_addons_folder.string
|
||||
};
|
||||
|
||||
const size_t n_paths = sizeof paths / sizeof *paths;
|
||||
|
||||
size_t i;
|
||||
|
||||
// Sort folder paths by longest to shortest so
|
||||
// overlapping paths work. E.g.:
|
||||
// Path 1: /home/james/.srb2/addons
|
||||
// Path 2: /home/james/.srb2
|
||||
qsort(paths, n_paths, sizeof *paths, cmp_strlen_desc);
|
||||
|
||||
// These paths are allowed to be absolute
|
||||
// path is offset so ".." can be checked only in the
|
||||
// rest of the path
|
||||
for (i = 0; i < n_paths; ++i)
|
||||
{
|
||||
if (check_top_dir(&path, paths[i]))
|
||||
break;
|
||||
}
|
||||
|
||||
// Only if none of the presets matched
|
||||
if (i == n_paths)
|
||||
{
|
||||
// Cannot be an absolute path
|
||||
if (M_IsPathAbsolute(path))
|
||||
return false;
|
||||
}
|
||||
|
||||
// Cannot traverse upwards
|
||||
if (strstr(path, ".."))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
boolean D_CheckPathAllowed(const char *path, const char *why)
|
||||
{
|
||||
if (!D_IsPathAllowed(path))
|
||||
{
|
||||
CONS_Alert(CONS_WARNING, "%s: %s, location is not allowed\n", why, path);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -44,6 +44,9 @@ void D_ProcessEvents(void);
|
|||
|
||||
const char *D_Home(void);
|
||||
|
||||
boolean D_IsPathAllowed(const char *path);
|
||||
boolean D_CheckPathAllowed(const char *path, const char *why);
|
||||
|
||||
//
|
||||
// BASE LEVEL
|
||||
//
|
||||
|
|
29
src/d_net.c
29
src/d_net.c
|
@ -869,6 +869,9 @@ static void DebugPrintpacket(const char *header)
|
|||
(UINT32)ExpandTics(netbuffer->u.clientpak.client_tic, doomcom->remotenode),
|
||||
(UINT32)ExpandTics (netbuffer->u.clientpak.resendfrom, doomcom->remotenode));
|
||||
break;
|
||||
case PT_BASICKEEPALIVE:
|
||||
fprintf(debugfile, " wipetime\n");
|
||||
break;
|
||||
case PT_TEXTCMD:
|
||||
case PT_TEXTCMD2:
|
||||
fprintf(debugfile, " length %d\n ", netbuffer->u.textcmd[0]);
|
||||
|
@ -1207,26 +1210,32 @@ static void Internal_FreeNodenum(INT32 nodenum)
|
|||
(void)nodenum;
|
||||
}
|
||||
|
||||
char *I_NetSplitAddress(char *host, char **port)
|
||||
{
|
||||
boolean v4 = (strchr(host, '.') != NULL);
|
||||
|
||||
host = strtok(host, v4 ? ":" : "[]");
|
||||
|
||||
if (port)
|
||||
*port = strtok(NULL, ":");
|
||||
|
||||
return host;
|
||||
}
|
||||
|
||||
SINT8 I_NetMakeNode(const char *hostname)
|
||||
{
|
||||
SINT8 newnode = -1;
|
||||
if (I_NetMakeNodewPort)
|
||||
{
|
||||
char *localhostname = strdup(hostname);
|
||||
char *t = localhostname;
|
||||
const char *port;
|
||||
char *port;
|
||||
if (!localhostname)
|
||||
return newnode;
|
||||
|
||||
// retrieve portnum from address!
|
||||
strtok(localhostname, ":");
|
||||
port = strtok(NULL, ":");
|
||||
hostname = I_NetSplitAddress(localhostname, &port);
|
||||
|
||||
// remove the port in the hostname as we've it already
|
||||
while ((*t != ':') && (*t != '\0'))
|
||||
t++;
|
||||
*t = '\0';
|
||||
|
||||
newnode = I_NetMakeNodewPort(localhostname, port);
|
||||
newnode = I_NetMakeNodewPort(hostname, port);
|
||||
free(localhostname);
|
||||
}
|
||||
return newnode;
|
||||
|
|
212
src/d_netcmd.c
212
src/d_netcmd.c
|
@ -49,7 +49,7 @@
|
|||
#include "m_anigif.h"
|
||||
#include "md5.h"
|
||||
#include "m_perfstats.h"
|
||||
#include "hardware/u_list.h" // TODO: this should be a standard utility class
|
||||
#include "u_list.h"
|
||||
|
||||
#ifdef NETGAME_DEVMODE
|
||||
#define CV_RESTRICT CV_NETVAR
|
||||
|
@ -599,6 +599,7 @@ void D_RegisterServerCommands(void)
|
|||
CV_RegisterVar(&cv_joinnextround);
|
||||
CV_RegisterVar(&cv_showjoinaddress);
|
||||
CV_RegisterVar(&cv_blamecfail);
|
||||
CV_RegisterVar(&cv_dedicatedidletime);
|
||||
#endif
|
||||
|
||||
COM_AddCommand("ping", Command_Ping_f, COM_LUA);
|
||||
|
@ -613,6 +614,10 @@ void D_RegisterServerCommands(void)
|
|||
|
||||
CV_RegisterVar(&cv_allowseenames);
|
||||
|
||||
// Other filesrch.c consvars are defined in D_RegisterClientCommands
|
||||
CV_RegisterVar(&cv_addons_option);
|
||||
CV_RegisterVar(&cv_addons_folder);
|
||||
|
||||
CV_RegisterVar(&cv_dummyconsvar);
|
||||
}
|
||||
|
||||
|
@ -771,6 +776,8 @@ void D_RegisterClientCommands(void)
|
|||
CV_RegisterVar(&cv_showfocuslost);
|
||||
CV_RegisterVar(&cv_pauseifunfocused);
|
||||
|
||||
CV_RegisterVar(&cv_instantretry);
|
||||
|
||||
// g_input.c
|
||||
CV_RegisterVar(&cv_sideaxis);
|
||||
CV_RegisterVar(&cv_sideaxis2);
|
||||
|
@ -794,8 +801,8 @@ void D_RegisterClientCommands(void)
|
|||
CV_RegisterVar(&cv_digitaldeadzone2);
|
||||
|
||||
// filesrch.c
|
||||
CV_RegisterVar(&cv_addons_option);
|
||||
CV_RegisterVar(&cv_addons_folder);
|
||||
//CV_RegisterVar(&cv_addons_option); // These two are now defined
|
||||
//CV_RegisterVar(&cv_addons_folder); // in D_RegisterServerCommands
|
||||
CV_RegisterVar(&cv_addons_md5);
|
||||
CV_RegisterVar(&cv_addons_showall);
|
||||
CV_RegisterVar(&cv_addons_search_type);
|
||||
|
@ -869,10 +876,15 @@ void D_RegisterClientCommands(void)
|
|||
// screen.c
|
||||
CV_RegisterVar(&cv_fullscreen);
|
||||
CV_RegisterVar(&cv_renderview);
|
||||
CV_RegisterVar(&cv_renderhitboxinterpolation);
|
||||
CV_RegisterVar(&cv_renderhitboxgldepth);
|
||||
CV_RegisterVar(&cv_renderhitbox);
|
||||
CV_RegisterVar(&cv_renderer);
|
||||
CV_RegisterVar(&cv_scr_depth);
|
||||
CV_RegisterVar(&cv_scr_width);
|
||||
CV_RegisterVar(&cv_scr_height);
|
||||
CV_RegisterVar(&cv_scr_width_w);
|
||||
CV_RegisterVar(&cv_scr_height_w);
|
||||
|
||||
CV_RegisterVar(&cv_soundtest);
|
||||
|
||||
|
@ -1633,9 +1645,14 @@ static void Command_Playdemo_f(void)
|
|||
{
|
||||
char name[256];
|
||||
|
||||
if (COM_Argc() != 2)
|
||||
if (COM_Argc() < 2)
|
||||
{
|
||||
CONS_Printf(M_GetText("playdemo <demoname>: playback a demo\n"));
|
||||
CONS_Printf("playdemo <demoname> [-addfiles / -force]:\n");
|
||||
CONS_Printf(M_GetText(
|
||||
"Play back a demo file. The full path from your SRB2 directory must be given.\n\n"
|
||||
|
||||
"* With \"-addfiles\", any required files are added from a list contained within the demo file.\n"
|
||||
"* With \"-force\", the demo is played even if the necessary files have not been added.\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1657,6 +1674,16 @@ static void Command_Playdemo_f(void)
|
|||
|
||||
CONS_Printf(M_GetText("Playing back demo '%s'.\n"), name);
|
||||
|
||||
demofileoverride = DFILE_OVERRIDE_NONE;
|
||||
if (strcmp(COM_Argv(2), "-addfiles") == 0)
|
||||
{
|
||||
demofileoverride = DFILE_OVERRIDE_LOAD;
|
||||
}
|
||||
else if (strcmp(COM_Argv(2), "-force") == 0)
|
||||
{
|
||||
demofileoverride = DFILE_OVERRIDE_SKIP;
|
||||
}
|
||||
|
||||
// Internal if no extension, external if one exists
|
||||
// If external, convert the file name to a path in SRB2's home directory
|
||||
if (FIL_CheckExtension(name))
|
||||
|
@ -1877,8 +1904,8 @@ static void Command_Map_f(void)
|
|||
size_t option_gametype;
|
||||
const char *gametypename;
|
||||
boolean newresetplayers;
|
||||
|
||||
boolean mustmodifygame;
|
||||
boolean prevent_cheat;
|
||||
boolean set_cheated;
|
||||
|
||||
INT32 newmapnum;
|
||||
|
||||
|
@ -1899,21 +1926,34 @@ static void Command_Map_f(void)
|
|||
option_gametype = COM_CheckPartialParm("-g");
|
||||
newresetplayers = ! COM_CheckParm("-noresetplayers");
|
||||
|
||||
mustmodifygame =
|
||||
!( netgame || multiplayer ) &&
|
||||
(!modifiedgame || savemoddata );
|
||||
prevent_cheat = !( usedCheats ) && !( option_force || cv_debug );
|
||||
set_cheated = false;
|
||||
|
||||
if (mustmodifygame && !option_force)
|
||||
if (!( netgame || multiplayer ))
|
||||
{
|
||||
/* May want to be more descriptive? */
|
||||
CONS_Printf(M_GetText("Sorry, level change disabled in single player.\n"));
|
||||
return;
|
||||
if (prevent_cheat)
|
||||
{
|
||||
/* May want to be more descriptive? */
|
||||
CONS_Printf(M_GetText("Cheats must be enabled to level change in single player.\n"));
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
set_cheated = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!newresetplayers && !cv_debug)
|
||||
if (!newresetplayers)
|
||||
{
|
||||
CONS_Printf(M_GetText("DEVMODE must be enabled.\n"));
|
||||
return;
|
||||
if (prevent_cheat)
|
||||
{
|
||||
CONS_Printf(M_GetText("Cheats must be enabled to use -noresetplayers.\n"));
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
set_cheated = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (option_gametype)
|
||||
|
@ -1921,7 +1961,7 @@ static void Command_Map_f(void)
|
|||
if (!multiplayer)
|
||||
{
|
||||
CONS_Printf(M_GetText(
|
||||
"You can't switch gametypes in single player!\n"));
|
||||
"You can't switch gametypes in single player!\n"));
|
||||
return;
|
||||
}
|
||||
else if (COM_Argc() < option_gametype + 2)/* no argument after? */
|
||||
|
@ -1934,7 +1974,9 @@ static void Command_Map_f(void)
|
|||
}
|
||||
|
||||
if (!( first_option = COM_FirstOption() ))
|
||||
{
|
||||
first_option = COM_Argc();
|
||||
}
|
||||
|
||||
if (first_option < 2)
|
||||
{
|
||||
|
@ -1957,11 +1999,6 @@ static void Command_Map_f(void)
|
|||
return;
|
||||
}
|
||||
|
||||
if (mustmodifygame && option_force)
|
||||
{
|
||||
G_SetGameModified(false);
|
||||
}
|
||||
|
||||
// new gametype value
|
||||
// use current one by default
|
||||
if (option_gametype)
|
||||
|
@ -2003,15 +2040,13 @@ static void Command_Map_f(void)
|
|||
}
|
||||
|
||||
// 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
|
||||
else
|
||||
if (!(
|
||||
mapheaderinfo[newmapnum-1] &&
|
||||
mapheaderinfo[newmapnum-1]->typeoflevel & G_TOLFlag(newgametype)
|
||||
))
|
||||
{
|
||||
if (!(
|
||||
mapheaderinfo[newmapnum-1] &&
|
||||
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),
|
||||
(multiplayer ? gametype_cons_t[newgametype].strvalue : "Single Player"));
|
||||
|
@ -2021,23 +2056,33 @@ static void Command_Map_f(void)
|
|||
}
|
||||
else
|
||||
{
|
||||
fromlevelselect =
|
||||
( netgame || multiplayer ) &&
|
||||
newgametype == gametype &&
|
||||
gametypedefaultrules[newgametype] & GTR_CAMPAIGN;
|
||||
// The player wants us to trek on anyway. Do so.
|
||||
fromlevelselect = false;
|
||||
set_cheated = ((gametypedefaultrules[newgametype] & GTR_CAMPAIGN) == GTR_CAMPAIGN);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
fromlevelselect =
|
||||
( netgame || multiplayer ) &&
|
||||
newgametype == gametype &&
|
||||
(gametypedefaultrules[newgametype] & GTR_CAMPAIGN);
|
||||
}
|
||||
|
||||
// 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.
|
||||
if (!dedicated && M_MapLocked(newmapnum))
|
||||
if (M_CampaignWarpIsCheat(newgametype, newmapnum, serverGamedata))
|
||||
{
|
||||
CONS_Alert(CONS_NOTICE, M_GetText("You need to unlock this level before you can warp to it!\n"));
|
||||
Z_Free(realmapname);
|
||||
Z_Free(mapname);
|
||||
return;
|
||||
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(mapname);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
set_cheated = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Ultimate Mode only in SP via menu
|
||||
|
@ -2054,6 +2099,11 @@ static void Command_Map_f(void)
|
|||
}
|
||||
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);
|
||||
|
||||
Z_Free(realmapname);
|
||||
|
@ -2095,11 +2145,13 @@ static void Got_Mapcmd(UINT8 **cp, INT32 playernum)
|
|||
|
||||
lastgametype = gametype;
|
||||
gametype = READUINT8(*cp);
|
||||
G_SetGametype(gametype); // I fear putting that macro as an argument
|
||||
|
||||
if (gametype < 0 || gametype >= gametypecount)
|
||||
gametype = lastgametype;
|
||||
else if (gametype != lastgametype)
|
||||
else
|
||||
G_SetGametype(gametype);
|
||||
|
||||
if (gametype != lastgametype)
|
||||
D_GameTypeChanged(lastgametype); // emulate consvar_t behavior for gametype
|
||||
|
||||
skipprecutscene = ((flags & (1<<2)) != 0);
|
||||
|
@ -2121,12 +2173,6 @@ static void Got_Mapcmd(UINT8 **cp, INT32 playernum)
|
|||
if (demoplayback && !timingdemo)
|
||||
precache = false;
|
||||
|
||||
if (resetplayer && !FLS)
|
||||
{
|
||||
emeralds = 0;
|
||||
memset(&luabanks, 0, sizeof(luabanks));
|
||||
}
|
||||
|
||||
if (modeattacking)
|
||||
{
|
||||
SetPlayerSkinByNum(0, cv_chooseskin.value-1);
|
||||
|
@ -2167,7 +2213,7 @@ static void Command_Pause(void)
|
|||
|
||||
if (cv_pause.value || server || (IsPlayerAdmin(consoleplayer)))
|
||||
{
|
||||
if (modeattacking || !(gamestate == GS_LEVEL || gamestate == GS_INTERMISSION) || (marathonmode && gamestate == GS_INTERMISSION))
|
||||
if (modeattacking || !(gamestate == GS_LEVEL || gamestate == GS_INTERMISSION || gamestate == GS_WAITINGPLAYERS) || (marathonmode && gamestate == GS_INTERMISSION))
|
||||
{
|
||||
CONS_Printf(M_GetText("You can't pause here.\n"));
|
||||
return;
|
||||
|
@ -2330,7 +2376,7 @@ static void Got_Clearscores(UINT8 **cp, INT32 playernum)
|
|||
}
|
||||
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
players[i].score = 0;
|
||||
players[i].score = players[i].recordscore = 0;
|
||||
|
||||
CONS_Printf(M_GetText("Scores have been reset by the server.\n"));
|
||||
}
|
||||
|
@ -3834,7 +3880,7 @@ static void Command_ListWADS_f(void)
|
|||
static void Command_Version_f(void)
|
||||
{
|
||||
#ifdef DEVELOP
|
||||
CONS_Printf("Sonic Robo Blast 2 %s-%s (%s %s) ", compbranch, comprevision, compdate, comptime);
|
||||
CONS_Printf("Sonic Robo Blast 2 %s %s %s (%s %s) ", compbranch, comprevision, compnote, compdate, comptime);
|
||||
#else
|
||||
CONS_Printf("Sonic Robo Blast 2 %s (%s %s %s %s) ", VERSIONSTRING, compdate, comptime, comprevision, compbranch);
|
||||
#endif
|
||||
|
@ -3868,11 +3914,6 @@ static void Command_Version_f(void)
|
|||
else // 16-bit? 128-bit?
|
||||
CONS_Printf("Bits Unknown ");
|
||||
|
||||
// No ASM?
|
||||
#ifdef NOASM
|
||||
CONS_Printf("\x85" "NOASM " "\x80");
|
||||
#endif
|
||||
|
||||
// Debug build
|
||||
#ifdef _DEBUG
|
||||
CONS_Printf("\x85" "DEBUG " "\x80");
|
||||
|
@ -3941,18 +3982,12 @@ void ItemFinder_OnChange(void)
|
|||
if (!cv_itemfinder.value)
|
||||
return; // it's fine.
|
||||
|
||||
if (!M_SecretUnlocked(SECRET_ITEMFINDER))
|
||||
if (!M_SecretUnlocked(SECRET_ITEMFINDER, clientGamedata))
|
||||
{
|
||||
CONS_Printf(M_GetText("You haven't earned this yet.\n"));
|
||||
CV_StealthSetValue(&cv_itemfinder, 0);
|
||||
return;
|
||||
}
|
||||
else if (netgame || multiplayer)
|
||||
{
|
||||
CONS_Printf(M_GetText("This only works in single player.\n"));
|
||||
CV_StealthSetValue(&cv_itemfinder, 0);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/** Deals with a pointlimit change by printing the change to the console.
|
||||
|
@ -4244,9 +4279,6 @@ void D_GameTypeChanged(INT32 lastgametype)
|
|||
else if (!multiplayer && !netgame)
|
||||
{
|
||||
G_SetGametype(GT_COOP);
|
||||
// These shouldn't matter anymore
|
||||
//CV_Set(&cv_itemrespawntime, cv_itemrespawntime.defaultvalue);
|
||||
//CV_SetValue(&cv_itemrespawn, 0);
|
||||
}
|
||||
|
||||
// reset timelimit and pointlimit in race/coop, prevent stupid cheats
|
||||
|
@ -4301,7 +4333,7 @@ void D_GameTypeChanged(INT32 lastgametype)
|
|||
|
||||
static void Ringslinger_OnChange(void)
|
||||
{
|
||||
if (!M_SecretUnlocked(SECRET_PANDORA) && !netgame && cv_ringslinger.value && !cv_debug)
|
||||
if (!M_SecretUnlocked(SECRET_PANDORA, serverGamedata) && !netgame && cv_ringslinger.value && !cv_debug)
|
||||
{
|
||||
CONS_Printf(M_GetText("You haven't earned this yet.\n"));
|
||||
CV_StealthSetValue(&cv_ringslinger, 0);
|
||||
|
@ -4309,12 +4341,12 @@ static void Ringslinger_OnChange(void)
|
|||
}
|
||||
|
||||
if (cv_ringslinger.value) // Only if it's been turned on
|
||||
G_SetGameModified(multiplayer);
|
||||
G_SetUsedCheats(false);
|
||||
}
|
||||
|
||||
static void Gravity_OnChange(void)
|
||||
{
|
||||
if (!M_SecretUnlocked(SECRET_PANDORA) && !netgame && !cv_debug
|
||||
if (!M_SecretUnlocked(SECRET_PANDORA, serverGamedata) && !netgame && !cv_debug
|
||||
&& strcmp(cv_gravity.string, cv_gravity.defaultvalue))
|
||||
{
|
||||
CONS_Printf(M_GetText("You haven't earned this yet.\n"));
|
||||
|
@ -4330,7 +4362,7 @@ static void Gravity_OnChange(void)
|
|||
#endif
|
||||
|
||||
if (!CV_IsSetToDefault(&cv_gravity))
|
||||
G_SetGameModified(multiplayer);
|
||||
G_SetUsedCheats(false);
|
||||
gravity = cv_gravity.value;
|
||||
}
|
||||
|
||||
|
@ -4547,25 +4579,37 @@ static void Command_Mapmd5_f(void)
|
|||
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)
|
||||
{
|
||||
if (!(netgame || (multiplayer && gametype != GT_COOP)) && !cv_debug)
|
||||
CONS_Printf(M_GetText("This only works in a netgame.\n"));
|
||||
else if (!(server || (IsPlayerAdmin(consoleplayer))))
|
||||
if (!(server || (IsPlayerAdmin(consoleplayer))))
|
||||
CONS_Printf(M_GetText("Only the server or a remote admin can use this.\n"));
|
||||
else if (( gamestate != GS_LEVEL && gamestate != GS_CREDITS ) || demoplayback)
|
||||
CONS_Printf(M_GetText("You must be in a level to use this.\n"));
|
||||
else
|
||||
SendNetXCmd(XD_EXITLEVEL, NULL, 0);
|
||||
D_SendExitLevel(true);
|
||||
}
|
||||
|
||||
static void Got_ExitLevelcmd(UINT8 **cp, INT32 playernum)
|
||||
{
|
||||
(void)cp;
|
||||
boolean cheat = false;
|
||||
|
||||
cheat = (boolean)READUINT8(*cp);
|
||||
|
||||
// Ignore duplicate XD_EXITLEVEL commands.
|
||||
if (gameaction == ga_completed)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (playernum != serverplayer && !IsPlayerAdmin(playernum))
|
||||
{
|
||||
|
@ -4575,6 +4619,11 @@ static void Got_ExitLevelcmd(UINT8 **cp, INT32 playernum)
|
|||
return;
|
||||
}
|
||||
|
||||
if (G_CoopGametype() && cheat)
|
||||
{
|
||||
G_SetUsedCheats(false);
|
||||
}
|
||||
|
||||
G_ExitLevel();
|
||||
}
|
||||
|
||||
|
@ -4611,6 +4660,7 @@ void Command_ExitGame_f(void)
|
|||
botskin = 0;
|
||||
cv_debug = 0;
|
||||
emeralds = 0;
|
||||
automapactive = false;
|
||||
memset(&luabanks, 0, sizeof(luabanks));
|
||||
|
||||
if (dirmenu)
|
||||
|
@ -4646,7 +4696,7 @@ static void Fishcake_OnChange(void)
|
|||
// so don't make modifiedgame always on!
|
||||
if (cv_debug)
|
||||
{
|
||||
G_SetGameModified(multiplayer);
|
||||
G_SetUsedCheats(false);
|
||||
}
|
||||
|
||||
else if (cv_debug != cv_fishcake.value)
|
||||
|
@ -4663,11 +4713,11 @@ static void Fishcake_OnChange(void)
|
|||
static void Command_Isgamemodified_f(void)
|
||||
{
|
||||
if (savemoddata)
|
||||
CONS_Printf(M_GetText("modifiedgame is true, but you can save emblem and time data in this mod.\n"));
|
||||
CONS_Printf(M_GetText("modifiedgame is true, but you can save time data in this mod.\n"));
|
||||
else if (modifiedgame)
|
||||
CONS_Printf(M_GetText("modifiedgame is true, extras will not be unlocked\n"));
|
||||
CONS_Printf(M_GetText("modifiedgame is true, time data can't be saved\n"));
|
||||
else
|
||||
CONS_Printf(M_GetText("modifiedgame is false, you can unlock extras\n"));
|
||||
CONS_Printf(M_GetText("modifiedgame is false, you can save time data\n"));
|
||||
}
|
||||
|
||||
static void Command_Cheats_f(void)
|
||||
|
|
|
@ -201,6 +201,7 @@ void D_SendPlayerConfig(void);
|
|||
void Command_ExitGame_f(void);
|
||||
void Command_Retry_f(void);
|
||||
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);
|
||||
boolean IsPlayerAdmin(INT32 playernum);
|
||||
void SetAdminPlayer(INT32 playernum);
|
||||
|
|
|
@ -498,7 +498,7 @@ INT32 CL_CheckFiles(void)
|
|||
CONS_Debug(DBG_NETPLAY, "searching for '%s' ", fileneeded[i].filename);
|
||||
|
||||
// Check in already loaded files
|
||||
for (j = mainwads; wadfiles[j]; j++)
|
||||
for (j = mainwads; j < numwadfiles; j++)
|
||||
{
|
||||
nameonly(strcpy(wadfilename, wadfiles[j]->filename));
|
||||
if (!stricmp(wadfilename, fileneeded[i].filename) &&
|
||||
|
|
|
@ -249,6 +249,38 @@ typedef enum
|
|||
CR_FAN
|
||||
} carrytype_t; // pw_carry
|
||||
|
||||
typedef enum
|
||||
{
|
||||
STR_NONE = 0, // All strong powers can stack onto each other
|
||||
|
||||
// Attack powers
|
||||
STR_ANIM = 0x1, // remove powers when leaving current animation
|
||||
STR_PUNCH = 0x2, // frontal attack (knuckles glide)
|
||||
STR_TAIL = 0x4, // rear attack
|
||||
STR_STOMP = 0x8, // falling onto object (fang bounce)
|
||||
STR_UPPER = 0x10, // moving upwards into object (tails fly)
|
||||
STR_GUARD = 0x20, //protect against damage
|
||||
STR_HEAVY = 0x40, // ignore vertical rebound
|
||||
STR_DASH = 0x80, // special type for machine dashmode, automatically removes your powers when leaving dashmode
|
||||
|
||||
// Environment powers
|
||||
STR_WALL = 0x100, // fof busting
|
||||
STR_FLOOR = 0x200,
|
||||
STR_CEILING = 0x400,
|
||||
STR_SPRING = 0x800, // power up hit springs
|
||||
STR_SPIKE = 0x1000, // break spikes
|
||||
|
||||
// Shortcuts
|
||||
STR_ATTACK = STR_PUNCH|STR_TAIL|STR_STOMP|STR_UPPER,
|
||||
STR_BUST = STR_WALL|STR_FLOOR|STR_CEILING,
|
||||
STR_FLY = STR_ANIM|STR_UPPER,
|
||||
STR_GLIDE = STR_ANIM|STR_PUNCH,
|
||||
STR_TWINSPIN = STR_ANIM|STR_ATTACK|STR_BUST|STR_SPRING|STR_SPIKE,
|
||||
STR_MELEE = STR_ANIM|STR_PUNCH|STR_HEAVY|STR_WALL|STR_FLOOR|STR_SPRING|STR_SPIKE,
|
||||
STR_BOUNCE = STR_ANIM|STR_STOMP|STR_FLOOR,
|
||||
STR_METAL = STR_DASH|STR_SPIKE
|
||||
} strongtype_t; // pw_strong
|
||||
|
||||
// Player powers. (don't edit this comment)
|
||||
typedef enum
|
||||
{
|
||||
|
@ -293,6 +325,8 @@ typedef enum
|
|||
|
||||
pw_ignorelatch, // Don't grab onto CR_GENERIC, add 32768 (powers[pw_ignorelatch] & 1<<15) to avoid ALL not-NiGHTS CR_ types
|
||||
|
||||
pw_strong, // Additional properties for powerful attacks
|
||||
|
||||
NUMPOWERS
|
||||
} powertype_t;
|
||||
|
||||
|
@ -407,6 +441,7 @@ typedef struct player_s
|
|||
|
||||
// playing animation.
|
||||
panim_t panim;
|
||||
UINT8 stronganim;
|
||||
|
||||
// For screen flashing (bright).
|
||||
UINT16 flashcount;
|
||||
|
@ -418,7 +453,8 @@ typedef struct player_s
|
|||
INT32 skin;
|
||||
UINT32 availabilities;
|
||||
|
||||
UINT32 score; // player score
|
||||
UINT32 score; // player score (total)
|
||||
UINT32 recordscore; // player score (per life / map)
|
||||
fixed_t dashspeed; // dashing speed
|
||||
|
||||
fixed_t normalspeed; // Normal ground
|
||||
|
|
|
@ -17,6 +17,8 @@
|
|||
#ifndef __D_THINK__
|
||||
#define __D_THINK__
|
||||
|
||||
#include "doomdef.h"
|
||||
|
||||
#ifdef __GNUG__
|
||||
#pragma interface
|
||||
#endif
|
||||
|
@ -49,6 +51,11 @@ typedef struct thinker_s
|
|||
// killough 11/98: count of how many other objects reference
|
||||
// this one using pointers. Used for garbage collection.
|
||||
INT32 references;
|
||||
|
||||
#ifdef PARANOIA
|
||||
INT32 debug_mobjtype;
|
||||
tic_t debug_time;
|
||||
#endif
|
||||
} thinker_t;
|
||||
|
||||
#endif
|
||||
|
|
270
src/deh_lua.c
270
src/deh_lua.c
|
@ -10,20 +10,7 @@
|
|||
/// \file deh_lua.c
|
||||
/// \brief Lua SOC library
|
||||
|
||||
#include "g_game.h"
|
||||
#include "s_sound.h"
|
||||
#include "z_zone.h"
|
||||
#include "m_menu.h"
|
||||
#include "m_misc.h"
|
||||
#include "p_local.h"
|
||||
#include "st_stuff.h"
|
||||
#include "fastcmp.h"
|
||||
#include "lua_script.h"
|
||||
#include "lua_libs.h"
|
||||
|
||||
#include "dehacked.h"
|
||||
#include "deh_lua.h"
|
||||
#include "deh_tables.h"
|
||||
|
||||
// freeslot takes a name (string only!)
|
||||
// and allocates it to the appropriate free slot.
|
||||
|
@ -89,6 +76,8 @@ static inline int lib_freeslot(lua_State *L)
|
|||
strncpy(sprnames[j],word,4);
|
||||
//sprnames[j][4] = 0;
|
||||
used_spr[(j-SPR_FIRSTFREESLOT)/8] |= 1<<(j%8); // Okay, this sprite slot has been named now.
|
||||
// Lua needs to update the value in _G if it exists
|
||||
LUA_UpdateSprName(word, j);
|
||||
lua_pushinteger(L, j);
|
||||
r++;
|
||||
break;
|
||||
|
@ -188,6 +177,9 @@ static inline int lib_freeslot(lua_State *L)
|
|||
lua_remove(L, 1);
|
||||
continue;
|
||||
}
|
||||
|
||||
R_RefreshSprite2();
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
|
@ -195,39 +187,54 @@ static inline int lib_freeslot(lua_State *L)
|
|||
// Arguments: mobj_t actor, int var1, int var2
|
||||
static int action_call(lua_State *L)
|
||||
{
|
||||
//actionf_t *action = lua_touserdata(L,lua_upvalueindex(1));
|
||||
actionf_t *action = *((actionf_t **)luaL_checkudata(L, 1, META_ACTION));
|
||||
mobj_t *actor = *((mobj_t **)luaL_checkudata(L, 2, META_MOBJ));
|
||||
|
||||
var1 = (INT32)luaL_optinteger(L, 3, 0);
|
||||
var2 = (INT32)luaL_optinteger(L, 4, 0);
|
||||
|
||||
if (!actor)
|
||||
{
|
||||
return LUA_ErrInvalid(L, "mobj_t");
|
||||
}
|
||||
|
||||
action->acp1(actor);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Hardcoded A_Action name to call for super() or NULL if super() would be invalid.
|
||||
// Set in lua_infolib.
|
||||
const char *superactions[MAXRECURSION];
|
||||
UINT8 superstack = 0;
|
||||
const char *luaactions[MAX_ACTION_RECURSION];
|
||||
UINT8 luaactionstack = 0;
|
||||
|
||||
static int lib_dummysuper(lua_State *L)
|
||||
{
|
||||
return luaL_error(L, "Can't call super() outside of hardcode-replacing A_Action functions being called by state changes!"); // convoluted, I know. @_@;;
|
||||
// TODO: Now that the restriction on only being allowed in state changes was lifted,
|
||||
// it'd be nice to have super extend to Lua A_ functions too :)
|
||||
return luaL_error(L, "Can't call super() outside of hardcode-replacing A_Action functions!");
|
||||
}
|
||||
|
||||
static inline int lib_getenum(lua_State *L)
|
||||
static void CacheAndPushConstant(lua_State *L, const char *name, lua_Integer value)
|
||||
{
|
||||
const char *word, *p;
|
||||
// "cache" into _G
|
||||
lua_pushstring(L, name);
|
||||
lua_pushinteger(L, value);
|
||||
lua_rawset(L, LUA_GLOBALSINDEX);
|
||||
// push
|
||||
lua_pushinteger(L, value);
|
||||
}
|
||||
|
||||
// Search for a matching constant variable.
|
||||
// Result is stored into _G for faster subsequent use. (Except for SPR_ in the SOC parser)
|
||||
static int ScanConstants(lua_State *L, boolean mathlib, const char *word)
|
||||
{
|
||||
const char *p;
|
||||
fixed_t i;
|
||||
boolean mathlib = lua_toboolean(L, lua_upvalueindex(1));
|
||||
if (lua_type(L,2) != LUA_TSTRING)
|
||||
return 0;
|
||||
word = lua_tostring(L,2);
|
||||
|
||||
if (strlen(word) == 1) { // Assume sprite frame if length 1.
|
||||
if (*word >= 'A' && *word <= '~')
|
||||
{
|
||||
lua_pushinteger(L, *word-'A');
|
||||
CacheAndPushConstant(L, word, *word-'A');
|
||||
return 1;
|
||||
}
|
||||
if (mathlib) return luaL_error(L, "constant '%s' could not be parsed.\n", word);
|
||||
|
@ -237,7 +244,7 @@ static inline int lib_getenum(lua_State *L)
|
|||
p = word+3;
|
||||
for (i = 0; MOBJFLAG_LIST[i]; i++)
|
||||
if (fastcmp(p, MOBJFLAG_LIST[i])) {
|
||||
lua_pushinteger(L, ((lua_Integer)1<<i));
|
||||
CacheAndPushConstant(L, word, ((lua_Integer)1<<i));
|
||||
return 1;
|
||||
}
|
||||
if (mathlib) return luaL_error(L, "mobjflag '%s' could not be found.\n", word);
|
||||
|
@ -247,7 +254,7 @@ static inline int lib_getenum(lua_State *L)
|
|||
p = word+4;
|
||||
for (i = 0; MOBJFLAG2_LIST[i]; i++)
|
||||
if (fastcmp(p, MOBJFLAG2_LIST[i])) {
|
||||
lua_pushinteger(L, ((lua_Integer)1<<i));
|
||||
CacheAndPushConstant(L, word, ((lua_Integer)1<<i));
|
||||
return 1;
|
||||
}
|
||||
if (mathlib) return luaL_error(L, "mobjflag2 '%s' could not be found.\n", word);
|
||||
|
@ -257,12 +264,12 @@ static inline int lib_getenum(lua_State *L)
|
|||
p = word+4;
|
||||
for (i = 0; MOBJEFLAG_LIST[i]; i++)
|
||||
if (fastcmp(p, MOBJEFLAG_LIST[i])) {
|
||||
lua_pushinteger(L, ((lua_Integer)1<<i));
|
||||
CacheAndPushConstant(L, word, ((lua_Integer)1<<i));
|
||||
return 1;
|
||||
}
|
||||
if (fastcmp(p, "REVERSESUPER"))
|
||||
{
|
||||
lua_pushinteger(L, (lua_Integer)MFE_REVERSESUPER);
|
||||
CacheAndPushConstant(L, word, (lua_Integer)MFE_REVERSESUPER);
|
||||
return 1;
|
||||
}
|
||||
if (mathlib) return luaL_error(L, "mobjeflag '%s' could not be found.\n", word);
|
||||
|
@ -270,9 +277,9 @@ static inline int lib_getenum(lua_State *L)
|
|||
}
|
||||
else if (fastncmp("MTF_", word, 4)) {
|
||||
p = word+4;
|
||||
for (i = 0; i < 4; i++)
|
||||
if (MAPTHINGFLAG_LIST[i] && fastcmp(p, MAPTHINGFLAG_LIST[i])) {
|
||||
lua_pushinteger(L, ((lua_Integer)1<<i));
|
||||
for (i = 0; MAPTHINGFLAG_LIST[i]; i++)
|
||||
if (fastcmp(p, MAPTHINGFLAG_LIST[i])) {
|
||||
CacheAndPushConstant(L, word, ((lua_Integer)1<<i));
|
||||
return 1;
|
||||
}
|
||||
if (mathlib) return luaL_error(L, "mapthingflag '%s' could not be found.\n", word);
|
||||
|
@ -282,17 +289,17 @@ static inline int lib_getenum(lua_State *L)
|
|||
p = word+3;
|
||||
for (i = 0; PLAYERFLAG_LIST[i]; i++)
|
||||
if (fastcmp(p, PLAYERFLAG_LIST[i])) {
|
||||
lua_pushinteger(L, ((lua_Integer)1<<i));
|
||||
CacheAndPushConstant(L, word, ((lua_Integer)1<<i));
|
||||
return 1;
|
||||
}
|
||||
if (fastcmp(p, "FULLSTASIS"))
|
||||
{
|
||||
lua_pushinteger(L, (lua_Integer)PF_FULLSTASIS);
|
||||
CacheAndPushConstant(L, word, (lua_Integer)PF_FULLSTASIS);
|
||||
return 1;
|
||||
}
|
||||
else if (fastcmp(p, "USEDOWN")) // Remove case when 2.3 nears release...
|
||||
{
|
||||
lua_pushinteger(L, (lua_Integer)PF_SPINDOWN);
|
||||
CacheAndPushConstant(L, word, (lua_Integer)PF_SPINDOWN);
|
||||
return 1;
|
||||
}
|
||||
if (mathlib) return luaL_error(L, "playerflag '%s' could not be found.\n", word);
|
||||
|
@ -302,7 +309,7 @@ static inline int lib_getenum(lua_State *L)
|
|||
p = word;
|
||||
for (i = 0; Gametype_ConstantNames[i]; i++)
|
||||
if (fastcmp(p, Gametype_ConstantNames[i])) {
|
||||
lua_pushinteger(L, i);
|
||||
CacheAndPushConstant(L, word, i);
|
||||
return 1;
|
||||
}
|
||||
if (mathlib) return luaL_error(L, "gametype '%s' could not be found.\n", word);
|
||||
|
@ -312,7 +319,7 @@ static inline int lib_getenum(lua_State *L)
|
|||
p = word+4;
|
||||
for (i = 0; GAMETYPERULE_LIST[i]; i++)
|
||||
if (fastcmp(p, GAMETYPERULE_LIST[i])) {
|
||||
lua_pushinteger(L, ((lua_Integer)1<<i));
|
||||
CacheAndPushConstant(L, word, ((lua_Integer)1<<i));
|
||||
return 1;
|
||||
}
|
||||
if (mathlib) return luaL_error(L, "game type rule '%s' could not be found.\n", word);
|
||||
|
@ -322,7 +329,7 @@ static inline int lib_getenum(lua_State *L)
|
|||
p = word+4;
|
||||
for (i = 0; TYPEOFLEVEL[i].name; i++)
|
||||
if (fastcmp(p, TYPEOFLEVEL[i].name)) {
|
||||
lua_pushinteger(L, TYPEOFLEVEL[i].flag);
|
||||
CacheAndPushConstant(L, word, TYPEOFLEVEL[i].flag);
|
||||
return 1;
|
||||
}
|
||||
if (mathlib) return luaL_error(L, "typeoflevel '%s' could not be found.\n", word);
|
||||
|
@ -330,9 +337,10 @@ static inline int lib_getenum(lua_State *L)
|
|||
}
|
||||
else if (fastncmp("ML_", word, 3)) {
|
||||
p = word+3;
|
||||
|
||||
for (i = 0; ML_LIST[i]; i++)
|
||||
if (fastcmp(p, ML_LIST[i])) {
|
||||
lua_pushinteger(L, ((lua_Integer)1<<i));
|
||||
CacheAndPushConstant(L, word, ((lua_Integer)1<<i));
|
||||
return 1;
|
||||
}
|
||||
// Aliases
|
||||
|
@ -415,13 +423,13 @@ static inline int lib_getenum(lua_State *L)
|
|||
if (!FREE_STATES[i])
|
||||
break;
|
||||
if (fastcmp(p, FREE_STATES[i])) {
|
||||
lua_pushinteger(L, S_FIRSTFREESLOT+i);
|
||||
CacheAndPushConstant(L, word, S_FIRSTFREESLOT+i);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
for (i = 0; i < S_FIRSTFREESLOT; i++)
|
||||
if (fastcmp(p, STATE_LIST[i]+2)) {
|
||||
lua_pushinteger(L, i);
|
||||
CacheAndPushConstant(L, word, i);
|
||||
return 1;
|
||||
}
|
||||
return luaL_error(L, "state '%s' does not exist.\n", word);
|
||||
|
@ -432,13 +440,13 @@ static inline int lib_getenum(lua_State *L)
|
|||
if (!FREE_MOBJS[i])
|
||||
break;
|
||||
if (fastcmp(p, FREE_MOBJS[i])) {
|
||||
lua_pushinteger(L, MT_FIRSTFREESLOT+i);
|
||||
CacheAndPushConstant(L, word, MT_FIRSTFREESLOT+i);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
for (i = 0; i < MT_FIRSTFREESLOT; i++)
|
||||
if (fastcmp(p, MOBJTYPE_LIST[i]+3)) {
|
||||
lua_pushinteger(L, i);
|
||||
CacheAndPushConstant(L, word, i);
|
||||
return 1;
|
||||
}
|
||||
return luaL_error(L, "mobjtype '%s' does not exist.\n", word);
|
||||
|
@ -447,7 +455,12 @@ static inline int lib_getenum(lua_State *L)
|
|||
p = word+4;
|
||||
for (i = 0; i < NUMSPRITES; i++)
|
||||
if (!sprnames[i][4] && fastncmp(p,sprnames[i],4)) {
|
||||
lua_pushinteger(L, i);
|
||||
// updating overridden sprnames is not implemented for soc parser,
|
||||
// so don't use cache
|
||||
if (mathlib)
|
||||
lua_pushinteger(L, i);
|
||||
else
|
||||
CacheAndPushConstant(L, word, i);
|
||||
return 1;
|
||||
}
|
||||
if (mathlib) return luaL_error(L, "sprite '%s' could not be found.\n", word);
|
||||
|
@ -462,12 +475,12 @@ static inline int lib_getenum(lua_State *L)
|
|||
// the spr2names entry will have "_" on the end, as in "RUN_"
|
||||
if (spr2names[i][3] == '_' && !p[3]) {
|
||||
if (fastncmp(p,spr2names[i],3)) {
|
||||
lua_pushinteger(L, i);
|
||||
CacheAndPushConstant(L, word, i);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else if (fastncmp(p,spr2names[i],4)) {
|
||||
lua_pushinteger(L, i);
|
||||
CacheAndPushConstant(L, word, i);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
@ -478,7 +491,7 @@ static inline int lib_getenum(lua_State *L)
|
|||
p = word+4;
|
||||
for (i = 0; i < NUMSFX; i++)
|
||||
if (S_sfx[i].name && fastcmp(p, S_sfx[i].name)) {
|
||||
lua_pushinteger(L, i);
|
||||
CacheAndPushConstant(L, word, i);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
|
@ -487,7 +500,7 @@ static inline int lib_getenum(lua_State *L)
|
|||
p = word+4;
|
||||
for (i = 0; i < NUMSFX; i++)
|
||||
if (S_sfx[i].name && fasticmp(p, S_sfx[i].name)) {
|
||||
lua_pushinteger(L, i);
|
||||
CacheAndPushConstant(L, word, i);
|
||||
return 1;
|
||||
}
|
||||
return luaL_error(L, "sfx '%s' could not be found.\n", word);
|
||||
|
@ -496,7 +509,7 @@ static inline int lib_getenum(lua_State *L)
|
|||
p = word+2;
|
||||
for (i = 0; i < NUMSFX; i++)
|
||||
if (S_sfx[i].name && fasticmp(p, S_sfx[i].name)) {
|
||||
lua_pushinteger(L, i);
|
||||
CacheAndPushConstant(L, word, i);
|
||||
return 1;
|
||||
}
|
||||
if (mathlib) return luaL_error(L, "sfx '%s' could not be found.\n", word);
|
||||
|
@ -506,7 +519,7 @@ static inline int lib_getenum(lua_State *L)
|
|||
p = word+3;
|
||||
for (i = 0; i < NUMPOWERS; i++)
|
||||
if (fasticmp(p, POWERS_LIST[i])) {
|
||||
lua_pushinteger(L, i);
|
||||
CacheAndPushConstant(L, word, i);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
|
@ -515,7 +528,7 @@ static inline int lib_getenum(lua_State *L)
|
|||
p = word+3;
|
||||
for (i = 0; i < NUMPOWERS; i++)
|
||||
if (fastcmp(p, POWERS_LIST[i])) {
|
||||
lua_pushinteger(L, i);
|
||||
CacheAndPushConstant(L, word, i);
|
||||
return 1;
|
||||
}
|
||||
return luaL_error(L, "power '%s' could not be found.\n", word);
|
||||
|
@ -524,7 +537,7 @@ static inline int lib_getenum(lua_State *L)
|
|||
p = word+4;
|
||||
for (i = 0; i < NUMHUDITEMS; i++)
|
||||
if (fastcmp(p, HUDITEMS_LIST[i])) {
|
||||
lua_pushinteger(L, i);
|
||||
CacheAndPushConstant(L, word, i);
|
||||
return 1;
|
||||
}
|
||||
if (mathlib) return luaL_error(L, "huditem '%s' could not be found.\n", word);
|
||||
|
@ -536,13 +549,13 @@ static inline int lib_getenum(lua_State *L)
|
|||
if (!FREE_SKINCOLORS[i])
|
||||
break;
|
||||
if (fastcmp(p, FREE_SKINCOLORS[i])) {
|
||||
lua_pushinteger(L, SKINCOLOR_FIRSTFREESLOT+i);
|
||||
CacheAndPushConstant(L, word, SKINCOLOR_FIRSTFREESLOT+i);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
for (i = 0; i < SKINCOLOR_FIRSTFREESLOT; i++)
|
||||
if (fastcmp(p, COLOR_ENUMS[i])) {
|
||||
lua_pushinteger(L, i);
|
||||
CacheAndPushConstant(L, word, i);
|
||||
return 1;
|
||||
}
|
||||
return luaL_error(L, "skincolor '%s' could not be found.\n", word);
|
||||
|
@ -553,7 +566,7 @@ static inline int lib_getenum(lua_State *L)
|
|||
for (i = 0; NIGHTSGRADE_LIST[i]; i++)
|
||||
if (*p == NIGHTSGRADE_LIST[i])
|
||||
{
|
||||
lua_pushinteger(L, i);
|
||||
CacheAndPushConstant(L, word, i);
|
||||
return 1;
|
||||
}
|
||||
if (mathlib) return luaL_error(L, "NiGHTS grade '%s' could not be found.\n", word);
|
||||
|
@ -563,70 +576,127 @@ static inline int lib_getenum(lua_State *L)
|
|||
p = word+3;
|
||||
for (i = 0; i < NUMMENUTYPES; i++)
|
||||
if (fastcmp(p, MENUTYPES_LIST[i])) {
|
||||
lua_pushinteger(L, i);
|
||||
CacheAndPushConstant(L, word, i);
|
||||
return 1;
|
||||
}
|
||||
if (mathlib) return luaL_error(L, "menutype '%s' could not be found.\n", word);
|
||||
return 0;
|
||||
}
|
||||
else if (!mathlib && fastncmp("A_",word,2)) {
|
||||
char *caps;
|
||||
// Try to get a Lua action first.
|
||||
/// \todo Push a closure that sets superactions[] and superstack.
|
||||
lua_getfield(L, LUA_REGISTRYINDEX, LREG_ACTIONS);
|
||||
// actions are stored in all uppercase.
|
||||
caps = Z_StrDup(word);
|
||||
strupr(caps);
|
||||
lua_getfield(L, -1, caps);
|
||||
Z_Free(caps);
|
||||
if (!lua_isnil(L, -1))
|
||||
return 1; // Success! :D That was easy.
|
||||
// Welp, that failed.
|
||||
lua_pop(L, 2); // pop nil and LREG_ACTIONS
|
||||
|
||||
// Hardcoded actions as callable Lua functions!
|
||||
// Retrieving them from this metatable allows them to be case-insensitive!
|
||||
for (i = 0; actionpointers[i].name; i++)
|
||||
if (fasticmp(word, actionpointers[i].name)) {
|
||||
// We push the actionf_t* itself as userdata!
|
||||
LUA_PushUserdata(L, &actionpointers[i].action, META_ACTION);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
else if (!mathlib && fastcmp("super",word))
|
||||
{
|
||||
if (!superstack)
|
||||
{
|
||||
lua_pushcfunction(L, lib_dummysuper);
|
||||
return 1;
|
||||
}
|
||||
for (i = 0; actionpointers[i].name; i++)
|
||||
if (fasticmp(superactions[superstack-1], actionpointers[i].name)) {
|
||||
LUA_PushUserdata(L, &actionpointers[i].action, META_ACTION);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (fastcmp(word, "BT_USE")) // Remove case when 2.3 nears release...
|
||||
{
|
||||
lua_pushinteger(L, (lua_Integer)BT_SPIN);
|
||||
CacheAndPushConstant(L, word, (lua_Integer)BT_SPIN);
|
||||
return 1;
|
||||
}
|
||||
|
||||
for (i = 0; INT_CONST[i].n; i++)
|
||||
if (fastcmp(word,INT_CONST[i].n)) {
|
||||
lua_pushinteger(L, INT_CONST[i].v);
|
||||
CacheAndPushConstant(L, word, INT_CONST[i].v);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int lib_getenum(lua_State *L)
|
||||
{
|
||||
const char *word;
|
||||
fixed_t i;
|
||||
boolean mathlib = lua_toboolean(L, lua_upvalueindex(1));
|
||||
if (lua_type(L,2) != LUA_TSTRING)
|
||||
return 0;
|
||||
word = lua_tostring(L,2);
|
||||
|
||||
// check actions, super and globals first, as they don't have _G caching implemented
|
||||
// so they benefit from being checked first
|
||||
|
||||
if (!mathlib && fastncmp("A_",word,2)) {
|
||||
char *caps;
|
||||
|
||||
// Hardcoded actions come first.
|
||||
// Trying to call them will invoke LUA_CallAction, which will handle super properly.
|
||||
// Retrieving them from this metatable allows them to be case-insensitive!
|
||||
for (i = 0; actionpointers[i].name; i++)
|
||||
{
|
||||
if (fasticmp(word, actionpointers[i].name))
|
||||
{
|
||||
// We push the actionf_t* itself as userdata!
|
||||
LUA_PushUserdata(L, &actionpointers[i].action, META_ACTION);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Now try to get Lua actions.
|
||||
/// \todo Push a closure that sets luaactions[] and luaactionstack.
|
||||
/// This would be part one of a step to get super functions working for custom A_ functions.
|
||||
/// Custom functions.
|
||||
lua_getfield(L, LUA_REGISTRYINDEX, LREG_ACTIONS);
|
||||
|
||||
// actions are stored in all uppercase.
|
||||
caps = Z_StrDup(word);
|
||||
strupr(caps);
|
||||
lua_getfield(L, -1, caps);
|
||||
Z_Free(caps);
|
||||
|
||||
if (!lua_isnil(L, -1))
|
||||
{
|
||||
return 1; // Success! :D That was easy.
|
||||
}
|
||||
|
||||
// Welp, that failed.
|
||||
lua_pop(L, 2); // pop nil and LREG_ACTIONS
|
||||
return 0;
|
||||
}
|
||||
else if (!mathlib && fastcmp("super",word))
|
||||
{
|
||||
if (!luaactionstack)
|
||||
{
|
||||
// Not in A_ action routine
|
||||
lua_pushcfunction(L, lib_dummysuper);
|
||||
return 1;
|
||||
}
|
||||
|
||||
for (i = 0; actionpointers[i].name; i++)
|
||||
{
|
||||
if (fasticmp(luaactions[luaactionstack-1], actionpointers[i].name))
|
||||
{
|
||||
LUA_PushUserdata(L, &actionpointers[i].action, META_ACTION);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Not a hardcoded A_ action.
|
||||
lua_pushcfunction(L, lib_dummysuper);
|
||||
return 1;
|
||||
}
|
||||
else if ((!mathlib && LUA_PushGlobals(L, word)) || ScanConstants(L, mathlib, word))
|
||||
return 1;
|
||||
|
||||
if (mathlib) return luaL_error(L, "constant '%s' could not be parsed.\n", word);
|
||||
|
||||
// DYNAMIC variables too!!
|
||||
// Try not to add anything that would break netgames or timeattack replays here.
|
||||
// You know, like consoleplayer, displayplayer, secondarydisplayplayer, or gametime.
|
||||
return LUA_PushGlobals(L, word);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// If a sprname has been "cached" to _G, update it to a new value.
|
||||
void LUA_UpdateSprName(const char *name, lua_Integer value)
|
||||
{
|
||||
char fullname[9] = "SPR_XXXX";
|
||||
|
||||
if (!gL)
|
||||
return;
|
||||
|
||||
strncpy(&fullname[4], name, 4);
|
||||
lua_pushstring(gL, fullname);
|
||||
lua_rawget(gL, LUA_GLOBALSINDEX);
|
||||
|
||||
if (!lua_isnil(gL, -1))
|
||||
{
|
||||
lua_pushstring(gL, name);
|
||||
lua_pushinteger(gL, value);
|
||||
lua_rawset(gL, LUA_GLOBALSINDEX);
|
||||
}
|
||||
|
||||
lua_pop(gL, 1); // pop the rawget result
|
||||
}
|
||||
|
||||
int LUA_EnumLib(lua_State *L)
|
||||
|
|
|
@ -13,6 +13,21 @@
|
|||
#ifndef __DEH_LUA_H__
|
||||
#define __DEH_LUA_H__
|
||||
|
||||
#include "g_game.h"
|
||||
#include "s_sound.h"
|
||||
#include "z_zone.h"
|
||||
#include "m_menu.h"
|
||||
#include "m_misc.h"
|
||||
#include "p_local.h"
|
||||
#include "st_stuff.h"
|
||||
#include "fastcmp.h"
|
||||
#include "lua_script.h"
|
||||
#include "lua_libs.h"
|
||||
|
||||
#include "dehacked.h"
|
||||
#include "deh_tables.h"
|
||||
|
||||
void LUA_UpdateSprName(const char *name, lua_Integer value);
|
||||
boolean LUA_SetLuaAction(void *state, const char *actiontocompare);
|
||||
const char *LUA_GetActionName(void *action);
|
||||
void LUA_SetActionByName(void *state, const char *actiontocompare);
|
||||
|
|
|
@ -45,6 +45,7 @@
|
|||
#include "dehacked.h"
|
||||
#include "deh_soc.h"
|
||||
#include "deh_lua.h" // included due to some LUA_SetLuaAction hack smh
|
||||
// also used for LUA_UpdateSprName
|
||||
#include "deh_tables.h"
|
||||
|
||||
// Loops through every constant and operation in word and performs its calculations, returning the final value.
|
||||
|
@ -439,6 +440,8 @@ void readfreeslots(MYFILE *f)
|
|||
strncpy(sprnames[i],word,4);
|
||||
//sprnames[i][4] = 0;
|
||||
used_spr[(i-SPR_FIRSTFREESLOT)/8] |= 1<<(i%8); // Okay, this sprite slot has been named now.
|
||||
// Lua needs to update the value in _G if it exists
|
||||
LUA_UpdateSprName(word, i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -513,6 +516,8 @@ void readfreeslots(MYFILE *f)
|
|||
} while (!myfeof(f)); // finish when the line is empty
|
||||
|
||||
Z_Free(s);
|
||||
|
||||
R_RefreshSprite2();
|
||||
}
|
||||
|
||||
void readthing(MYFILE *f, INT32 num)
|
||||
|
@ -907,7 +912,7 @@ static void readspriteframe(MYFILE *f, spriteinfo_t *sprinfo, UINT8 frame)
|
|||
else if (fastcmp(word, "YPIVOT"))
|
||||
sprinfo->pivot[frame].y = value;
|
||||
else if (fastcmp(word, "ROTAXIS"))
|
||||
sprinfo->pivot[frame].rotaxis = value;
|
||||
deh_warning("SpriteInfo: ROTAXIS is deprecated and will be removed.");
|
||||
else
|
||||
{
|
||||
f->curpos = lastline;
|
||||
|
@ -2907,7 +2912,9 @@ static boolean GoodDataFileName(const char *s)
|
|||
p = s + strlen(s) - strlen(tail);
|
||||
if (p <= s) return false; // too short
|
||||
if (!fasticmp(p, tail)) return false; // doesn't end in .dat
|
||||
if (fasticmp(s, "gamedata.dat")) return false;
|
||||
|
||||
if (fasticmp(s, "gamedata.dat")) return false; // Don't overwrite default gamedata
|
||||
if (fasticmp(s, "main.dat")) return false; // Don't overwrite default time attack replays
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -3835,6 +3842,10 @@ void readmaincfg(MYFILE *f)
|
|||
{
|
||||
useContinues = (UINT8)(value || word2[0] == 'T' || word2[0] == 'Y');
|
||||
}
|
||||
else if (fastcmp(word, "SHAREEMBLEMS"))
|
||||
{
|
||||
shareEmblems = (UINT8)(value || word2[0] == 'T' || word2[0] == 'Y');
|
||||
}
|
||||
|
||||
else if (fastcmp(word, "GAMEDATA"))
|
||||
{
|
||||
|
@ -3845,7 +3856,7 @@ void readmaincfg(MYFILE *f)
|
|||
if (!GoodDataFileName(word2))
|
||||
I_Error("Maincfg: bad data file name '%s'\n", word2);
|
||||
|
||||
G_SaveGameData();
|
||||
G_SaveGameData(clientGamedata);
|
||||
strlcpy(gamedatafilename, word2, sizeof (gamedatafilename));
|
||||
strlwr(gamedatafilename);
|
||||
savemoddata = true;
|
||||
|
|
|
@ -198,6 +198,7 @@ actionpointer_t actionpointers[] =
|
|||
{{A_Boss3TakeDamage}, "A_BOSS3TAKEDAMAGE"},
|
||||
{{A_Boss3Path}, "A_BOSS3PATH"},
|
||||
{{A_Boss3ShockThink}, "A_BOSS3SHOCKTHINK"},
|
||||
{{A_Shockwave}, "A_SHOCKWAVE"},
|
||||
{{A_LinedefExecute}, "A_LINEDEFEXECUTE"},
|
||||
{{A_LinedefExecuteFromArg}, "A_LINEDEFEXECUTEFROMARG"},
|
||||
{{A_PlaySeeSound}, "A_PLAYSEESOUND"},
|
||||
|
@ -4409,11 +4410,12 @@ const char *const MOBJEFLAG_LIST[] = {
|
|||
NULL
|
||||
};
|
||||
|
||||
const char *const MAPTHINGFLAG_LIST[4] = {
|
||||
const char *const MAPTHINGFLAG_LIST[] = {
|
||||
"EXTRA", // Extra flag for objects.
|
||||
"OBJECTFLIP", // Reverse gravity flag for 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[] = {
|
||||
|
@ -4550,6 +4552,7 @@ const char *const MSF_LIST[] = {
|
|||
const char *const SSF_LIST[] = {
|
||||
"OUTERSPACE",
|
||||
"DOUBLESTEPUP",
|
||||
"NOSTEPDOWN",
|
||||
"WINDCURRENT",
|
||||
"CONVEYOR",
|
||||
"SPEEDPAD",
|
||||
|
@ -4566,6 +4569,8 @@ const char *const SSF_LIST[] = {
|
|||
"ZOOMTUBEEND",
|
||||
"FINISHLINE",
|
||||
"ROPEHANG",
|
||||
"JUMPFLIP",
|
||||
"GRAVITYOVERRIDE",
|
||||
NULL
|
||||
};
|
||||
|
||||
|
@ -4609,66 +4614,111 @@ const char *COLOR_ENUMS[] = {
|
|||
// Desaturated
|
||||
"AETHER", // SKINCOLOR_AETHER,
|
||||
"SLATE", // SKINCOLOR_SLATE,
|
||||
"MOONSTONE", // SKINCOLOR_MOONSTONE,
|
||||
"BLUEBELL", // SKINCOLOR_BLUEBELL,
|
||||
"PINK", // SKINCOLOR_PINK,
|
||||
"ROSEWOOD", // SKINCOLOR_ROSEWOOD,
|
||||
"YOGURT", // SKINCOLOR_YOGURT,
|
||||
"LATTE", // SKINCOLOR_LATTE,
|
||||
"BROWN", // SKINCOLOR_BROWN,
|
||||
"BOULDER", // SKINCOLOR_BOULDER
|
||||
"BRONZE", // SKINCOLOR_BRONZE,
|
||||
"TAN", // SKINCOLOR_TAN,
|
||||
"SEPIA", // SKINCOLOR_SEPIA,
|
||||
"ECRU", // SKINCOLOR_ECRU,
|
||||
"TAN", // SKINCOLOR_TAN,
|
||||
"BEIGE", // SKINCOLOR_BEIGE,
|
||||
"ROSEBUSH", // SKINCOLOR_ROSEBUSH,
|
||||
"MOSS", // SKINCOLOR_MOSS,
|
||||
"AZURE", // SKINCOLOR_AZURE,
|
||||
"LAVENDER", // SKINCOLOR_LAVENDER,
|
||||
"EGGPLANT", // SKINCOLOR_EGGPLANT,
|
||||
"LAVENDER", // SKINCOLOR_LAVENDER,
|
||||
|
||||
// Viv's vivid colours (toast 21/07/17)
|
||||
// Tweaks & additions (Lach, sphere, Alice, MotorRoach 26/10/22)
|
||||
"RUBY", // SKINCOLOR_RUBY,
|
||||
"CHERRY", // SKINCOLOR_CHERRY,
|
||||
"SALMON", // SKINCOLOR_SALMON,
|
||||
"PEPPER", // SKINCOLOR_PEPPER,
|
||||
"RED", // SKINCOLOR_RED,
|
||||
"CRIMSON", // SKINCOLOR_CRIMSON,
|
||||
"FLAME", // SKINCOLOR_FLAME,
|
||||
"GARNET", // SKINCOLOR_GARNET,
|
||||
"KETCHUP", // SKINCOLOR_KETCHUP,
|
||||
"PEACHY", // SKINCOLOR_PEACHY,
|
||||
"QUAIL", // SKINCOLOR_QUAIL,
|
||||
"FOUNDATION", // SKINCOLOR_FOUNDATION,
|
||||
"SUNSET", // SKINCOLOR_SUNSET,
|
||||
"COPPER", // SKINCOLOR_COPPER,
|
||||
"APRICOT", // SKINCOLOR_APRICOT,
|
||||
"ORANGE", // SKINCOLOR_ORANGE,
|
||||
"RUST", // SKINCOLOR_RUST,
|
||||
"TANGERINE", // SKINCOLOR_TANGERINE,
|
||||
"TOPAZ", // SKINCOLOR_TOPAZ,
|
||||
"GOLD", // SKINCOLOR_GOLD,
|
||||
"SANDY", // SKINCOLOR_SANDY,
|
||||
"GOLDENROD", // SKINCOLOR_GOLDENROD,
|
||||
"YELLOW", // SKINCOLOR_YELLOW,
|
||||
"OLIVE", // SKINCOLOR_OLIVE,
|
||||
"PEAR", // SKINCOLOR_PEAR,
|
||||
"LEMON", // SKINCOLOR_LEMON,
|
||||
"LIME", // SKINCOLOR_LIME,
|
||||
"PERIDOT", // SKINCOLOR_PERIDOT,
|
||||
"APPLE", // SKINCOLOR_APPLE,
|
||||
"HEADLIGHT", // SKINCOLOR_HEADLIGHT,
|
||||
"CHARTREUSE", // SKINCOLOR_CHARTREUSE,
|
||||
"GREEN", // SKINCOLOR_GREEN,
|
||||
"FOREST", // SKINCOLOR_FOREST,
|
||||
"EMERALD", // SKINCOLOR_EMERALD,
|
||||
"SHAMROCK", // SKINCOLOR_SHAMROCK,
|
||||
"JADE", // SKINCOLOR_JADE,
|
||||
"MINT", // SKINCOLOR_MINT,
|
||||
"MASTER", // SKINCOLOR_MASTER,
|
||||
"EMERALD", // SKINCOLOR_EMERALD,
|
||||
"SEAFOAM", // SKINCOLOR_SEAFOAM,
|
||||
"ISLAND", // SKINCOLOR_ISLAND,
|
||||
"BOTTLE", // SKINCOLOR_BOTTLE,
|
||||
"AQUA", // SKINCOLOR_AQUA,
|
||||
"TEAL", // SKINCOLOR_TEAL,
|
||||
"OCEAN", // SKINCOLOR_OCEAN,
|
||||
"WAVE", // SKINCOLOR_WAVE,
|
||||
"CYAN", // SKINCOLOR_CYAN,
|
||||
"TURQUOISE", // SKINCOLOR_TURQUOISE,
|
||||
"AQUAMARINE", // SKINCOLOR_AQUAMARINE,
|
||||
"SKY", // SKINCOLOR_SKY,
|
||||
"MARINE", // SKINCOLOR_MARINE,
|
||||
"CERULEAN", // SKINCOLOR_CERULEAN,
|
||||
"DREAM", // SKINCOLOR_DREAM,
|
||||
"ICY", // SKINCOLOR_ICY,
|
||||
"DAYBREAK", // SKINCOLOR_DAYBREAK,
|
||||
"SAPPHIRE", // SKINCOLOR_SAPPHIRE,
|
||||
"ARCTIC", // SKINCOLOR_ARCTIC,
|
||||
"CORNFLOWER", // SKINCOLOR_CORNFLOWER,
|
||||
"BLUE", // SKINCOLOR_BLUE,
|
||||
"COBALT", // SKINCOLOR_COBALT,
|
||||
"MIDNIGHT", // SKINCOLOR_MIDNIGHT,
|
||||
"GALAXY", // SKINCOLOR_GALAXY,
|
||||
"VAPOR", // SKINCOLOR_VAPOR,
|
||||
"DUSK", // SKINCOLOR_DUSK,
|
||||
"MAJESTY", // SKINCOLOR_MAJESTY,
|
||||
"PASTEL", // SKINCOLOR_PASTEL,
|
||||
"PURPLE", // SKINCOLOR_PURPLE,
|
||||
"BUBBLEGUM", // SKINCOLOR_BUBBLEGUM,
|
||||
"NOBLE", // SKINCOLOR_NOBLE,
|
||||
"FUCHSIA", // SKINCOLOR_FUCHSIA,
|
||||
"BUBBLEGUM", // SKINCOLOR_BUBBLEGUM,
|
||||
"SIBERITE", // SKINCOLOR_SIBERITE,
|
||||
"MAGENTA", // SKINCOLOR_MAGENTA,
|
||||
"NEON", // SKINCOLOR_NEON,
|
||||
"VIOLET", // SKINCOLOR_VIOLET,
|
||||
"ROYAL", // SKINCOLOR_ROYAL,
|
||||
"LILAC", // SKINCOLOR_LILAC,
|
||||
"MAUVE", // SKINCOLOR_MAUVE,
|
||||
"EVENTIDE", // SKINCOLOR_EVENTIDE,
|
||||
"PLUM", // SKINCOLOR_PLUM,
|
||||
"RASPBERRY", // SKINCOLOR_RASPBERRY,
|
||||
"TAFFY", // SKINCOLOR_TAFFY,
|
||||
"ROSY", // SKINCOLOR_ROSY,
|
||||
"FANCY", // SKINCOLOR_FANCY,
|
||||
"SANGRIA", // SKINCOLOR_SANGRIA,
|
||||
"VOLCANIC", // SKINCOLOR_VOLCANIC,
|
||||
|
||||
// Super special awesome Super flashing colors!
|
||||
"SUPERSILVER1", // SKINCOLOR_SUPERSILVER1
|
||||
|
@ -4768,7 +4818,9 @@ const char *const POWERS_LIST[] = {
|
|||
|
||||
"JUSTLAUNCHED",
|
||||
|
||||
"IGNORELATCH"
|
||||
"IGNORELATCH",
|
||||
|
||||
"STRONG"
|
||||
};
|
||||
|
||||
const char *const HUDITEMS_LIST[] = {
|
||||
|
@ -5121,6 +5173,30 @@ struct int_const_s const INT_CONST[] = {
|
|||
{"CR_DUSTDEVIL",CR_DUSTDEVIL},
|
||||
{"CR_FAN",CR_FAN},
|
||||
|
||||
// Strong powers
|
||||
{"STR_NONE",STR_NONE},
|
||||
{"STR_ANIM",STR_ANIM},
|
||||
{"STR_PUNCH",STR_PUNCH},
|
||||
{"STR_TAIL",STR_TAIL},
|
||||
{"STR_STOMP",STR_STOMP},
|
||||
{"STR_UPPER",STR_UPPER},
|
||||
{"STR_GUARD",STR_GUARD},
|
||||
{"STR_HEAVY",STR_HEAVY},
|
||||
{"STR_DASH",STR_DASH},
|
||||
{"STR_WALL",STR_WALL},
|
||||
{"STR_FLOOR",STR_FLOOR},
|
||||
{"STR_CEILING",STR_CEILING},
|
||||
{"STR_SPRING",STR_SPRING},
|
||||
{"STR_SPIKE",STR_SPIKE},
|
||||
{"STR_ATTACK",STR_ATTACK},
|
||||
{"STR_BUST",STR_BUST},
|
||||
{"STR_FLY",STR_FLY},
|
||||
{"STR_GLIDE",STR_GLIDE},
|
||||
{"STR_TWINSPIN",STR_TWINSPIN},
|
||||
{"STR_MELEE",STR_MELEE},
|
||||
{"STR_BOUNCE",STR_BOUNCE},
|
||||
{"STR_METAL",STR_METAL},
|
||||
|
||||
// Ring weapons (ringweapons_t)
|
||||
// Useful for A_GiveWeapon
|
||||
{"RW_AUTO",RW_AUTO},
|
||||
|
|
|
@ -30,6 +30,7 @@ extern UINT8 used_spr[(NUMSPRITEFREESLOTS / 8) + 1]; // Bitwise flag for sprite
|
|||
memset(FREE_MOBJS,0,sizeof(char *) * NUMMOBJFREESLOTS);\
|
||||
memset(FREE_SKINCOLORS,0,sizeof(char *) * NUMCOLORFREESLOTS);\
|
||||
memset(used_spr,0,sizeof(UINT8) * ((NUMSPRITEFREESLOTS / 8) + 1));\
|
||||
memset(actionsoverridden, LUA_REFNIL, sizeof(actionsoverridden));\
|
||||
}
|
||||
|
||||
struct flickytypes_s {
|
||||
|
@ -61,7 +62,7 @@ extern const char *const MOBJTYPE_LIST[];
|
|||
extern const char *const MOBJFLAG_LIST[];
|
||||
extern const char *const MOBJFLAG2_LIST[]; // \tMF2_(\S+).*// (.+) --> \t"\1", // \2
|
||||
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 GAMETYPERULE_LIST[];
|
||||
extern const char *const ML_LIST[]; // Linedef flags
|
||||
|
|
|
@ -575,7 +575,7 @@ static void DEH_LoadDehackedFile(MYFILE *f, boolean mainfile)
|
|||
} // end while
|
||||
|
||||
if (gamedataadded)
|
||||
G_LoadGameData();
|
||||
G_LoadGameData(clientGamedata);
|
||||
|
||||
if (gamestate == GS_TITLESCREEN)
|
||||
{
|
||||
|
|
|
@ -40,9 +40,9 @@ extern boolean gamedataadded;
|
|||
extern boolean titlechanged;
|
||||
extern boolean introchanged;
|
||||
|
||||
#define MAXRECURSION 30
|
||||
extern const char *superactions[MAXRECURSION];
|
||||
extern UINT8 superstack;
|
||||
#define MAX_ACTION_RECURSION 30
|
||||
extern const char *luaactions[MAX_ACTION_RECURSION];
|
||||
extern UINT8 luaactionstack;
|
||||
|
||||
// If the dehacked patch does not match this version, we throw a warning
|
||||
#define PATCHVERSION 220
|
||||
|
|
|
@ -62,6 +62,10 @@ enum
|
|||
#define MTF_AMBUSH 8
|
||||
|
||||
// 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)
|
||||
#pragma pack(1)
|
||||
|
@ -211,6 +215,7 @@ typedef struct
|
|||
UINT8 extrainfo;
|
||||
taglist_t tags;
|
||||
fixed_t scale;
|
||||
fixed_t spritexscale, spriteyscale;
|
||||
INT32 args[NUMMAPTHINGARGS];
|
||||
char *stringargs[NUMMAPTHINGSTRINGARGS];
|
||||
struct mobj_s *mobj;
|
||||
|
|
|
@ -104,8 +104,18 @@
|
|||
#include <io.h>
|
||||
#endif
|
||||
|
||||
FILE *fopenfile(const char*, const char*);
|
||||
|
||||
//#define NOMD5
|
||||
|
||||
// If you don't disable ALL debug first, you get ALL debug enabled
|
||||
#if !defined (NDEBUG)
|
||||
#define PACKETDROP
|
||||
#define PARANOIA
|
||||
#define RANGECHECK
|
||||
#define ZDEBUG
|
||||
#endif
|
||||
|
||||
// Uncheck this to compile debugging code
|
||||
//#define RANGECHECK
|
||||
//#ifndef PARANOIA
|
||||
|
@ -150,7 +160,7 @@ extern char logfilename[1024];
|
|||
|
||||
// Does this version require an added patch file?
|
||||
// Comment or uncomment this as necessary.
|
||||
// #define USE_PATCH_DTA
|
||||
#define USE_PATCH_DTA
|
||||
|
||||
// Enforce a limit of loaded WAD files.
|
||||
//#define ENFORCE_WAD_LIMIT
|
||||
|
@ -259,66 +269,111 @@ typedef enum
|
|||
// Desaturated
|
||||
SKINCOLOR_AETHER,
|
||||
SKINCOLOR_SLATE,
|
||||
SKINCOLOR_MOONSTONE,
|
||||
SKINCOLOR_BLUEBELL,
|
||||
SKINCOLOR_PINK,
|
||||
SKINCOLOR_ROSEWOOD,
|
||||
SKINCOLOR_YOGURT,
|
||||
SKINCOLOR_LATTE,
|
||||
SKINCOLOR_BROWN,
|
||||
SKINCOLOR_BOULDER,
|
||||
SKINCOLOR_BRONZE,
|
||||
SKINCOLOR_SEPIA,
|
||||
SKINCOLOR_ECRU,
|
||||
SKINCOLOR_TAN,
|
||||
SKINCOLOR_BEIGE,
|
||||
SKINCOLOR_ROSEBUSH,
|
||||
SKINCOLOR_MOSS,
|
||||
SKINCOLOR_AZURE,
|
||||
SKINCOLOR_EGGPLANT,
|
||||
SKINCOLOR_LAVENDER,
|
||||
|
||||
// Viv's vivid colours (toast 21/07/17)
|
||||
// Tweaks & additions (Lach, sphere, Alice, MotorRoach 26/10/22)
|
||||
SKINCOLOR_RUBY,
|
||||
SKINCOLOR_CHERRY,
|
||||
SKINCOLOR_SALMON,
|
||||
SKINCOLOR_PEPPER,
|
||||
SKINCOLOR_RED,
|
||||
SKINCOLOR_CRIMSON,
|
||||
SKINCOLOR_FLAME,
|
||||
SKINCOLOR_GARNET,
|
||||
SKINCOLOR_KETCHUP,
|
||||
SKINCOLOR_PEACHY,
|
||||
SKINCOLOR_QUAIL,
|
||||
SKINCOLOR_FOUNDATION,
|
||||
SKINCOLOR_SUNSET,
|
||||
SKINCOLOR_COPPER,
|
||||
SKINCOLOR_APRICOT,
|
||||
SKINCOLOR_ORANGE,
|
||||
SKINCOLOR_RUST,
|
||||
SKINCOLOR_TANGERINE,
|
||||
SKINCOLOR_TOPAZ,
|
||||
SKINCOLOR_GOLD,
|
||||
SKINCOLOR_SANDY,
|
||||
SKINCOLOR_GOLDENROD,
|
||||
SKINCOLOR_YELLOW,
|
||||
SKINCOLOR_OLIVE,
|
||||
SKINCOLOR_PEAR,
|
||||
SKINCOLOR_LEMON,
|
||||
SKINCOLOR_LIME,
|
||||
SKINCOLOR_PERIDOT,
|
||||
SKINCOLOR_APPLE,
|
||||
SKINCOLOR_HEADLIGHT,
|
||||
SKINCOLOR_CHARTREUSE,
|
||||
SKINCOLOR_GREEN,
|
||||
SKINCOLOR_FOREST,
|
||||
SKINCOLOR_EMERALD,
|
||||
SKINCOLOR_SHAMROCK,
|
||||
SKINCOLOR_JADE,
|
||||
SKINCOLOR_MINT,
|
||||
SKINCOLOR_MASTER,
|
||||
SKINCOLOR_EMERALD,
|
||||
SKINCOLOR_SEAFOAM,
|
||||
SKINCOLOR_ISLAND,
|
||||
SKINCOLOR_BOTTLE,
|
||||
SKINCOLOR_AQUA,
|
||||
SKINCOLOR_TEAL,
|
||||
SKINCOLOR_OCEAN,
|
||||
SKINCOLOR_WAVE,
|
||||
SKINCOLOR_CYAN,
|
||||
SKINCOLOR_TURQUOISE,
|
||||
SKINCOLOR_AQUAMARINE,
|
||||
SKINCOLOR_SKY,
|
||||
SKINCOLOR_MARINE,
|
||||
SKINCOLOR_CERULEAN,
|
||||
SKINCOLOR_DREAM,
|
||||
SKINCOLOR_ICY,
|
||||
SKINCOLOR_DAYBREAK,
|
||||
SKINCOLOR_SAPPHIRE, // sweet mother, i cannot weave – slender aphrodite has overcome me with longing for a girl
|
||||
SKINCOLOR_ARCTIC,
|
||||
SKINCOLOR_CORNFLOWER,
|
||||
SKINCOLOR_BLUE,
|
||||
SKINCOLOR_COBALT,
|
||||
SKINCOLOR_MIDNIGHT,
|
||||
SKINCOLOR_GALAXY,
|
||||
SKINCOLOR_VAPOR,
|
||||
SKINCOLOR_DUSK,
|
||||
SKINCOLOR_MAJESTY,
|
||||
SKINCOLOR_PASTEL,
|
||||
SKINCOLOR_PURPLE,
|
||||
SKINCOLOR_NOBLE,
|
||||
SKINCOLOR_FUCHSIA,
|
||||
SKINCOLOR_BUBBLEGUM,
|
||||
SKINCOLOR_SIBERITE,
|
||||
SKINCOLOR_MAGENTA,
|
||||
SKINCOLOR_NEON,
|
||||
SKINCOLOR_VIOLET,
|
||||
SKINCOLOR_ROYAL,
|
||||
SKINCOLOR_LILAC,
|
||||
SKINCOLOR_MAUVE,
|
||||
SKINCOLOR_EVENTIDE,
|
||||
SKINCOLOR_PLUM,
|
||||
SKINCOLOR_RASPBERRY,
|
||||
SKINCOLOR_TAFFY,
|
||||
SKINCOLOR_ROSY,
|
||||
SKINCOLOR_FANCY,
|
||||
SKINCOLOR_SANGRIA,
|
||||
SKINCOLOR_VOLCANIC,
|
||||
|
||||
FIRSTSUPERCOLOR,
|
||||
|
||||
|
@ -590,7 +645,16 @@ UINT32 quickncasehash (const char *p, size_t n)
|
|||
#define PUNCTUATION "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~"
|
||||
|
||||
// Compile date and time and revision.
|
||||
extern const char *compdate, *comptime, *comprevision, *compbranch;
|
||||
extern const char
|
||||
*compdate,
|
||||
*comptime,
|
||||
*comprevision,
|
||||
*compbranch,
|
||||
*compnote,
|
||||
*comptype;
|
||||
extern int
|
||||
compuncommitted,
|
||||
compoptimized;
|
||||
|
||||
// Disabled code and code under testing
|
||||
// None of these that are disabled in the normal build are guaranteed to work perfectly
|
||||
|
|
|
@ -75,6 +75,7 @@ extern SINT8 startinglivesbalance[maxgameovers+1];
|
|||
extern boolean modifiedgame;
|
||||
extern UINT16 mainwads;
|
||||
extern boolean savemoddata; // This mod saves time/emblem data.
|
||||
extern boolean usedCheats;
|
||||
extern boolean disableSpeedAdjust; // Don't alter the duration of player states if true
|
||||
extern boolean imcontinuing; // Temporary flag while continuing
|
||||
extern boolean metalrecording;
|
||||
|
@ -131,8 +132,6 @@ extern INT32 postimgparam2;
|
|||
extern INT32 viewwindowx, viewwindowy;
|
||||
extern INT32 viewwidth, scaledviewwidth;
|
||||
|
||||
extern boolean gamedataloaded;
|
||||
|
||||
// Player taking events, and displaying.
|
||||
extern INT32 consoleplayer;
|
||||
extern INT32 displayplayer;
|
||||
|
@ -250,6 +249,7 @@ extern textprompt_t *textprompts[MAX_PROMPTS];
|
|||
// For the Custom Exit linedef.
|
||||
extern INT16 nextmapoverride;
|
||||
extern UINT8 skipstats;
|
||||
extern INT16 nextgametype;
|
||||
|
||||
extern UINT32 ssspheres; // Total # of spheres in a level
|
||||
|
||||
|
@ -494,8 +494,6 @@ typedef struct
|
|||
extern tolinfo_t TYPEOFLEVEL[NUMTOLNAMES];
|
||||
extern UINT32 lastcustomtol;
|
||||
|
||||
extern tic_t totalplaytime;
|
||||
|
||||
extern boolean stagefailed;
|
||||
|
||||
// Emeralds stored as bits to throw savegame hackers off.
|
||||
|
@ -514,52 +512,6 @@ extern INT32 luabanks[NUM_LUABANKS];
|
|||
|
||||
extern INT32 nummaprings; //keep track of spawned rings/coins
|
||||
|
||||
/** Time attack information, currently a very small structure.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
tic_t time; ///< Time in which the level was finished.
|
||||
UINT32 score; ///< Score when the level was finished.
|
||||
UINT16 rings; ///< Rings when the level was finished.
|
||||
} recorddata_t;
|
||||
|
||||
/** Setup for one NiGHTS map.
|
||||
* These are dynamically allocated because I am insane
|
||||
*/
|
||||
#define GRADE_F 0
|
||||
#define GRADE_E 1
|
||||
#define GRADE_D 2
|
||||
#define GRADE_C 3
|
||||
#define GRADE_B 4
|
||||
#define GRADE_A 5
|
||||
#define GRADE_S 6
|
||||
|
||||
typedef struct
|
||||
{
|
||||
// 8 mares, 1 overall (0)
|
||||
UINT8 nummares;
|
||||
UINT32 score[9];
|
||||
UINT8 grade[9];
|
||||
tic_t time[9];
|
||||
} nightsdata_t;
|
||||
|
||||
extern nightsdata_t *nightsrecords[NUMMAPS];
|
||||
extern recorddata_t *mainrecords[NUMMAPS];
|
||||
|
||||
// mapvisited is now a set of flags that says what we've done in the map.
|
||||
#define MV_VISITED 1
|
||||
#define MV_BEATEN 2
|
||||
#define MV_ALLEMERALDS 4
|
||||
#define MV_ULTIMATE 8
|
||||
#define MV_PERFECT 16
|
||||
#define MV_PERFECTRA 32
|
||||
#define MV_MAX 63 // used in gamedata check, update whenever MV's are added
|
||||
#define MV_MP 128
|
||||
extern UINT8 mapvisited[NUMMAPS];
|
||||
|
||||
// Temporary holding place for nights data for the current map
|
||||
extern nightsdata_t ntemprecords;
|
||||
|
||||
extern UINT32 token; ///< Number of tokens collected in a level
|
||||
extern UINT32 tokenlist; ///< List of tokens collected
|
||||
extern boolean gottoken; ///< Did you get a token? Used for end of act
|
||||
|
@ -592,9 +544,12 @@ extern UINT8 useBlackRock;
|
|||
|
||||
extern UINT8 use1upSound;
|
||||
extern UINT8 maxXtraLife; // Max extra lives from rings
|
||||
|
||||
extern UINT8 useContinues;
|
||||
#define continuesInSession (!multiplayer && (ultimatemode || (useContinues && !marathonmode) || (!modeattacking && !(cursaveslot > 0))))
|
||||
|
||||
extern UINT8 shareEmblems;
|
||||
|
||||
extern mobj_t *hunt1, *hunt2, *hunt3; // Emerald hunt locations
|
||||
|
||||
// For racing
|
||||
|
@ -615,10 +570,6 @@ extern INT32 cheats;
|
|||
|
||||
extern tic_t hidetime;
|
||||
|
||||
extern UINT32 timesBeaten; // # of times the game has been beaten.
|
||||
extern UINT32 timesBeatenWithEmeralds;
|
||||
extern UINT32 timesBeatenUltimate;
|
||||
|
||||
// ===========================
|
||||
// Internal parameters, fixed.
|
||||
// ===========================
|
||||
|
|
|
@ -17,6 +17,10 @@
|
|||
#ifndef __DOOMTYPE__
|
||||
#define __DOOMTYPE__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
//#define WIN32_LEAN_AND_MEAN
|
||||
#define RPC_NO_WINDOWS_H
|
||||
|
@ -78,7 +82,9 @@ typedef long ssize_t;
|
|||
#endif
|
||||
#define strncasecmp strnicmp
|
||||
#define strcasecmp stricmp
|
||||
#ifndef __cplusplus
|
||||
#define inline __inline
|
||||
#endif
|
||||
#elif defined (__WATCOMC__)
|
||||
#include <dos.h>
|
||||
#include <sys\types.h>
|
||||
|
@ -94,31 +100,28 @@ typedef long ssize_t;
|
|||
#define strnicmp(x,y,n) strncasecmp(x,y,n)
|
||||
#endif
|
||||
|
||||
char *strcasestr(const char *in, const char *what);
|
||||
char *nongnu_strcasestr(const char *in, const char *what);
|
||||
#ifndef _GNU_SOURCE
|
||||
#define strcasestr nongnu_strcasestr
|
||||
#endif
|
||||
#define stristr strcasestr
|
||||
|
||||
#if defined (macintosh) //|| defined (__APPLE__) //skip all boolean/Boolean crap
|
||||
#define true 1
|
||||
#define false 0
|
||||
#define min(x,y) (((x)<(y)) ? (x) : (y))
|
||||
#define max(x,y) (((x)>(y)) ? (x) : (y))
|
||||
|
||||
#ifdef macintosh
|
||||
#define stricmp strcmp
|
||||
#define strnicmp strncmp
|
||||
#endif
|
||||
|
||||
#define boolean INT32
|
||||
|
||||
#ifndef O_BINARY
|
||||
#define O_BINARY 0
|
||||
#endif
|
||||
#endif //macintosh
|
||||
int startswith (const char *base, const char *tag);
|
||||
int endswith (const char *base, const char *tag);
|
||||
|
||||
#if defined (_WIN32) || defined (__HAIKU__)
|
||||
#define HAVE_DOSSTR_FUNCS
|
||||
#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
|
||||
int strupr(char *n); // from dosstr.c
|
||||
int strlwr(char *n); // from dosstr.c
|
||||
|
@ -126,7 +129,7 @@ int strlwr(char *n); // from dosstr.c
|
|||
|
||||
#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 strlcpy(char *dst, const char *src, size_t siz);
|
||||
#endif
|
||||
|
@ -141,22 +144,24 @@ size_t strlcpy(char *dst, const char *src, size_t siz);
|
|||
|
||||
/* Boolean type definition */
|
||||
|
||||
// \note __BYTEBOOL__ used to be set above if "macintosh" was defined,
|
||||
// if macintosh's version of boolean type isn't needed anymore, then isn't this macro pointless now?
|
||||
#ifndef __BYTEBOOL__
|
||||
#define __BYTEBOOL__
|
||||
// Note: C++ bool and C99/C11 _Bool are NOT compatible.
|
||||
// Historically, boolean was win32 BOOL on Windows. For equivalence, it's now
|
||||
// int32_t. "true" and "false" are only declared for C code; in C++, conversion
|
||||
// between "bool" and "int32_t" takes over.
|
||||
#ifndef _WIN32
|
||||
typedef int32_t boolean;
|
||||
#else
|
||||
#define boolean BOOL
|
||||
#endif
|
||||
|
||||
//faB: clean that up !!
|
||||
#if defined( _MSC_VER) && (_MSC_VER >= 1800) // MSVC 2013 and forward
|
||||
#include "stdbool.h"
|
||||
#elif defined (_WIN32)
|
||||
#define false FALSE // use windows types
|
||||
#define true TRUE
|
||||
#define boolean BOOL
|
||||
#else
|
||||
typedef enum {false, true} boolean;
|
||||
#endif
|
||||
#endif // __BYTEBOOL__
|
||||
#ifndef __cplusplus
|
||||
#ifndef _WIN32
|
||||
enum {false = 0, true = 1};
|
||||
#else
|
||||
#define false FALSE
|
||||
#define true TRUE
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* 7.18.2.1 Limits of exact-width integer types */
|
||||
|
||||
|
@ -384,4 +389,8 @@ unset_bit_array (bitarray_t * const array, const int value)
|
|||
|
||||
typedef UINT64 precise_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif //__DOOMTYPE__
|
||||
|
|
|
@ -8,19 +8,24 @@ UINT8 graphics_started = 0;
|
|||
|
||||
UINT8 keyboard_started = 0;
|
||||
|
||||
UINT32 I_GetFreeMem(UINT32 *total)
|
||||
size_t I_GetFreeMem(size_t *total)
|
||||
{
|
||||
*total = 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;
|
||||
}
|
||||
|
||||
UINT64 I_GetPrecisePrecision(void) {
|
||||
UINT64 I_GetPrecisePrecision(void)
|
||||
{
|
||||
return 1000000;
|
||||
}
|
||||
|
||||
|
@ -180,7 +185,14 @@ const char *I_ClipboardPaste(void)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
void I_RegisterSysCommands(void) {}
|
||||
size_t I_GetRandomBytes(char *destination, size_t amount)
|
||||
{
|
||||
(void)destination;
|
||||
(void)amount;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void I_RegisterSysCommands(void){}
|
||||
|
||||
void I_GetCursorPosition(INT32 *x, INT32 *y)
|
||||
{
|
||||
|
|
|
@ -57,6 +57,8 @@ const char *VID_GetModeName(INT32 modenum)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
UINT32 I_GetRefreshRate(void) { return 35; }
|
||||
|
||||
void I_UpdateNoBlit(void){}
|
||||
|
||||
void I_FinishUpdate(void){}
|
||||
|
|
221
src/f_finale.c
221
src/f_finale.c
|
@ -63,7 +63,6 @@ static tic_t stoptimer;
|
|||
static boolean keypressed = false;
|
||||
|
||||
// (no longer) De-Demo'd Title Screen
|
||||
static INT32 menuanimtimer; // Title screen: background animation timing
|
||||
mobj_t *titlemapcameraref = NULL;
|
||||
|
||||
// menu presentation state
|
||||
|
@ -75,6 +74,8 @@ INT32 curbgyspeed;
|
|||
boolean curbghide;
|
||||
boolean hidetitlemap; // WARNING: set to false by M_SetupNextMenu and M_ClearMenus
|
||||
|
||||
static fixed_t curbgx = 0;
|
||||
static fixed_t curbgy = 0;
|
||||
static UINT8 curDemo = 0;
|
||||
static UINT32 demoDelayLeft;
|
||||
static UINT32 demoIdleLeft;
|
||||
|
@ -223,7 +224,6 @@ static INT32 cutscene_writeptr = 0;
|
|||
static INT32 cutscene_textcount = 0;
|
||||
static INT32 cutscene_textspeed = 0;
|
||||
static UINT8 cutscene_boostspeed = 0;
|
||||
static tic_t cutscene_lasttextwrite = 0;
|
||||
|
||||
// STJR Intro
|
||||
char stjrintro[9] = "STJRI000";
|
||||
|
@ -239,11 +239,6 @@ static UINT8 F_WriteText(void)
|
|||
{
|
||||
INT32 numtowrite = 1;
|
||||
const char *c;
|
||||
tic_t ltw = I_GetTime();
|
||||
|
||||
if (cutscene_lasttextwrite == ltw)
|
||||
return 1; // singletics prevention
|
||||
cutscene_lasttextwrite = ltw;
|
||||
|
||||
if (cutscene_boostspeed)
|
||||
{
|
||||
|
@ -337,7 +332,7 @@ static tic_t introscenetime[NUMINTROSCENES] =
|
|||
};
|
||||
|
||||
// custom intros
|
||||
void F_StartCustomCutscene(INT32 cutscenenum, boolean precutscene, boolean resetplayer);
|
||||
void F_StartCustomCutscene(INT32 cutscenenum, boolean precutscene, boolean resetplayer, boolean FLS);
|
||||
|
||||
void F_StartIntro(void)
|
||||
{
|
||||
|
@ -349,7 +344,7 @@ void F_StartIntro(void)
|
|||
if (!cutscenes[introtoplay - 1])
|
||||
D_StartTitle();
|
||||
else
|
||||
F_StartCustomCutscene(introtoplay - 1, false, false);
|
||||
F_StartCustomCutscene(introtoplay - 1, false, false, false);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1067,12 +1062,14 @@ static const char *credits[] = {
|
|||
"\"Golden\"",
|
||||
"Vivian \"toaster\" Grannell",
|
||||
"Julio \"Chaos Zero 64\" Guir",
|
||||
"\"Hanicef\"",
|
||||
"\"Hannu_Hanhi\"", // For many OpenGL performance improvements!
|
||||
"Kepa \"Nev3r\" Iceta",
|
||||
"Thomas \"Shadow Hog\" Igoe",
|
||||
"Iestyn \"Monster Iestyn\" Jealous",
|
||||
"\"Kaito Sinclaire\"",
|
||||
"\"Kalaron\"", // Coded some of Sryder13's collection of OpenGL fixes, especially fog
|
||||
"\"katsy\"",
|
||||
"Ronald \"Furyhunter\" Kinard", // The SDL2 port
|
||||
"\"Lat'\"", // SRB2-CHAT, the chat window from Kart
|
||||
"\"LZA\"",
|
||||
|
@ -1095,6 +1092,7 @@ static const char *credits[] = {
|
|||
"Ben \"Cue\" Woodford",
|
||||
"Lachlan \"Lach\" Wright",
|
||||
"Marco \"mazmazz\" Zafra",
|
||||
"\"Zwip-Zwap Zapony\"",
|
||||
"",
|
||||
"\1Art",
|
||||
"Victor \"VAdaPEGA\" Ara\x1Fjo", // Araújo -- sorry for our limited font! D:
|
||||
|
@ -1202,6 +1200,7 @@ static const char *credits[] = {
|
|||
"FreeDoom Project", // Used some of the mancubus and rocket launcher sprites for Brak
|
||||
"Kart Krew",
|
||||
"Alex \"MistaED\" Fuller",
|
||||
"Howard Drossin", // Virtual Sonic - Sonic & Knuckles Theme
|
||||
"Pascal \"CodeImp\" vd Heiden", // Doom Builder developer
|
||||
"Randi Heit (<!>)", // For their MSPaint <!> sprite that we nicked
|
||||
"Simon \"sirjuddington\" Judd", // SLADE developer
|
||||
|
@ -1257,7 +1256,7 @@ void F_StartCredits(void)
|
|||
|
||||
if (creditscutscene)
|
||||
{
|
||||
F_StartCustomCutscene(creditscutscene - 1, false, false);
|
||||
F_StartCustomCutscene(creditscutscene - 1, false, false, false);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1279,14 +1278,23 @@ void F_CreditDrawer(void)
|
|||
UINT16 i;
|
||||
INT16 zagpos = (timetonext - finalecount - animtimer) % 32;
|
||||
fixed_t y = (80<<FRACBITS) - (animtimer<<FRACBITS>>1);
|
||||
UINT8 colornum;
|
||||
const UINT8 *colormap;
|
||||
|
||||
if (players[consoleplayer].skincolor)
|
||||
colornum = players[consoleplayer].skincolor;
|
||||
else
|
||||
colornum = cv_playercolor.value;
|
||||
|
||||
colormap = R_GetTranslationColormap(TC_DEFAULT, colornum, GTC_CACHE);
|
||||
|
||||
V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31);
|
||||
|
||||
// Zig Zagz
|
||||
V_DrawScaledPatch(-16, zagpos, V_SNAPTOLEFT, W_CachePatchName("LTZIGZAG", PU_PATCH_LOWPRIORITY));
|
||||
V_DrawScaledPatch(-16, zagpos - 320, V_SNAPTOLEFT, W_CachePatchName("LTZIGZAG", PU_PATCH_LOWPRIORITY));
|
||||
V_DrawScaledPatch(BASEVIDWIDTH + 16, zagpos, V_SNAPTORIGHT|V_FLIP, W_CachePatchName("LTZIGZAG", PU_PATCH_LOWPRIORITY));
|
||||
V_DrawScaledPatch(BASEVIDWIDTH + 16, zagpos - 320, V_SNAPTORIGHT|V_FLIP, W_CachePatchName("LTZIGZAG", PU_PATCH_LOWPRIORITY));
|
||||
V_DrawFixedPatch(-16*FRACUNIT, zagpos<<FRACBITS, FRACUNIT, V_SNAPTOLEFT, W_CachePatchName("LTZIGZAG", PU_PATCH_LOWPRIORITY), colormap);
|
||||
V_DrawFixedPatch(-16*FRACUNIT, (zagpos - 320)<<FRACBITS, FRACUNIT, V_SNAPTOLEFT, W_CachePatchName("LTZIGZAG", PU_PATCH_LOWPRIORITY), colormap);
|
||||
V_DrawFixedPatch((BASEVIDWIDTH + 16)*FRACUNIT, zagpos<<FRACBITS, FRACUNIT, V_SNAPTORIGHT|V_FLIP, W_CachePatchName("LTZIGZAG", PU_PATCH_LOWPRIORITY), colormap);
|
||||
V_DrawFixedPatch((BASEVIDWIDTH + 16)*FRACUNIT, (zagpos - 320)<<FRACBITS, FRACUNIT, V_SNAPTORIGHT|V_FLIP, W_CachePatchName("LTZIGZAG", PU_PATCH_LOWPRIORITY), colormap);
|
||||
|
||||
// Draw background pictures first
|
||||
for (i = 0; credits_pics[i].patch; i++)
|
||||
|
@ -1411,7 +1419,7 @@ boolean F_CreditResponder(event_t *event)
|
|||
break;
|
||||
}
|
||||
|
||||
if (!(timesBeaten) && !(netgame || multiplayer) && !cv_debug)
|
||||
if (!(serverGamedata->timesBeaten) && !(netgame || multiplayer) && !cv_debug)
|
||||
return false;
|
||||
|
||||
if (event->type != ev_keydown)
|
||||
|
@ -1573,27 +1581,19 @@ void F_GameEvaluationDrawer(void)
|
|||
#if 0 // the following looks like hot garbage the more unlockables we add, and we now have a lot of unlockables
|
||||
if (finalecount >= 5*TICRATE)
|
||||
{
|
||||
INT32 startcoord = 32;
|
||||
V_DrawString(8, 16, V_YELLOWMAP, "Unlocked:");
|
||||
|
||||
if (!(netgame) && (!modifiedgame || savemoddata))
|
||||
for (i = 0; i < MAXUNLOCKABLES; i++)
|
||||
{
|
||||
INT32 startcoord = 32;
|
||||
|
||||
for (i = 0; i < MAXUNLOCKABLES; i++)
|
||||
if (unlockables[i].conditionset && unlockables[i].conditionset < MAXCONDITIONSETS
|
||||
&& unlockables[i].type && !unlockables[i].nocecho)
|
||||
{
|
||||
if (unlockables[i].conditionset && unlockables[i].conditionset < MAXCONDITIONSETS
|
||||
&& unlockables[i].type && !unlockables[i].nocecho)
|
||||
{
|
||||
if (unlockables[i].unlocked)
|
||||
V_DrawString(8, startcoord, 0, unlockables[i].name);
|
||||
startcoord += 8;
|
||||
}
|
||||
if (clientGamedata->unlocked[i])
|
||||
V_DrawString(8, startcoord, 0, unlockables[i].name);
|
||||
startcoord += 8;
|
||||
}
|
||||
}
|
||||
else if (netgame)
|
||||
V_DrawString(8, 96, V_YELLOWMAP, "Multiplayer games\ncan't unlock\nextras!");
|
||||
else
|
||||
V_DrawString(8, 96, V_YELLOWMAP, "Modified games\ncan't unlock\nextras!");
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -1648,37 +1648,29 @@ void F_GameEvaluationTicker(void)
|
|||
sparklloop = 0;
|
||||
}
|
||||
|
||||
if (finalecount == 5*TICRATE)
|
||||
if (G_CoopGametype() && !stagefailed && finalecount == 5*TICRATE)
|
||||
{
|
||||
if (netgame || multiplayer) // modify this when we finally allow unlocking stuff in 2P
|
||||
serverGamedata->timesBeaten++;
|
||||
clientGamedata->timesBeaten++;
|
||||
|
||||
if (ALL7EMERALDS(emeralds))
|
||||
{
|
||||
HU_SetCEchoFlags(V_YELLOWMAP|V_RETURN8);
|
||||
HU_SetCEchoDuration(6);
|
||||
HU_DoCEcho("\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\Multiplayer games can't unlock extras!");
|
||||
serverGamedata->timesBeatenWithEmeralds++;
|
||||
clientGamedata->timesBeatenWithEmeralds++;
|
||||
}
|
||||
|
||||
if (ultimatemode)
|
||||
{
|
||||
serverGamedata->timesBeatenUltimate++;
|
||||
clientGamedata->timesBeatenUltimate++;
|
||||
}
|
||||
|
||||
M_SilentUpdateUnlockablesAndEmblems(serverGamedata);
|
||||
|
||||
if (M_UpdateUnlockablesAndExtraEmblems(clientGamedata))
|
||||
S_StartSound(NULL, sfx_s3k68);
|
||||
}
|
||||
else if (!modifiedgame || savemoddata)
|
||||
{
|
||||
++timesBeaten;
|
||||
|
||||
if (ALL7EMERALDS(emeralds))
|
||||
++timesBeatenWithEmeralds;
|
||||
|
||||
if (ultimatemode)
|
||||
++timesBeatenUltimate;
|
||||
|
||||
if (M_UpdateUnlockablesAndExtraEmblems())
|
||||
S_StartSound(NULL, sfx_s3k68);
|
||||
|
||||
G_SaveGameData();
|
||||
}
|
||||
else
|
||||
{
|
||||
HU_SetCEchoFlags(V_YELLOWMAP|V_RETURN8);
|
||||
HU_SetCEchoDuration(6);
|
||||
HU_DoCEcho("\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\Modified games can't unlock extras!");
|
||||
S_StartSound(NULL, sfx_s3k68);
|
||||
}
|
||||
G_SaveGameData(clientGamedata);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2192,7 +2184,7 @@ void F_EndingDrawer(void)
|
|||
//colset(linkmap, 164, 165, 169); -- the ideal purple colour to represent a clicked in-game link, but not worth it just for a soundtest-controlled secret
|
||||
V_DrawCenteredString(BASEVIDWIDTH/2, 8, V_ALLOWLOWERCASE|(trans<<V_ALPHASHIFT), str);
|
||||
V_DrawCharacter(32, BASEVIDHEIGHT-16, '>'|(trans<<V_ALPHASHIFT), false);
|
||||
V_DrawString(40, ((finalecount == STOPPINGPOINT-(20+TICRATE)) ? 1 : 0)+BASEVIDHEIGHT-16, ((timesBeaten || finalecount >= STOPPINGPOINT-TICRATE) ? V_PURPLEMAP : V_BLUEMAP)|(trans<<V_ALPHASHIFT), " [S] ===>");
|
||||
V_DrawString(40, ((finalecount == STOPPINGPOINT-(20+TICRATE)) ? 1 : 0)+BASEVIDHEIGHT-16, ((serverGamedata->timesBeaten || finalecount >= STOPPINGPOINT-TICRATE) ? V_PURPLEMAP : V_BLUEMAP)|(trans<<V_ALPHASHIFT), " [S] ===>");
|
||||
}
|
||||
|
||||
if (finalecount > STOPPINGPOINT-(20+(2*TICRATE)))
|
||||
|
@ -2258,7 +2250,8 @@ void F_GameEndTicker(void)
|
|||
|
||||
void F_InitMenuPresValues(void)
|
||||
{
|
||||
menuanimtimer = 0;
|
||||
curbgx = 0;
|
||||
curbgy = 0;
|
||||
prevMenuId = 0;
|
||||
activeMenuId = MainDef.menuid;
|
||||
|
||||
|
@ -2267,7 +2260,7 @@ void F_InitMenuPresValues(void)
|
|||
curfadevalue = 16;
|
||||
curbgcolor = -1;
|
||||
curbgxspeed = (gamestate == GS_TIMEATTACK) ? 0 : titlescrollxspeed;
|
||||
curbgyspeed = (gamestate == GS_TIMEATTACK) ? 22 : titlescrollyspeed;
|
||||
curbgyspeed = (gamestate == GS_TIMEATTACK) ? 18 : titlescrollyspeed;
|
||||
curbghide = (gamestate == GS_TIMEATTACK) ? false : true;
|
||||
|
||||
curhidepics = hidetitlepics;
|
||||
|
@ -2291,17 +2284,11 @@ void F_InitMenuPresValues(void)
|
|||
//
|
||||
// F_SkyScroll
|
||||
//
|
||||
void F_SkyScroll(INT32 scrollxspeed, INT32 scrollyspeed, const char *patchname)
|
||||
void F_SkyScroll(const char *patchname)
|
||||
{
|
||||
INT32 xscrolled, x, xneg = (scrollxspeed > 0) - (scrollxspeed < 0), tilex;
|
||||
INT32 yscrolled, y, yneg = (scrollyspeed > 0) - (scrollyspeed < 0), tiley;
|
||||
boolean xispos = (scrollxspeed >= 0), yispos = (scrollyspeed >= 0);
|
||||
INT32 x, basey = 0;
|
||||
INT32 dupz = (vid.dupx < vid.dupy ? vid.dupx : vid.dupy);
|
||||
INT16 patwidth, patheight;
|
||||
INT32 pw, ph; // scaled by dupz
|
||||
patch_t *pat;
|
||||
INT32 i, j;
|
||||
fixed_t fracmenuanimtimer, xscrolltimer, yscrolltimer;
|
||||
|
||||
if (rendermode == render_none)
|
||||
return;
|
||||
|
@ -2312,43 +2299,34 @@ void F_SkyScroll(INT32 scrollxspeed, INT32 scrollyspeed, const char *patchname)
|
|||
return;
|
||||
}
|
||||
|
||||
if (!scrollxspeed && !scrollyspeed)
|
||||
pat = W_CachePatchName(patchname, PU_PATCH_LOWPRIORITY);
|
||||
|
||||
if (!curbgxspeed && !curbgyspeed)
|
||||
{
|
||||
V_DrawPatchFill(W_CachePatchName(patchname, PU_PATCH_LOWPRIORITY));
|
||||
V_DrawPatchFill(pat);
|
||||
W_UnlockCachedPatch(pat);
|
||||
return;
|
||||
}
|
||||
|
||||
pat = W_CachePatchName(patchname, PU_PATCH_LOWPRIORITY);
|
||||
// Modulo the background scrolling to prevent jumps from integer overflows
|
||||
// We already load the background patch here, so we can modulo it here
|
||||
// to avoid also having to load the patch in F_MenuPresTicker
|
||||
curbgx %= pat->width * 16;
|
||||
curbgy %= pat->height * 16;
|
||||
|
||||
patwidth = pat->width;
|
||||
patheight = pat->height;
|
||||
pw = patwidth * dupz;
|
||||
ph = patheight * dupz;
|
||||
// Ooh, fancy frame interpolation
|
||||
x = ((curbgx*dupz) + FixedInt((rendertimefrac-FRACUNIT) * curbgxspeed*dupz)) / 16;
|
||||
basey = ((curbgy*dupz) + FixedInt((rendertimefrac-FRACUNIT) * curbgyspeed*dupz)) / 16;
|
||||
|
||||
tilex = max(FixedCeil(FixedDiv(vid.width, pw)) >> FRACBITS, 1)+2; // one tile on both sides of center
|
||||
tiley = max(FixedCeil(FixedDiv(vid.height, ph)) >> FRACBITS, 1)+2;
|
||||
if (x > 0) // Make sure that we don't leave the left or top sides empty
|
||||
x -= pat->width * dupz;
|
||||
if (basey > 0)
|
||||
basey -= pat->height * dupz;
|
||||
|
||||
fracmenuanimtimer = (menuanimtimer * FRACUNIT) - (FRACUNIT - rendertimefrac);
|
||||
xscrolltimer = ((fracmenuanimtimer*scrollxspeed)/16 + patwidth*xneg*FRACUNIT) % (patwidth * FRACUNIT);
|
||||
yscrolltimer = ((fracmenuanimtimer*scrollyspeed)/16 + patheight*yneg*FRACUNIT) % (patheight * FRACUNIT);
|
||||
|
||||
// coordinate offsets
|
||||
xscrolled = FixedInt(xscrolltimer * dupz);
|
||||
yscrolled = FixedInt(yscrolltimer * dupz);
|
||||
|
||||
for (x = (xispos) ? -pw*(tilex-1)+pw : 0, i = 0;
|
||||
i < tilex;
|
||||
x += pw, i++)
|
||||
for (; x < vid.width; x += pat->width * dupz)
|
||||
{
|
||||
for (y = (yispos) ? -ph*(tiley-1)+ph : 0, j = 0;
|
||||
j < tiley;
|
||||
y += ph, j++)
|
||||
{
|
||||
V_DrawScaledPatch(
|
||||
(xispos) ? xscrolled - x : x + xscrolled,
|
||||
(yispos) ? yscrolled - y : y + yscrolled,
|
||||
V_NOSCALESTART, pat);
|
||||
}
|
||||
for (INT32 y = basey; y < vid.height; y += pat->height * dupz)
|
||||
V_DrawScaledPatch(x, y, V_NOSCALESTART, pat);
|
||||
}
|
||||
|
||||
W_UnlockCachedPatch(pat);
|
||||
|
@ -2671,7 +2649,7 @@ void F_TitleScreenDrawer(void)
|
|||
if (curbgcolor >= 0)
|
||||
V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, curbgcolor);
|
||||
else if (!curbghide || !titlemapinaction || gamestate == GS_WAITINGPLAYERS)
|
||||
F_SkyScroll(curbgxspeed, curbgyspeed, curbgname);
|
||||
F_SkyScroll(curbgname);
|
||||
|
||||
// Don't draw outside of the title screen, or if the patch isn't there.
|
||||
if (gamestate != GS_TITLESCREEN && gamestate != GS_WAITINGPLAYERS)
|
||||
|
@ -3426,10 +3404,10 @@ luahook:
|
|||
|
||||
// separate animation timer for backgrounds, since we also count
|
||||
// during GS_TIMEATTACK
|
||||
void F_MenuPresTicker(boolean run)
|
||||
void F_MenuPresTicker(void)
|
||||
{
|
||||
if (run)
|
||||
menuanimtimer++;
|
||||
curbgx += curbgxspeed;
|
||||
curbgy += curbgyspeed;
|
||||
}
|
||||
|
||||
// (no longer) De-Demo'd Title Screen
|
||||
|
@ -3535,6 +3513,7 @@ void F_TitleScreenTicker(boolean run)
|
|||
}
|
||||
|
||||
titledemo = true;
|
||||
demofileoverride = DFILE_OVERRIDE_NONE;
|
||||
G_DoPlayDemo(dname);
|
||||
}
|
||||
}
|
||||
|
@ -3859,7 +3838,7 @@ static INT32 scenenum, cutnum;
|
|||
static INT32 picxpos, picypos, picnum, pictime, picmode, numpics, pictoloop;
|
||||
static INT32 textxpos, textypos;
|
||||
static boolean cutsceneover = false;
|
||||
static boolean runningprecutscene = false, precutresetplayer = false;
|
||||
static boolean runningprecutscene = false, precutresetplayer = false, precutFLS = false;
|
||||
|
||||
static void F_AdvanceToNextScene(void)
|
||||
{
|
||||
|
@ -3928,7 +3907,7 @@ void F_EndCutScene(void)
|
|||
if (runningprecutscene)
|
||||
{
|
||||
if (server)
|
||||
D_MapChange(gamemap, gametype, ultimatemode, precutresetplayer, 0, true, false);
|
||||
D_MapChange(gamemap, gametype, ultimatemode, precutresetplayer, 0, true, precutFLS);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -3943,7 +3922,7 @@ void F_EndCutScene(void)
|
|||
}
|
||||
}
|
||||
|
||||
void F_StartCustomCutscene(INT32 cutscenenum, boolean precutscene, boolean resetplayer)
|
||||
void F_StartCustomCutscene(INT32 cutscenenum, boolean precutscene, boolean resetplayer, boolean FLS)
|
||||
{
|
||||
if (!cutscenes[cutscenenum])
|
||||
return;
|
||||
|
@ -3962,6 +3941,7 @@ void F_StartCustomCutscene(INT32 cutscenenum, boolean precutscene, boolean reset
|
|||
cutsceneover = false;
|
||||
runningprecutscene = precutscene;
|
||||
precutresetplayer = resetplayer;
|
||||
precutFLS = FLS;
|
||||
|
||||
scenenum = picnum = 0;
|
||||
cutnum = cutscenenum;
|
||||
|
@ -4694,3 +4674,36 @@ void F_TextPromptTicker(void)
|
|||
animtimer--;
|
||||
}
|
||||
}
|
||||
|
||||
// ================
|
||||
// WAITINGPLAYERS
|
||||
// ================
|
||||
|
||||
void F_StartWaitingPlayers(void)
|
||||
{
|
||||
wipegamestate = GS_TITLESCREEN; // technically wiping from title screen
|
||||
finalecount = 0;
|
||||
}
|
||||
|
||||
void F_WaitingPlayersTicker(void)
|
||||
{
|
||||
if (paused)
|
||||
return;
|
||||
|
||||
finalecount++;
|
||||
|
||||
// dumb hack, only start the music on the 1st tick so if you instantly go into the map you aren't hearing a tic of music
|
||||
if (finalecount == 2)
|
||||
S_ChangeMusicInternal("_CHSEL", true);
|
||||
}
|
||||
|
||||
void F_WaitingPlayersDrawer(void)
|
||||
{
|
||||
const char *waittext1 = "You will join";
|
||||
const char *waittext2 = "next level...";
|
||||
|
||||
V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31);
|
||||
|
||||
V_DrawCreditString((160 - (V_CreditStringWidth(waittext1)>>1))<<FRACBITS, 48<<FRACBITS, 0, waittext1);
|
||||
V_DrawCreditString((160 - (V_CreditStringWidth(waittext2)>>1))<<FRACBITS, 64<<FRACBITS, 0, waittext2);
|
||||
}
|
||||
|
|
|
@ -40,7 +40,7 @@ void F_TextPromptTicker(void);
|
|||
void F_GameEndDrawer(void);
|
||||
void F_IntroDrawer(void);
|
||||
void F_TitleScreenDrawer(void);
|
||||
void F_SkyScroll(INT32 scrollxspeed, INT32 scrollyspeed, const char *patchname);
|
||||
void F_SkyScroll(const char *patchname);
|
||||
|
||||
void F_GameEvaluationDrawer(void);
|
||||
void F_StartGameEvaluation(void);
|
||||
|
@ -52,7 +52,7 @@ void F_EndingDrawer(void);
|
|||
void F_CreditTicker(void);
|
||||
void F_CreditDrawer(void);
|
||||
|
||||
void F_StartCustomCutscene(INT32 cutscenenum, boolean precutscene, boolean resetplayer);
|
||||
void F_StartCustomCutscene(INT32 cutscenenum, boolean precutscene, boolean resetplayer, boolean FLS);
|
||||
void F_CutsceneDrawer(void);
|
||||
void F_EndCutScene(void);
|
||||
|
||||
|
@ -74,6 +74,10 @@ void F_StartContinue(void);
|
|||
void F_ContinueTicker(void);
|
||||
void F_ContinueDrawer(void);
|
||||
|
||||
void F_StartWaitingPlayers(void);
|
||||
void F_WaitingPlayersTicker(void);
|
||||
void F_WaitingPlayersDrawer(void);
|
||||
|
||||
extern INT32 finalecount;
|
||||
extern INT32 titlescrollxspeed;
|
||||
extern INT32 titlescrollyspeed;
|
||||
|
@ -131,7 +135,7 @@ extern UINT16 curtttics;
|
|||
#define TITLEBACKGROUNDACTIVE (curfadevalue >= 0 || curbgname[0])
|
||||
|
||||
void F_InitMenuPresValues(void);
|
||||
void F_MenuPresTicker(boolean run);
|
||||
void F_MenuPresTicker(void);
|
||||
|
||||
//
|
||||
// WIPE
|
||||
|
|
|
@ -614,6 +614,8 @@ void F_RunWipe(UINT8 wipetype, boolean drawMenu)
|
|||
|
||||
if (moviemode)
|
||||
M_SaveFrame();
|
||||
|
||||
NetKeepAlive(); // Update the network so we don't cause timeouts
|
||||
}
|
||||
|
||||
WipeInAction = false;
|
||||
|
|
|
@ -39,6 +39,7 @@
|
|||
|
||||
#define SUFFIX "*"
|
||||
#define SLASH "\\"
|
||||
#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
|
||||
#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
|
||||
|
||||
#ifndef INVALID_FILE_ATTRIBUTES
|
||||
|
@ -307,6 +308,39 @@ closedir (DIR * dirp)
|
|||
}
|
||||
#endif
|
||||
|
||||
// fopen but it REALLY only works on regular files
|
||||
// Turns out, on linux, anyway, you can fopen directories
|
||||
// in read mode. (It's supposed to fail in write mode
|
||||
// though!!)
|
||||
FILE *fopenfile(const char *path, const char *mode)
|
||||
{
|
||||
FILE *h = fopen(path, mode);
|
||||
|
||||
if (h != NULL)
|
||||
{
|
||||
struct stat st;
|
||||
int eno;
|
||||
|
||||
if (fstat(fileno(h), &st) == -1)
|
||||
{
|
||||
eno = errno;
|
||||
}
|
||||
else if (!S_ISREG(st.st_mode))
|
||||
{
|
||||
eno = EACCES; // set some kinda error
|
||||
}
|
||||
else
|
||||
{
|
||||
return h; // ok
|
||||
}
|
||||
|
||||
fclose(h);
|
||||
errno = eno;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static CV_PossibleValue_t addons_cons_t[] = {{0, "Default"},
|
||||
#if 1
|
||||
{1, "HOME"}, {2, "SRB2"},
|
||||
|
|
438
src/g_demo.c
438
src/g_demo.c
|
@ -39,6 +39,7 @@
|
|||
#include "v_video.h"
|
||||
#include "lua_hook.h"
|
||||
#include "md5.h" // demo checksums
|
||||
#include "d_netfil.h" // G_CheckDemoExtraFiles
|
||||
|
||||
boolean timingdemo; // if true, exit with report on completion
|
||||
boolean nodrawers; // for comparative timing purposes
|
||||
|
@ -49,6 +50,7 @@ static char demoname[64];
|
|||
boolean demorecording;
|
||||
boolean demoplayback;
|
||||
boolean titledemo; // Title Screen demo can be cancelled by any key
|
||||
demo_file_override_e demofileoverride;
|
||||
static UINT8 *demobuffer = NULL;
|
||||
static UINT8 *demo_p, *demotime_p;
|
||||
static UINT8 *demoend;
|
||||
|
@ -56,6 +58,7 @@ static UINT8 demoflags;
|
|||
static UINT16 demoversion;
|
||||
boolean singledemo; // quit after playing a demo from cmdline
|
||||
boolean demo_start; // don't start playing demo right away
|
||||
boolean demo_forwardmove_rng; // old demo backwards compatibility
|
||||
boolean demosynced = true; // console warning message
|
||||
|
||||
boolean metalrecording; // recording as metal sonic
|
||||
|
@ -95,7 +98,7 @@ demoghost *ghosts = NULL;
|
|||
// DEMO RECORDING
|
||||
//
|
||||
|
||||
#define DEMOVERSION 0x000f
|
||||
#define DEMOVERSION 0x0010
|
||||
#define DEMOHEADER "\xF0" "SRB2Replay" "\x0F"
|
||||
|
||||
#define DF_GHOST 0x01 // This demo contains ghost data too!
|
||||
|
@ -1413,6 +1416,10 @@ void G_BeginRecording(void)
|
|||
char name[MAXCOLORNAME+1];
|
||||
player_t *player = &players[consoleplayer];
|
||||
|
||||
char *filename;
|
||||
UINT16 totalfiles;
|
||||
UINT8 *m;
|
||||
|
||||
if (demo_p)
|
||||
return;
|
||||
memset(name,0,sizeof(name));
|
||||
|
@ -1435,23 +1442,43 @@ void G_BeginRecording(void)
|
|||
M_Memcpy(demo_p, mapmd5, 16); demo_p += 16;
|
||||
|
||||
WRITEUINT8(demo_p,demoflags);
|
||||
|
||||
// file list
|
||||
m = demo_p;/* file count */
|
||||
demo_p += 2;
|
||||
|
||||
totalfiles = 0;
|
||||
for (i = mainwads; ++i < numwadfiles; )
|
||||
{
|
||||
if (wadfiles[i]->important)
|
||||
{
|
||||
nameonly(( filename = va("%s", wadfiles[i]->filename) ));
|
||||
WRITESTRINGL(demo_p, filename, MAX_WADPATH);
|
||||
WRITEMEM(demo_p, wadfiles[i]->md5sum, 16);
|
||||
|
||||
totalfiles++;
|
||||
}
|
||||
}
|
||||
|
||||
WRITEUINT16(m, totalfiles);
|
||||
|
||||
switch ((demoflags & DF_ATTACKMASK)>>DF_ATTACKSHIFT)
|
||||
{
|
||||
case ATTACKING_NONE: // 0
|
||||
break;
|
||||
case ATTACKING_RECORD: // 1
|
||||
demotime_p = demo_p;
|
||||
WRITEUINT32(demo_p,UINT32_MAX); // time
|
||||
WRITEUINT32(demo_p,0); // score
|
||||
WRITEUINT16(demo_p,0); // rings
|
||||
break;
|
||||
case ATTACKING_NIGHTS: // 2
|
||||
demotime_p = demo_p;
|
||||
WRITEUINT32(demo_p,UINT32_MAX); // time
|
||||
WRITEUINT32(demo_p,0); // score
|
||||
break;
|
||||
default: // 3
|
||||
break;
|
||||
case ATTACKING_NONE: // 0
|
||||
break;
|
||||
case ATTACKING_RECORD: // 1
|
||||
demotime_p = demo_p;
|
||||
WRITEUINT32(demo_p,UINT32_MAX); // time
|
||||
WRITEUINT32(demo_p,0); // score
|
||||
WRITEUINT16(demo_p,0); // rings
|
||||
break;
|
||||
case ATTACKING_NIGHTS: // 2
|
||||
demotime_p = demo_p;
|
||||
WRITEUINT32(demo_p,UINT32_MAX); // time
|
||||
WRITEUINT32(demo_p,0); // score
|
||||
break;
|
||||
default: // 3
|
||||
break;
|
||||
}
|
||||
|
||||
WRITEUINT32(demo_p,P_GetInitSeed());
|
||||
|
@ -1483,18 +1510,18 @@ void G_BeginRecording(void)
|
|||
// Stats
|
||||
WRITEUINT8(demo_p,player->charability);
|
||||
WRITEUINT8(demo_p,player->charability2);
|
||||
WRITEUINT8(demo_p,player->actionspd>>FRACBITS);
|
||||
WRITEUINT8(demo_p,player->mindash>>FRACBITS);
|
||||
WRITEUINT8(demo_p,player->maxdash>>FRACBITS);
|
||||
WRITEUINT8(demo_p,player->normalspeed>>FRACBITS);
|
||||
WRITEUINT8(demo_p,player->runspeed>>FRACBITS);
|
||||
WRITEFIXED(demo_p,player->actionspd);
|
||||
WRITEFIXED(demo_p,player->mindash);
|
||||
WRITEFIXED(demo_p,player->maxdash);
|
||||
WRITEFIXED(demo_p,player->normalspeed);
|
||||
WRITEFIXED(demo_p,player->runspeed);
|
||||
WRITEUINT8(demo_p,player->thrustfactor);
|
||||
WRITEUINT8(demo_p,player->accelstart);
|
||||
WRITEUINT8(demo_p,player->acceleration);
|
||||
WRITEFIXED(demo_p,player->height);
|
||||
WRITEFIXED(demo_p,player->spinheight);
|
||||
WRITEUINT8(demo_p,player->camerascale>>FRACBITS);
|
||||
WRITEUINT8(demo_p,player->shieldscale>>FRACBITS);
|
||||
WRITEFIXED(demo_p,player->camerascale);
|
||||
WRITEFIXED(demo_p,player->shieldscale);
|
||||
|
||||
// Trying to convert it back to % causes demo desync due to precision loss.
|
||||
// Don't do it.
|
||||
|
@ -1590,6 +1617,183 @@ void G_BeginMetal(void)
|
|||
oldmetal.angle = mo->angle>>24;
|
||||
}
|
||||
|
||||
static void G_LoadDemoExtraFiles(UINT8 **pp, UINT16 this_demo_version)
|
||||
{
|
||||
UINT16 totalfiles;
|
||||
char filename[MAX_WADPATH];
|
||||
UINT8 md5sum[16];
|
||||
filestatus_t ncs;
|
||||
boolean toomany = false;
|
||||
boolean alreadyloaded;
|
||||
UINT16 i, j;
|
||||
|
||||
if (this_demo_version < 0x0010)
|
||||
{
|
||||
// demo has no file list
|
||||
return;
|
||||
}
|
||||
|
||||
totalfiles = READUINT16((*pp));
|
||||
for (i = 0; i < totalfiles; ++i)
|
||||
{
|
||||
if (toomany)
|
||||
SKIPSTRING((*pp));
|
||||
else
|
||||
{
|
||||
strlcpy(filename, (char *)(*pp), sizeof filename);
|
||||
SKIPSTRING((*pp));
|
||||
}
|
||||
READMEM((*pp), md5sum, 16);
|
||||
|
||||
if (!toomany)
|
||||
{
|
||||
alreadyloaded = false;
|
||||
|
||||
for (j = 0; j < numwadfiles; ++j)
|
||||
{
|
||||
if (memcmp(md5sum, wadfiles[j]->md5sum, 16) == 0)
|
||||
{
|
||||
alreadyloaded = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (alreadyloaded)
|
||||
continue;
|
||||
|
||||
if (numwadfiles >= MAX_WADFILES)
|
||||
toomany = true;
|
||||
else
|
||||
ncs = findfile(filename, md5sum, false);
|
||||
|
||||
if (toomany)
|
||||
{
|
||||
CONS_Alert(CONS_WARNING, M_GetText("Too many files loaded to add anymore for demo playback\n"));
|
||||
if (!CON_Ready())
|
||||
M_StartMessage(M_GetText("There are too many files loaded to add this demo's addons.\n\nDemo playback may desync.\n\nPress ESC\n"), NULL, MM_NOTHING);
|
||||
}
|
||||
else if (ncs != FS_FOUND)
|
||||
{
|
||||
if (ncs == FS_NOTFOUND)
|
||||
CONS_Alert(CONS_NOTICE, M_GetText("You do not have a copy of %s\n"), filename);
|
||||
else if (ncs == FS_MD5SUMBAD)
|
||||
CONS_Alert(CONS_NOTICE, M_GetText("Checksum mismatch on %s\n"), filename);
|
||||
else
|
||||
CONS_Alert(CONS_NOTICE, M_GetText("Unknown error finding file %s\n"), filename);
|
||||
|
||||
if (!CON_Ready())
|
||||
M_StartMessage(M_GetText("There were errors trying to add this demo's addons. Check the console for more information.\n\nDemo playback may desync.\n\nPress ESC\n"), NULL, MM_NOTHING);
|
||||
}
|
||||
else
|
||||
{
|
||||
P_AddWadFile(filename);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void G_SkipDemoExtraFiles(UINT8 **pp, UINT16 this_demo_version)
|
||||
{
|
||||
UINT16 totalfiles;
|
||||
UINT16 i;
|
||||
|
||||
if (this_demo_version < 0x0010)
|
||||
{
|
||||
// demo has no file list
|
||||
return;
|
||||
}
|
||||
|
||||
totalfiles = READUINT16((*pp));
|
||||
for (i = 0; i < totalfiles; ++i)
|
||||
{
|
||||
SKIPSTRING((*pp));// file name
|
||||
(*pp) += 16;// md5
|
||||
}
|
||||
}
|
||||
|
||||
// G_CheckDemoExtraFiles: checks if our loaded WAD list matches the demo's.
|
||||
// Enabling quick prevents filesystem checks to see if needed files are available to load.
|
||||
static UINT8 G_CheckDemoExtraFiles(UINT8 **pp, boolean quick, UINT16 this_demo_version)
|
||||
{
|
||||
UINT16 totalfiles, filesloaded, nmusfilecount;
|
||||
char filename[MAX_WADPATH];
|
||||
UINT8 md5sum[16];
|
||||
boolean toomany = false;
|
||||
boolean alreadyloaded;
|
||||
UINT16 i, j;
|
||||
UINT8 error = DFILE_ERROR_NONE;
|
||||
|
||||
if (this_demo_version < 0x0010)
|
||||
{
|
||||
// demo has no file list
|
||||
return DFILE_ERROR_NONE;
|
||||
}
|
||||
|
||||
totalfiles = READUINT16((*pp));
|
||||
filesloaded = 0;
|
||||
for (i = 0; i < totalfiles; ++i)
|
||||
{
|
||||
if (toomany)
|
||||
SKIPSTRING((*pp));
|
||||
else
|
||||
{
|
||||
strlcpy(filename, (char *)(*pp), sizeof filename);
|
||||
SKIPSTRING((*pp));
|
||||
}
|
||||
READMEM((*pp), md5sum, 16);
|
||||
|
||||
if (!toomany)
|
||||
{
|
||||
alreadyloaded = false;
|
||||
nmusfilecount = 0;
|
||||
|
||||
for (j = 0; j < numwadfiles; ++j)
|
||||
{
|
||||
if (wadfiles[j]->important && j > mainwads)
|
||||
nmusfilecount++;
|
||||
else
|
||||
continue;
|
||||
|
||||
if (memcmp(md5sum, wadfiles[j]->md5sum, 16) == 0)
|
||||
{
|
||||
alreadyloaded = true;
|
||||
|
||||
if (i != nmusfilecount-1 && error < DFILE_ERROR_OUTOFORDER)
|
||||
error |= DFILE_ERROR_OUTOFORDER;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (alreadyloaded)
|
||||
{
|
||||
filesloaded++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (numwadfiles >= MAX_WADFILES)
|
||||
error = DFILE_ERROR_CANNOTLOAD;
|
||||
else if (!quick && findfile(filename, md5sum, false) != FS_FOUND)
|
||||
error = DFILE_ERROR_CANNOTLOAD;
|
||||
else if (error < DFILE_ERROR_INCOMPLETEOUTOFORDER)
|
||||
error |= DFILE_ERROR_NOTLOADED;
|
||||
} else
|
||||
error = DFILE_ERROR_CANNOTLOAD;
|
||||
}
|
||||
|
||||
// Get final file count
|
||||
nmusfilecount = 0;
|
||||
|
||||
for (j = 0; j < numwadfiles; ++j)
|
||||
if (wadfiles[j]->important && j > mainwads)
|
||||
nmusfilecount++;
|
||||
|
||||
if (!error && filesloaded < nmusfilecount)
|
||||
error = DFILE_ERROR_EXTRAFILES;
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
void G_SetDemoTime(UINT32 ptime, UINT32 pscore, UINT16 prings)
|
||||
{
|
||||
if (!demorecording || !demotime_p)
|
||||
|
@ -1618,10 +1822,9 @@ UINT8 G_CmpDemoTime(char *oldname, char *newname)
|
|||
UINT8 *buffer,*p;
|
||||
UINT8 flags;
|
||||
UINT32 oldtime, newtime, oldscore, newscore;
|
||||
UINT16 oldrings, newrings, oldversion;
|
||||
UINT16 oldrings, newrings, oldversion, newversion;
|
||||
size_t bufsize ATTRUNUSED;
|
||||
UINT8 c;
|
||||
UINT16 s ATTRUNUSED;
|
||||
UINT8 aflags = 0;
|
||||
|
||||
// load the new file
|
||||
|
@ -1637,15 +1840,15 @@ UINT8 G_CmpDemoTime(char *oldname, char *newname)
|
|||
I_Assert(c == VERSION);
|
||||
c = READUINT8(p); // SUBVERSION
|
||||
I_Assert(c == SUBVERSION);
|
||||
s = READUINT16(p);
|
||||
I_Assert(s >= 0x000c);
|
||||
newversion = READUINT16(p);
|
||||
I_Assert(newversion == DEMOVERSION);
|
||||
p += 16; // demo checksum
|
||||
I_Assert(!memcmp(p, "PLAY", 4));
|
||||
p += 4; // PLAY
|
||||
p += 2; // gamemap
|
||||
p += 16; // map md5
|
||||
flags = READUINT8(p); // demoflags
|
||||
|
||||
G_SkipDemoExtraFiles(&p, newversion);
|
||||
aflags = flags & (DF_RECORDATTACK|DF_NIGHTSATTACK);
|
||||
I_Assert(aflags);
|
||||
if (flags & DF_RECORDATTACK)
|
||||
|
@ -1687,7 +1890,8 @@ UINT8 G_CmpDemoTime(char *oldname, char *newname)
|
|||
switch(oldversion) // demoversion
|
||||
{
|
||||
case DEMOVERSION: // latest always supported
|
||||
case 0x000e: // The previous demoversions also supported
|
||||
case 0x000f: // The previous demoversions also supported
|
||||
case 0x000e:
|
||||
case 0x000d: // all that changed between then and now was longer color name
|
||||
case 0x000c:
|
||||
break;
|
||||
|
@ -1710,6 +1914,7 @@ UINT8 G_CmpDemoTime(char *oldname, char *newname)
|
|||
p += 2; // gamemap
|
||||
p += 16; // mapmd5
|
||||
flags = READUINT8(p);
|
||||
G_SkipDemoExtraFiles(&p, oldversion);
|
||||
if (!(flags & aflags))
|
||||
{
|
||||
CONS_Alert(CONS_NOTICE, M_GetText("File '%s' not from same game mode. It will be overwritten.\n"), oldname);
|
||||
|
@ -1829,8 +2034,10 @@ void G_DoPlayDemo(char *defdemoname)
|
|||
version = READUINT8(demo_p);
|
||||
subversion = READUINT8(demo_p);
|
||||
demoversion = READUINT16(demo_p);
|
||||
demo_forwardmove_rng = (demoversion < 0x0010);
|
||||
switch(demoversion)
|
||||
{
|
||||
case 0x000f:
|
||||
case 0x000d:
|
||||
case 0x000e:
|
||||
case DEMOVERSION: // latest always supported
|
||||
|
@ -1871,6 +2078,69 @@ void G_DoPlayDemo(char *defdemoname)
|
|||
demo_p += 16; // mapmd5
|
||||
|
||||
demoflags = READUINT8(demo_p);
|
||||
|
||||
if (titledemo)
|
||||
{
|
||||
// Titledemos should always play and ought to always be compatible with whatever wadlist is running.
|
||||
G_SkipDemoExtraFiles(&demo_p, demoversion);
|
||||
}
|
||||
else if (demofileoverride == DFILE_OVERRIDE_LOAD)
|
||||
{
|
||||
G_LoadDemoExtraFiles(&demo_p, demoversion);
|
||||
}
|
||||
else if (demofileoverride == DFILE_OVERRIDE_SKIP)
|
||||
{
|
||||
G_SkipDemoExtraFiles(&demo_p, demoversion);
|
||||
}
|
||||
else
|
||||
{
|
||||
UINT8 error = G_CheckDemoExtraFiles(&demo_p, false, demoversion);
|
||||
|
||||
if (error)
|
||||
{
|
||||
switch (error)
|
||||
{
|
||||
case DFILE_ERROR_NOTLOADED:
|
||||
snprintf(msg, 1024,
|
||||
M_GetText("Required files for this demo are not loaded.\n\nUse\n\"playdemo %s -addfiles\"\nto load them and play the demo.\n"),
|
||||
pdemoname);
|
||||
break;
|
||||
|
||||
case DFILE_ERROR_OUTOFORDER:
|
||||
snprintf(msg, 1024,
|
||||
M_GetText("Required files for this demo are loaded out of order.\n\nUse\n\"playdemo %s -force\"\nto play the demo anyway.\n"),
|
||||
pdemoname);
|
||||
break;
|
||||
|
||||
case DFILE_ERROR_INCOMPLETEOUTOFORDER:
|
||||
snprintf(msg, 1024,
|
||||
M_GetText("Required files for this demo are not loaded, and some are out of order.\n\nUse\n\"playdemo %s -addfiles\"\nto load needed files and play the demo.\n"),
|
||||
pdemoname);
|
||||
break;
|
||||
|
||||
case DFILE_ERROR_CANNOTLOAD:
|
||||
snprintf(msg, 1024,
|
||||
M_GetText("Required files for this demo cannot be loaded.\n\nUse\n\"playdemo %s -force\"\nto play the demo anyway.\n"),
|
||||
pdemoname);
|
||||
break;
|
||||
|
||||
case DFILE_ERROR_EXTRAFILES:
|
||||
snprintf(msg, 1024,
|
||||
M_GetText("You have additional files loaded beyond the demo's file list.\n\nUse\n\"playdemo %s -force\"\nto play the demo anyway.\n"),
|
||||
pdemoname);
|
||||
break;
|
||||
}
|
||||
|
||||
CONS_Alert(CONS_ERROR, "%s", msg);
|
||||
M_StartMessage(msg, NULL, MM_NOTHING);
|
||||
Z_Free(pdemoname);
|
||||
Z_Free(demobuffer);
|
||||
demoplayback = false;
|
||||
titledemo = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
modeattacking = (demoflags & DF_ATTACKMASK)>>DF_ATTACKSHIFT;
|
||||
CON_ToggleOff();
|
||||
|
||||
|
@ -1913,18 +2183,18 @@ void G_DoPlayDemo(char *defdemoname)
|
|||
|
||||
charability = READUINT8(demo_p);
|
||||
charability2 = READUINT8(demo_p);
|
||||
actionspd = (fixed_t)READUINT8(demo_p)<<FRACBITS;
|
||||
mindash = (fixed_t)READUINT8(demo_p)<<FRACBITS;
|
||||
maxdash = (fixed_t)READUINT8(demo_p)<<FRACBITS;
|
||||
normalspeed = (fixed_t)READUINT8(demo_p)<<FRACBITS;
|
||||
runspeed = (fixed_t)READUINT8(demo_p)<<FRACBITS;
|
||||
actionspd = (demoversion < 0x0010) ? (fixed_t)READUINT8(demo_p)<<FRACBITS : READFIXED(demo_p);
|
||||
mindash = (demoversion < 0x0010) ? (fixed_t)READUINT8(demo_p)<<FRACBITS : READFIXED(demo_p);
|
||||
maxdash = (demoversion < 0x0010) ? (fixed_t)READUINT8(demo_p)<<FRACBITS : READFIXED(demo_p);
|
||||
normalspeed = (demoversion < 0x0010) ? (fixed_t)READUINT8(demo_p)<<FRACBITS : READFIXED(demo_p);
|
||||
runspeed = (demoversion < 0x0010) ? (fixed_t)READUINT8(demo_p)<<FRACBITS : READFIXED(demo_p);
|
||||
thrustfactor = READUINT8(demo_p);
|
||||
accelstart = READUINT8(demo_p);
|
||||
acceleration = READUINT8(demo_p);
|
||||
height = (demoversion < 0x000e) ? (fixed_t)READUINT8(demo_p)<<FRACBITS : READFIXED(demo_p);
|
||||
spinheight = (demoversion < 0x000e) ? (fixed_t)READUINT8(demo_p)<<FRACBITS : READFIXED(demo_p);
|
||||
camerascale = (fixed_t)READUINT8(demo_p)<<FRACBITS;
|
||||
shieldscale = (fixed_t)READUINT8(demo_p)<<FRACBITS;
|
||||
camerascale = (demoversion < 0x0010) ? (fixed_t)READUINT8(demo_p)<<FRACBITS : READFIXED(demo_p);
|
||||
shieldscale = (demoversion < 0x0010) ? (fixed_t)READUINT8(demo_p)<<FRACBITS : READFIXED(demo_p);
|
||||
jumpfactor = READFIXED(demo_p);
|
||||
followitem = READUINT32(demo_p);
|
||||
|
||||
|
@ -2026,6 +2296,88 @@ void G_DoPlayDemo(char *defdemoname)
|
|||
demo_start = true;
|
||||
}
|
||||
|
||||
//
|
||||
// Check if a replay can be loaded from the menu
|
||||
//
|
||||
UINT8 G_CheckDemoForError(char *defdemoname)
|
||||
{
|
||||
lumpnum_t l;
|
||||
char *n,*pdemoname;
|
||||
UINT16 our_demo_version;
|
||||
|
||||
if (titledemo)
|
||||
{
|
||||
// Don't do anything with files for these.
|
||||
return DFILE_ERROR_NONE;
|
||||
}
|
||||
|
||||
n = defdemoname+strlen(defdemoname);
|
||||
while (*n != '/' && *n != '\\' && n != defdemoname)
|
||||
n--;
|
||||
if (n != defdemoname)
|
||||
n++;
|
||||
pdemoname = ZZ_Alloc(strlen(n)+1);
|
||||
strcpy(pdemoname,n);
|
||||
|
||||
// Internal if no extension, external if one exists
|
||||
if (FIL_CheckExtension(defdemoname))
|
||||
{
|
||||
//FIL_DefaultExtension(defdemoname, ".lmp");
|
||||
if (!FIL_ReadFile(defdemoname, &demobuffer))
|
||||
{
|
||||
return DFILE_ERROR_NOTDEMO;
|
||||
}
|
||||
demo_p = demobuffer;
|
||||
}
|
||||
// load demo resource from WAD
|
||||
else if ((l = W_CheckNumForName(defdemoname)) == LUMPERROR)
|
||||
{
|
||||
return DFILE_ERROR_NOTDEMO;
|
||||
}
|
||||
else // it's an internal demo
|
||||
{
|
||||
demobuffer = demo_p = W_CacheLumpNum(l, PU_STATIC);
|
||||
}
|
||||
|
||||
// read demo header
|
||||
if (memcmp(demo_p, DEMOHEADER, 12))
|
||||
{
|
||||
return DFILE_ERROR_NOTDEMO;
|
||||
}
|
||||
demo_p += 12; // DEMOHEADER
|
||||
|
||||
demo_p++; // version
|
||||
demo_p++; // subversion
|
||||
our_demo_version = READUINT16(demo_p);
|
||||
switch(our_demo_version)
|
||||
{
|
||||
case 0x000d:
|
||||
case 0x000e:
|
||||
case 0x000f:
|
||||
case DEMOVERSION: // latest always supported
|
||||
break;
|
||||
#ifdef OLD22DEMOCOMPAT
|
||||
case 0x000c:
|
||||
break;
|
||||
#endif
|
||||
// too old, cannot support.
|
||||
default:
|
||||
return DFILE_ERROR_NOTDEMO;
|
||||
}
|
||||
demo_p += 16; // demo checksum
|
||||
if (memcmp(demo_p, "PLAY", 4))
|
||||
{
|
||||
return DFILE_ERROR_NOTDEMO;
|
||||
}
|
||||
demo_p += 4; // "PLAY"
|
||||
demo_p += 2; // gamemap
|
||||
demo_p += 16; // mapmd5
|
||||
|
||||
demo_p++; // demoflags
|
||||
|
||||
return G_CheckDemoExtraFiles(&demo_p, true, our_demo_version);
|
||||
}
|
||||
|
||||
void G_AddGhost(char *defdemoname)
|
||||
{
|
||||
INT32 i;
|
||||
|
@ -2085,6 +2437,7 @@ void G_AddGhost(char *defdemoname)
|
|||
ghostversion = READUINT16(p);
|
||||
switch(ghostversion)
|
||||
{
|
||||
case 0x000f:
|
||||
case 0x000d:
|
||||
case 0x000e:
|
||||
case DEMOVERSION: // latest always supported
|
||||
|
@ -2130,6 +2483,9 @@ void G_AddGhost(char *defdemoname)
|
|||
Z_Free(buffer);
|
||||
return;
|
||||
}
|
||||
|
||||
G_SkipDemoExtraFiles(&p, ghostversion); // Don't wanna modify the file list for ghosts.
|
||||
|
||||
switch ((flags & DF_ATTACKMASK)>>DF_ATTACKSHIFT)
|
||||
{
|
||||
case ATTACKING_NONE: // 0
|
||||
|
@ -2161,17 +2517,12 @@ void G_AddGhost(char *defdemoname)
|
|||
// Ghosts do not have a player structure to put this in.
|
||||
p++; // charability
|
||||
p++; // charability2
|
||||
p++; // actionspd
|
||||
p++; // mindash
|
||||
p++; // maxdash
|
||||
p++; // normalspeed
|
||||
p++; // runspeed
|
||||
p += (ghostversion < 0x0010) ? 5 : 5 * sizeof(fixed_t); // actionspd, mindash, maxdash, normalspeed, and runspeed
|
||||
p++; // thrustfactor
|
||||
p++; // accelstart
|
||||
p++; // acceleration
|
||||
p += (ghostversion < 0x000e) ? 2 : 2 * sizeof(fixed_t); // height and spinheight
|
||||
p++; // camerascale
|
||||
p++; // shieldscale
|
||||
p += (ghostversion < 0x0010) ? 2 : 2 * sizeof(fixed_t); // camerascale and shieldscale
|
||||
p += 4; // jumpfactor
|
||||
p += 4; // followitem
|
||||
|
||||
|
@ -2347,6 +2698,7 @@ void G_DoPlayMetal(void)
|
|||
switch(metalversion)
|
||||
{
|
||||
case DEMOVERSION: // latest always supported
|
||||
case 0x000f:
|
||||
case 0x000e: // There are checks wheter the momentum is from older demo versions or not
|
||||
case 0x000d: // all that changed between then and now was longer color name
|
||||
case 0x000c:
|
||||
|
|
23
src/g_demo.h
23
src/g_demo.h
|
@ -26,9 +26,19 @@
|
|||
extern boolean demoplayback, titledemo, demorecording, timingdemo;
|
||||
extern tic_t demostarttime;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
DFILE_OVERRIDE_NONE = 0, // Show errors normally
|
||||
DFILE_OVERRIDE_LOAD, // Forcefully load demo, add files beforehand
|
||||
DFILE_OVERRIDE_SKIP, // Forcefully load demo, skip file list
|
||||
} demo_file_override_e;
|
||||
|
||||
extern demo_file_override_e demofileoverride;
|
||||
|
||||
// Quit after playing a demo from cmdline.
|
||||
extern boolean singledemo;
|
||||
extern boolean demo_start;
|
||||
extern boolean demo_forwardmove_rng;
|
||||
extern boolean demosynced;
|
||||
|
||||
extern mobj_t *metalplayback;
|
||||
|
@ -53,6 +63,18 @@ typedef enum
|
|||
GHC_RETURNSKIN // ditto
|
||||
} ghostcolor_t;
|
||||
|
||||
// G_CheckDemoExtraFiles: checks if our loaded WAD list matches the demo's.
|
||||
typedef enum
|
||||
{
|
||||
DFILE_ERROR_NONE = 0, // No file error
|
||||
DFILE_ERROR_NOTLOADED, // Files are not loaded, but can be without a restart.
|
||||
DFILE_ERROR_OUTOFORDER, // Files are loaded, but out of order.
|
||||
DFILE_ERROR_INCOMPLETEOUTOFORDER, // Some files are loaded out of order, but others are not.
|
||||
DFILE_ERROR_CANNOTLOAD, // Files are missing and cannot be loaded.
|
||||
DFILE_ERROR_EXTRAFILES, // Extra files outside of the replay's file list are loaded.
|
||||
DFILE_ERROR_NOTDEMO = UINT8_MAX, // This replay isn't even a replay...
|
||||
} demo_file_error_e;
|
||||
|
||||
// Record/playback tics
|
||||
void G_ReadDemoTiccmd(ticcmd_t *cmd, INT32 playernum);
|
||||
void G_WriteDemoTiccmd(ticcmd_t *cmd, INT32 playernum);
|
||||
|
@ -83,5 +105,6 @@ ATTRNORETURN void FUNCNORETURN G_StopMetalRecording(boolean kill);
|
|||
void G_StopDemo(void);
|
||||
boolean G_CheckDemoStatus(void);
|
||||
INT32 G_ConvertOldFrameFlags(INT32 frame);
|
||||
UINT8 G_CheckDemoForError(char *defdemoname);
|
||||
|
||||
#endif // __G_DEMO__
|
||||
|
|
829
src/g_game.c
829
src/g_game.c
File diff suppressed because it is too large
Load diff
29
src/g_game.h
29
src/g_game.h
|
@ -19,6 +19,7 @@
|
|||
#include "d_event.h"
|
||||
#include "g_demo.h"
|
||||
#include "m_cheat.h" // objectplacing
|
||||
#include "m_cond.h"
|
||||
|
||||
extern char gamedatafilename[64];
|
||||
extern char timeattackfolder[64];
|
||||
|
@ -48,6 +49,8 @@ extern boolean promptactive;
|
|||
|
||||
extern consvar_t cv_pauseifunfocused;
|
||||
|
||||
extern consvar_t cv_instantretry;
|
||||
|
||||
// used in game menu
|
||||
extern consvar_t cv_tutorialprompt;
|
||||
extern consvar_t cv_chatwidth, cv_chatnotifications, cv_chatheight, cv_chattime, cv_consolechat, cv_chatbacktint, cv_chatspamprotection, cv_compactscoreboard;
|
||||
|
@ -183,7 +186,7 @@ boolean G_IsTitleCardAvailable(void);
|
|||
// Can be called by the startup code or M_Responder, calls P_SetupLevel.
|
||||
void G_LoadGame(UINT32 slot, INT16 mapoverride);
|
||||
|
||||
void G_SaveGameData(void);
|
||||
void G_SaveGameData(gamedata_t *data);
|
||||
|
||||
void G_SaveGame(UINT32 slot, INT16 mapnum);
|
||||
|
||||
|
@ -239,27 +242,27 @@ void G_SetModeAttackRetryFlag(void);
|
|||
void G_ClearModeAttackRetryFlag(void);
|
||||
boolean G_GetModeAttackRetryFlag(void);
|
||||
|
||||
void G_LoadGameData(void);
|
||||
void G_LoadGameData(gamedata_t *data);
|
||||
void G_LoadGameSettings(void);
|
||||
|
||||
void G_SetGameModified(boolean silent);
|
||||
void G_SetUsedCheats(boolean silent);
|
||||
|
||||
void G_SetGamestate(gamestate_t newstate);
|
||||
|
||||
// Gamedata record shit
|
||||
void G_AllocMainRecordData(INT16 i);
|
||||
void G_AllocNightsRecordData(INT16 i);
|
||||
void G_ClearRecords(void);
|
||||
void G_AllocMainRecordData(INT16 i, gamedata_t *data);
|
||||
void G_AllocNightsRecordData(INT16 i, gamedata_t *data);
|
||||
void G_ClearRecords(gamedata_t *data);
|
||||
|
||||
UINT32 G_GetBestScore(INT16 map);
|
||||
tic_t G_GetBestTime(INT16 map);
|
||||
UINT16 G_GetBestRings(INT16 map);
|
||||
UINT32 G_GetBestNightsScore(INT16 map, UINT8 mare);
|
||||
tic_t G_GetBestNightsTime(INT16 map, UINT8 mare);
|
||||
UINT8 G_GetBestNightsGrade(INT16 map, UINT8 mare);
|
||||
UINT32 G_GetBestScore(INT16 map, gamedata_t *data);
|
||||
tic_t G_GetBestTime(INT16 map, gamedata_t *data);
|
||||
UINT16 G_GetBestRings(INT16 map, gamedata_t *data);
|
||||
UINT32 G_GetBestNightsScore(INT16 map, UINT8 mare, gamedata_t *data);
|
||||
tic_t G_GetBestNightsTime(INT16 map, UINT8 mare, gamedata_t *data);
|
||||
UINT8 G_GetBestNightsGrade(INT16 map, UINT8 mare, gamedata_t *data);
|
||||
|
||||
void G_AddTempNightsRecords(UINT32 pscore, tic_t ptime, UINT8 mare);
|
||||
void G_SetNightsRecords(void);
|
||||
void G_AddTempNightsRecords(player_t *player, UINT32 pscore, tic_t ptime, UINT8 mare);
|
||||
|
||||
FUNCMATH INT32 G_TicsToHours(tic_t tics);
|
||||
FUNCMATH INT32 G_TicsToMinutes(tic_t tics, boolean full);
|
||||
|
|
|
@ -1 +1,14 @@
|
|||
target_sourcefile(c)
|
||||
target_sources(SRB2SDL2 PRIVATE
|
||||
hw_bsp.c
|
||||
hw_draw.c
|
||||
hw_light.c
|
||||
hw_main.c
|
||||
hw_clip.c
|
||||
hw_md2.c
|
||||
hw_cache.c
|
||||
hw_md2load.c
|
||||
hw_md3load.c
|
||||
hw_model.c
|
||||
hw_batching.c
|
||||
r_opengl/r_opengl.c
|
||||
)
|
||||
|
|
|
@ -8,6 +8,5 @@ hw_cache.c
|
|||
hw_md2load.c
|
||||
hw_md3load.c
|
||||
hw_model.c
|
||||
u_list.c
|
||||
hw_batching.c
|
||||
r_opengl/r_opengl.c
|
||||
|
|
|
@ -42,10 +42,10 @@ int unsortedVertexArrayAllocSize = 65536;
|
|||
// Call HWR_RenderBatches to render all the collected geometry.
|
||||
void HWR_StartBatching(void)
|
||||
{
|
||||
if (currently_batching)
|
||||
I_Error("Repeat call to HWR_StartBatching without HWR_RenderBatches");
|
||||
if (currently_batching)
|
||||
I_Error("Repeat call to HWR_StartBatching without HWR_RenderBatches");
|
||||
|
||||
// init arrays if that has not been done yet
|
||||
// init arrays if that has not been done yet
|
||||
if (!finalVertexArray)
|
||||
{
|
||||
finalVertexArray = malloc(finalVertexArrayAllocSize * sizeof(FOutVector));
|
||||
|
@ -55,7 +55,7 @@ void HWR_StartBatching(void)
|
|||
unsortedVertexArray = malloc(unsortedVertexArrayAllocSize * sizeof(FOutVector));
|
||||
}
|
||||
|
||||
currently_batching = true;
|
||||
currently_batching = true;
|
||||
}
|
||||
|
||||
// This replaces the direct calls to pfnSetTexture in cases where batching is available.
|
||||
|
|
|
@ -93,33 +93,22 @@ typedef struct FVector
|
|||
//Hurdler: Transform (coords + angles)
|
||||
//BP: transform order : scale(rotation_x(rotation_y(translation(v))))
|
||||
|
||||
// Kart features
|
||||
//#define USE_FTRANSFORM_ANGLEZ
|
||||
//#define USE_FTRANSFORM_MIRROR
|
||||
|
||||
// Vanilla features
|
||||
#define USE_MODEL_NEXTFRAME
|
||||
|
||||
typedef struct
|
||||
{
|
||||
FLOAT x,y,z; // position
|
||||
#ifdef USE_FTRANSFORM_ANGLEZ
|
||||
FLOAT anglex,angley,anglez; // aimingangle / viewangle
|
||||
#else
|
||||
FLOAT anglex,angley; // aimingangle / viewangle
|
||||
#endif
|
||||
FLOAT scalex,scaley,scalez;
|
||||
FLOAT fovxangle, fovyangle;
|
||||
UINT8 splitscreen;
|
||||
boolean flip; // screenflip
|
||||
boolean roll;
|
||||
SINT8 rollflip;
|
||||
FLOAT rollangle; // done to not override USE_FTRANSFORM_ANGLEZ
|
||||
UINT8 rotaxis;
|
||||
FLOAT centerx, centery;
|
||||
#ifdef USE_FTRANSFORM_MIRROR
|
||||
FLOAT rollx, rollz;
|
||||
boolean mirror; // SRB2Kart: Encore Mode
|
||||
#endif
|
||||
boolean shearing; // 14042019
|
||||
float viewaiming; // 17052019
|
||||
} FTransform;
|
||||
|
@ -136,6 +125,7 @@ typedef struct
|
|||
// Predefined shader types
|
||||
enum
|
||||
{
|
||||
SHADER_NONE = -1,
|
||||
SHADER_DEFAULT = 0,
|
||||
|
||||
SHADER_FLOOR,
|
||||
|
@ -237,7 +227,8 @@ enum EPolyFlags
|
|||
PF_RemoveYWrap = 0x00010000, // Forces clamp texture on Y
|
||||
PF_ForceWrapX = 0x00020000, // Forces repeat texture on X
|
||||
PF_ForceWrapY = 0x00040000, // Forces repeat texture on Y
|
||||
PF_Ripple = 0x00100000 // Water ripple effect. The current backend doesn't use it for anything.
|
||||
PF_Ripple = 0x00100000, // Water ripple effect. The current backend doesn't use it for anything.
|
||||
PF_WireFrame = 0x00200000, // Draws vertices as lines instead of triangles
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -51,7 +51,7 @@ EXPORT void HWRAPI(ClearMipMapCache) (void);
|
|||
EXPORT void HWRAPI(SetSpecialState) (hwdspecialstate_t IdState, INT32 Value);
|
||||
|
||||
//Hurdler: added for new development
|
||||
EXPORT void HWRAPI(DrawModel) (model_t *model, INT32 frameIndex, float duration, float tics, INT32 nextFrameIndex, FTransform *pos, float scale, UINT8 flipped, UINT8 hflipped, FSurfaceInfo *Surface);
|
||||
EXPORT void HWRAPI(DrawModel) (model_t *model, INT32 frameIndex, float duration, float tics, INT32 nextFrameIndex, FTransform *pos, float hscale, float vscale, UINT8 flipped, UINT8 hflipped, FSurfaceInfo *Surface);
|
||||
EXPORT void HWRAPI(CreateModelVBOs) (model_t *model);
|
||||
EXPORT void HWRAPI(SetTransform) (FTransform *ptransform);
|
||||
EXPORT INT32 HWRAPI(GetTextureUsed) (void);
|
||||
|
@ -136,4 +136,3 @@ extern struct hwdriver_s hwdriver;
|
|||
#endif //not defined _CREATE_DLL_
|
||||
|
||||
#endif //__HWR_DRV_H__
|
||||
|
||||
|
|
|
@ -81,6 +81,7 @@ typedef struct gl_vissprite_s
|
|||
|
||||
boolean flip, vflip;
|
||||
boolean precip; // Tails 08-25-2002
|
||||
boolean bbox;
|
||||
boolean rotated;
|
||||
UINT8 translucency; //alpha level 0-255
|
||||
|
||||
|
@ -88,7 +89,7 @@ typedef struct gl_vissprite_s
|
|||
|
||||
//Hurdler: 25/04/2000: now support colormap in hardware mode
|
||||
UINT8 *colormap;
|
||||
INT32 dispoffset; // copy of info->dispoffset, affects ordering but not drawing
|
||||
INT32 dispoffset; // copy of mobj->dispoffset, affects ordering but not drawing
|
||||
|
||||
patch_t *gpatch;
|
||||
mobj_t *mobj; // NOTE: This is a precipmobj_t if precip is true !!! Watch out.
|
||||
|
|
|
@ -66,6 +66,7 @@ static void HWR_ProjectSprite(mobj_t *thing);
|
|||
#ifdef HWPRECIP
|
||||
static void HWR_ProjectPrecipitationSprite(precipmobj_t *thing);
|
||||
#endif
|
||||
static void HWR_ProjectBoundingBox(mobj_t *thing);
|
||||
|
||||
void HWR_AddTransparentFloor(levelflat_t *levelflat, extrasubsector_t *xsub, boolean isceiling, fixed_t fixedheight, INT32 lightlevel, INT32 alpha, sector_t *FOFSector, FBITFIELD blend, boolean fogplane, extracolormap_t *planecolormap);
|
||||
void HWR_AddTransparentPolyobjectFloor(levelflat_t *levelflat, polyobj_t *polysector, boolean isceiling, fixed_t fixedheight,
|
||||
|
@ -139,7 +140,7 @@ static fixed_t dup_viewx, dup_viewy, dup_viewz;
|
|||
static angle_t dup_viewangle;
|
||||
|
||||
static float gl_viewx, gl_viewy, gl_viewz;
|
||||
static float gl_viewsin, gl_viewcos;
|
||||
float gl_viewsin, gl_viewcos;
|
||||
|
||||
// Maybe not necessary with the new T&L code (needs to be checked!)
|
||||
static float gl_viewludsin, gl_viewludcos; // look up down kik test
|
||||
|
@ -459,30 +460,30 @@ static void HWR_RenderPlane(subsector_t *subsector, extrasubsector_t *xsub, bool
|
|||
{
|
||||
if (!isceiling) // it's a floor
|
||||
{
|
||||
scrollx = FIXED_TO_FLOAT(FOFsector->floor_xoffs)/fflatwidth;
|
||||
scrolly = FIXED_TO_FLOAT(FOFsector->floor_yoffs)/fflatheight;
|
||||
angle = FOFsector->floorpic_angle;
|
||||
scrollx = FIXED_TO_FLOAT(FOFsector->floorxoffset)/fflatwidth;
|
||||
scrolly = FIXED_TO_FLOAT(FOFsector->flooryoffset)/fflatheight;
|
||||
angle = FOFsector->floorangle;
|
||||
}
|
||||
else // it's a ceiling
|
||||
{
|
||||
scrollx = FIXED_TO_FLOAT(FOFsector->ceiling_xoffs)/fflatwidth;
|
||||
scrolly = FIXED_TO_FLOAT(FOFsector->ceiling_yoffs)/fflatheight;
|
||||
angle = FOFsector->ceilingpic_angle;
|
||||
scrollx = FIXED_TO_FLOAT(FOFsector->ceilingxoffset)/fflatwidth;
|
||||
scrolly = FIXED_TO_FLOAT(FOFsector->ceilingyoffset)/fflatheight;
|
||||
angle = FOFsector->ceilingangle;
|
||||
}
|
||||
}
|
||||
else if (gl_frontsector)
|
||||
{
|
||||
if (!isceiling) // it's a floor
|
||||
{
|
||||
scrollx = FIXED_TO_FLOAT(gl_frontsector->floor_xoffs)/fflatwidth;
|
||||
scrolly = FIXED_TO_FLOAT(gl_frontsector->floor_yoffs)/fflatheight;
|
||||
angle = gl_frontsector->floorpic_angle;
|
||||
scrollx = FIXED_TO_FLOAT(gl_frontsector->floorxoffset)/fflatwidth;
|
||||
scrolly = FIXED_TO_FLOAT(gl_frontsector->flooryoffset)/fflatheight;
|
||||
angle = gl_frontsector->floorangle;
|
||||
}
|
||||
else // it's a ceiling
|
||||
{
|
||||
scrollx = FIXED_TO_FLOAT(gl_frontsector->ceiling_xoffs)/fflatwidth;
|
||||
scrolly = FIXED_TO_FLOAT(gl_frontsector->ceiling_yoffs)/fflatheight;
|
||||
angle = gl_frontsector->ceilingpic_angle;
|
||||
scrollx = FIXED_TO_FLOAT(gl_frontsector->ceilingxoffset)/fflatwidth;
|
||||
scrolly = FIXED_TO_FLOAT(gl_frontsector->ceilingyoffset)/fflatheight;
|
||||
angle = gl_frontsector->ceilingangle;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1153,7 +1154,7 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
|
|||
else
|
||||
texturevpeg = gl_backsector->ceilingheight + textureheight[gl_toptexture] - gl_frontsector->ceilingheight;
|
||||
|
||||
texturevpeg += gl_sidedef->rowoffset;
|
||||
texturevpeg += gl_sidedef->rowoffset + gl_sidedef->offsety_top;
|
||||
|
||||
// This is so that it doesn't overflow and screw up the wall, it doesn't need to go higher than the texture's height anyway
|
||||
texturevpeg %= textureheight[gl_toptexture];
|
||||
|
@ -1162,8 +1163,8 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
|
|||
|
||||
wallVerts[3].t = wallVerts[2].t = texturevpeg * grTex->scaleY;
|
||||
wallVerts[0].t = wallVerts[1].t = (texturevpeg + gl_frontsector->ceilingheight - gl_backsector->ceilingheight) * grTex->scaleY;
|
||||
wallVerts[0].s = wallVerts[3].s = cliplow * grTex->scaleX;
|
||||
wallVerts[2].s = wallVerts[1].s = cliphigh * grTex->scaleX;
|
||||
wallVerts[0].s = wallVerts[3].s = (cliplow + gl_sidedef->offsetx_top) * grTex->scaleX;
|
||||
wallVerts[2].s = wallVerts[1].s = (cliphigh + gl_sidedef->offsetx_top) * grTex->scaleX;
|
||||
|
||||
// Adjust t value for sloped walls
|
||||
if (!(gl_linedef->flags & ML_SKEWTD))
|
||||
|
@ -1213,7 +1214,7 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
|
|||
else
|
||||
texturevpeg = gl_frontsector->floorheight - gl_backsector->floorheight;
|
||||
|
||||
texturevpeg += gl_sidedef->rowoffset;
|
||||
texturevpeg += gl_sidedef->rowoffset + gl_sidedef->offsety_bot;
|
||||
|
||||
// This is so that it doesn't overflow and screw up the wall, it doesn't need to go higher than the texture's height anyway
|
||||
texturevpeg %= textureheight[gl_bottomtexture];
|
||||
|
@ -1222,8 +1223,8 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
|
|||
|
||||
wallVerts[3].t = wallVerts[2].t = texturevpeg * grTex->scaleY;
|
||||
wallVerts[0].t = wallVerts[1].t = (texturevpeg + gl_backsector->floorheight - gl_frontsector->floorheight) * grTex->scaleY;
|
||||
wallVerts[0].s = wallVerts[3].s = cliplow * grTex->scaleX;
|
||||
wallVerts[2].s = wallVerts[1].s = cliphigh * grTex->scaleX;
|
||||
wallVerts[0].s = wallVerts[3].s = (cliplow + gl_sidedef->offsetx_bot) * grTex->scaleX;
|
||||
wallVerts[2].s = wallVerts[1].s = (cliphigh + gl_sidedef->offsetx_bot) * grTex->scaleX;
|
||||
|
||||
// Adjust t value for sloped walls
|
||||
if (!(gl_linedef->flags & ML_SKEWTD))
|
||||
|
@ -1333,13 +1334,13 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
|
|||
// Peg it to the floor
|
||||
if (gl_linedef->flags & ML_MIDPEG)
|
||||
{
|
||||
polybottom = max(front->floorheight, back->floorheight) + gl_sidedef->rowoffset;
|
||||
polybottom = max(front->floorheight, back->floorheight) + gl_sidedef->rowoffset + gl_sidedef->offsety_mid;
|
||||
polytop = polybottom + midtexheight;
|
||||
}
|
||||
// Peg it to the ceiling
|
||||
else
|
||||
{
|
||||
polytop = min(front->ceilingheight, back->ceilingheight) + gl_sidedef->rowoffset;
|
||||
polytop = min(front->ceilingheight, back->ceilingheight) + gl_sidedef->rowoffset + gl_sidedef->offsety_mid;
|
||||
polybottom = polytop - midtexheight;
|
||||
}
|
||||
|
||||
|
@ -1350,9 +1351,9 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
|
|||
// Skew the texture, but peg it to the floor
|
||||
else if (gl_linedef->flags & ML_MIDPEG)
|
||||
{
|
||||
polybottom = popenbottom + gl_sidedef->rowoffset;
|
||||
polybottom = popenbottom + gl_sidedef->rowoffset + gl_sidedef->offsety_mid;
|
||||
polytop = polybottom + midtexheight;
|
||||
polybottomslope = popenbottomslope + gl_sidedef->rowoffset;
|
||||
polybottomslope = popenbottomslope + gl_sidedef->rowoffset + gl_sidedef->offsety_mid;
|
||||
polytopslope = polybottomslope + midtexheight;
|
||||
}
|
||||
// Skew it according to the ceiling's slope
|
||||
|
@ -1407,12 +1408,12 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
|
|||
// Left side
|
||||
wallVerts[3].t = texturevpeg * grTex->scaleY;
|
||||
wallVerts[0].t = (h - l + texturevpeg) * grTex->scaleY;
|
||||
wallVerts[0].s = wallVerts[3].s = cliplow * grTex->scaleX;
|
||||
wallVerts[0].s = wallVerts[3].s = (cliplow + gl_sidedef->offsetx_mid) * grTex->scaleX;
|
||||
|
||||
// Right side
|
||||
wallVerts[2].t = texturevpegslope * grTex->scaleY;
|
||||
wallVerts[1].t = (hS - lS + texturevpegslope) * grTex->scaleY;
|
||||
wallVerts[2].s = wallVerts[1].s = cliphigh * grTex->scaleX;
|
||||
wallVerts[2].s = wallVerts[1].s = (cliphigh + gl_sidedef->offsetx_mid) * grTex->scaleX;
|
||||
|
||||
// set top/bottom coords
|
||||
// Take the texture peg into account, rather than changing the offsets past
|
||||
|
@ -1474,19 +1475,19 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
|
|||
|
||||
// PEGGING
|
||||
if ((gl_linedef->flags & (ML_DONTPEGBOTTOM|ML_NOSKEW)) == (ML_DONTPEGBOTTOM|ML_NOSKEW))
|
||||
texturevpeg = gl_frontsector->floorheight + textureheight[gl_sidedef->midtexture] - gl_frontsector->ceilingheight + gl_sidedef->rowoffset;
|
||||
texturevpeg = gl_frontsector->floorheight + textureheight[gl_sidedef->midtexture] - gl_frontsector->ceilingheight + gl_sidedef->rowoffset + gl_sidedef->offsety_mid;
|
||||
else if (gl_linedef->flags & ML_DONTPEGBOTTOM)
|
||||
texturevpeg = worldbottom + textureheight[gl_sidedef->midtexture] - worldtop + gl_sidedef->rowoffset;
|
||||
texturevpeg = worldbottom + textureheight[gl_sidedef->midtexture] - worldtop + gl_sidedef->rowoffset + gl_sidedef->offsety_mid;
|
||||
else
|
||||
// top of texture at top
|
||||
texturevpeg = gl_sidedef->rowoffset;
|
||||
texturevpeg = gl_sidedef->rowoffset + gl_sidedef->offsety_mid;
|
||||
|
||||
grTex = HWR_GetTexture(gl_midtexture);
|
||||
|
||||
wallVerts[3].t = wallVerts[2].t = texturevpeg * grTex->scaleY;
|
||||
wallVerts[0].t = wallVerts[1].t = (texturevpeg + gl_frontsector->ceilingheight - gl_frontsector->floorheight) * grTex->scaleY;
|
||||
wallVerts[0].s = wallVerts[3].s = cliplow * grTex->scaleX;
|
||||
wallVerts[2].s = wallVerts[1].s = cliphigh * grTex->scaleX;
|
||||
wallVerts[0].s = wallVerts[3].s = (cliplow + gl_sidedef->offsetx_mid) * grTex->scaleX;
|
||||
wallVerts[2].s = wallVerts[1].s = (cliphigh + gl_sidedef->offsetx_mid) * grTex->scaleX;
|
||||
|
||||
// Texture correction for slopes
|
||||
if (gl_linedef->flags & ML_NOSKEW) {
|
||||
|
@ -1634,13 +1635,13 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
|
|||
// -- Monster Iestyn 26/06/18
|
||||
if (newline)
|
||||
{
|
||||
texturevpeg = sides[newline->sidenum[0]].rowoffset;
|
||||
texturevpeg = sides[newline->sidenum[0]].rowoffset + sides[newline->sidenum[0]].offsety_mid;
|
||||
attachtobottom = !!(newline->flags & ML_DONTPEGBOTTOM);
|
||||
slopeskew = !!(newline->flags & ML_SKEWTD);
|
||||
}
|
||||
else
|
||||
{
|
||||
texturevpeg = sides[rover->master->sidenum[0]].rowoffset;
|
||||
texturevpeg = sides[rover->master->sidenum[0]].rowoffset + sides[rover->master->sidenum[0]].offsety_mid;
|
||||
attachtobottom = !!(gl_linedef->flags & ML_DONTPEGBOTTOM);
|
||||
slopeskew = !!(rover->master->flags & ML_SKEWTD);
|
||||
}
|
||||
|
@ -1672,8 +1673,8 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
|
|||
}
|
||||
}
|
||||
|
||||
wallVerts[0].s = wallVerts[3].s = cliplow * grTex->scaleX;
|
||||
wallVerts[2].s = wallVerts[1].s = cliphigh * grTex->scaleX;
|
||||
wallVerts[0].s = wallVerts[3].s = (cliplow + gl_sidedef->offsetx_mid) * grTex->scaleX;
|
||||
wallVerts[2].s = wallVerts[1].s = (cliphigh + gl_sidedef->offsetx_mid) * grTex->scaleX;
|
||||
}
|
||||
if (rover->fofflags & FOF_FOG)
|
||||
{
|
||||
|
@ -1698,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)
|
||||
{
|
||||
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)
|
||||
|
@ -1785,17 +1786,17 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
|
|||
|
||||
if (newline)
|
||||
{
|
||||
wallVerts[3].t = wallVerts[2].t = (*rover->topheight - h + sides[newline->sidenum[0]].rowoffset) * grTex->scaleY;
|
||||
wallVerts[0].t = wallVerts[1].t = (h - l + (*rover->topheight - h + sides[newline->sidenum[0]].rowoffset)) * grTex->scaleY;
|
||||
wallVerts[3].t = wallVerts[2].t = (*rover->topheight - h + sides[newline->sidenum[0]].rowoffset + sides[newline->sidenum[0]].offsety_mid) * grTex->scaleY;
|
||||
wallVerts[0].t = wallVerts[1].t = (h - l + (*rover->topheight - h + sides[newline->sidenum[0]].rowoffset) + sides[newline->sidenum[0]].offsety_mid) * grTex->scaleY;
|
||||
}
|
||||
else
|
||||
{
|
||||
wallVerts[3].t = wallVerts[2].t = (*rover->topheight - h + sides[rover->master->sidenum[0]].rowoffset) * grTex->scaleY;
|
||||
wallVerts[0].t = wallVerts[1].t = (h - l + (*rover->topheight - h + sides[rover->master->sidenum[0]].rowoffset)) * grTex->scaleY;
|
||||
wallVerts[3].t = wallVerts[2].t = (*rover->topheight - h + sides[rover->master->sidenum[0]].rowoffset + sides[rover->master->sidenum[0]].offsety_mid) * grTex->scaleY;
|
||||
wallVerts[0].t = wallVerts[1].t = (h - l + (*rover->topheight - h + sides[rover->master->sidenum[0]].rowoffset + sides[rover->master->sidenum[0]].offsety_mid)) * grTex->scaleY;
|
||||
}
|
||||
|
||||
wallVerts[0].s = wallVerts[3].s = cliplow * grTex->scaleX;
|
||||
wallVerts[2].s = wallVerts[1].s = cliphigh * grTex->scaleX;
|
||||
wallVerts[0].s = wallVerts[3].s = (cliplow + gl_sidedef->offsetx_mid) * grTex->scaleX;
|
||||
wallVerts[2].s = wallVerts[1].s = (cliphigh + gl_sidedef->offsetx_mid) * grTex->scaleX;
|
||||
}
|
||||
|
||||
if (rover->fofflags & FOF_FOG)
|
||||
|
@ -1821,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)
|
||||
{
|
||||
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)
|
||||
|
@ -2719,30 +2720,30 @@ static void HWR_RenderPolyObjectPlane(polyobj_t *polysector, boolean isceiling,
|
|||
{
|
||||
if (!isceiling) // it's a floor
|
||||
{
|
||||
scrollx = FIXED_TO_FLOAT(FOFsector->floor_xoffs)/fflatwidth;
|
||||
scrolly = FIXED_TO_FLOAT(FOFsector->floor_yoffs)/fflatheight;
|
||||
angle = FOFsector->floorpic_angle;
|
||||
scrollx = FIXED_TO_FLOAT(FOFsector->floorxoffset)/fflatwidth;
|
||||
scrolly = FIXED_TO_FLOAT(FOFsector->flooryoffset)/fflatheight;
|
||||
angle = FOFsector->floorangle;
|
||||
}
|
||||
else // it's a ceiling
|
||||
{
|
||||
scrollx = FIXED_TO_FLOAT(FOFsector->ceiling_xoffs)/fflatwidth;
|
||||
scrolly = FIXED_TO_FLOAT(FOFsector->ceiling_yoffs)/fflatheight;
|
||||
angle = FOFsector->ceilingpic_angle;
|
||||
scrollx = FIXED_TO_FLOAT(FOFsector->ceilingxoffset)/fflatwidth;
|
||||
scrolly = FIXED_TO_FLOAT(FOFsector->ceilingyoffset)/fflatheight;
|
||||
angle = FOFsector->ceilingangle;
|
||||
}
|
||||
}
|
||||
else if (gl_frontsector)
|
||||
{
|
||||
if (!isceiling) // it's a floor
|
||||
{
|
||||
scrollx = FIXED_TO_FLOAT(gl_frontsector->floor_xoffs)/fflatwidth;
|
||||
scrolly = FIXED_TO_FLOAT(gl_frontsector->floor_yoffs)/fflatheight;
|
||||
angle = gl_frontsector->floorpic_angle;
|
||||
scrollx = FIXED_TO_FLOAT(gl_frontsector->floorxoffset)/fflatwidth;
|
||||
scrolly = FIXED_TO_FLOAT(gl_frontsector->flooryoffset)/fflatheight;
|
||||
angle = gl_frontsector->floorangle;
|
||||
}
|
||||
else // it's a ceiling
|
||||
{
|
||||
scrollx = FIXED_TO_FLOAT(gl_frontsector->ceiling_xoffs)/fflatwidth;
|
||||
scrolly = FIXED_TO_FLOAT(gl_frontsector->ceiling_yoffs)/fflatheight;
|
||||
angle = gl_frontsector->ceilingpic_angle;
|
||||
scrollx = FIXED_TO_FLOAT(gl_frontsector->ceilingxoffset)/fflatwidth;
|
||||
scrolly = FIXED_TO_FLOAT(gl_frontsector->ceilingyoffset)/fflatheight;
|
||||
angle = gl_frontsector->ceilingangle;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3094,7 +3095,7 @@ static void HWR_Subsector(size_t num)
|
|||
false,
|
||||
*rover->bottomheight,
|
||||
*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),
|
||||
false, *gl_frontsector->lightlist[light].extra_colormap);
|
||||
}
|
||||
|
@ -3140,7 +3141,7 @@ static void HWR_Subsector(size_t num)
|
|||
true,
|
||||
*rover->topheight,
|
||||
*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),
|
||||
false, *gl_frontsector->lightlist[light].extra_colormap);
|
||||
}
|
||||
|
@ -3594,7 +3595,7 @@ static void HWR_DrawDropShadow(mobj_t *thing, fixed_t scale)
|
|||
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;
|
||||
if (alpha >= 255) return;
|
||||
|
@ -3605,7 +3606,7 @@ static void HWR_DrawDropShadow(mobj_t *thing, fixed_t scale)
|
|||
HWR_GetPatch(gpatch);
|
||||
|
||||
scalemul = FixedMul(FRACUNIT - floordiff/640, scale);
|
||||
scalemul = FixedMul(scalemul, (thing->radius*2) / gpatch->height);
|
||||
scalemul = FixedMul(scalemul, (interp.radius*2) / gpatch->height);
|
||||
|
||||
fscale = FIXED_TO_FLOAT(scalemul);
|
||||
fx = FIXED_TO_FLOAT(interp.x);
|
||||
|
@ -3717,7 +3718,7 @@ static void HWR_RotateSpritePolyToAim(gl_vissprite_t *spr, FOutVector *wallVerts
|
|||
|
||||
if (P_MobjFlip(spr->mobj) == -1)
|
||||
{
|
||||
basey = FIXED_TO_FLOAT(interp.z + spr->mobj->height);
|
||||
basey = FIXED_TO_FLOAT(interp.z + interp.height);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -4036,6 +4037,54 @@ static void HWR_SplitSprite(gl_vissprite_t *spr)
|
|||
HWR_LinkDrawHackAdd(wallVerts, spr);
|
||||
}
|
||||
|
||||
static void HWR_DrawBoundingBox(gl_vissprite_t *vis)
|
||||
{
|
||||
FOutVector v[24];
|
||||
FSurfaceInfo Surf = {0};
|
||||
|
||||
//
|
||||
// create a cube (side view)
|
||||
//
|
||||
// 5--4 3
|
||||
// |
|
||||
// |
|
||||
// 0--1 2
|
||||
//
|
||||
// repeat this 4 times (overhead)
|
||||
//
|
||||
//
|
||||
// 15 16 17 09
|
||||
// 14 13 12 08
|
||||
// 23 18 *--* 07 10
|
||||
// | |
|
||||
// 22 19 *--* 06 11
|
||||
// 20 00 01 02
|
||||
// 21 05 04 03
|
||||
//
|
||||
|
||||
v[ 0].x = v[ 5].x = v[13].x = v[14].x = v[15].x = v[16].x =
|
||||
v[18].x = v[19].x = v[20].x = v[21].x = v[22].x = v[23].x = vis->x1; // west
|
||||
|
||||
v[ 1].x = v[ 2].x = v[ 3].x = v[ 4].x = v[ 6].x = v[ 7].x =
|
||||
v[ 8].x = v[ 9].x = v[10].x = v[11].x = v[12].x = v[17].x = vis->x2; // east
|
||||
|
||||
v[ 0].z = v[ 1].z = v[ 2].z = v[ 3].z = v[ 4].z = v[ 5].z =
|
||||
v[ 6].z = v[11].z = v[19].z = v[20].z = v[21].z = v[22].z = vis->z1; // south
|
||||
|
||||
v[ 7].z = v[ 8].z = v[ 9].z = v[10].z = v[12].z = v[13].z =
|
||||
v[14].z = v[15].z = v[16].z = v[17].z = v[18].z = v[23].z = vis->z2; // north
|
||||
|
||||
v[ 0].y = v[ 1].y = v[ 2].y = v[ 6].y = v[ 7].y = v[ 8].y =
|
||||
v[12].y = v[13].y = v[14].y = v[18].y = v[19].y = v[20].y = vis->gz; // bottom
|
||||
|
||||
v[ 3].y = v[ 4].y = v[ 5].y = v[ 9].y = v[10].y = v[11].y =
|
||||
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));
|
||||
|
||||
HWR_ProcessPolygon(&Surf, v, 24, (cv_renderhitboxgldepth.value ? 0 : PF_NoDepthTest)|PF_Modulated|PF_NoTexture|PF_WireFrame, SHADER_NONE, false);
|
||||
}
|
||||
|
||||
// -----------------+
|
||||
// HWR_DrawSprite : Draw flat sprites
|
||||
// : (monsters, bonuses, weapons, lights, ...)
|
||||
|
@ -4092,14 +4141,11 @@ static void HWR_DrawSprite(gl_vissprite_t *spr)
|
|||
float xscale, yscale;
|
||||
float xoffset, yoffset;
|
||||
float leftoffset, topoffset;
|
||||
float scale = spr->scale;
|
||||
float zoffset = (P_MobjFlip(spr->mobj) * 0.05f);
|
||||
pslope_t *splatslope = NULL;
|
||||
INT32 i;
|
||||
|
||||
renderflags_t renderflags = spr->renderflags;
|
||||
if (renderflags & RF_SHADOWEFFECTS)
|
||||
scale *= spr->shadowscale;
|
||||
|
||||
if (spr->rotateflags & SRF_3D || renderflags & RF_NOSPLATBILLBOARD)
|
||||
angle = spr->mobj->angle;
|
||||
|
@ -4107,7 +4153,7 @@ static void HWR_DrawSprite(gl_vissprite_t *spr)
|
|||
angle = viewangle;
|
||||
|
||||
if (!spr->rotated)
|
||||
angle += spr->mobj->rollangle;
|
||||
angle += spr->mobj->spriteroll;
|
||||
|
||||
angle = -angle;
|
||||
angle += ANGLE_90;
|
||||
|
@ -4480,9 +4526,16 @@ static int CompareVisSprites(const void *p1, const void *p2)
|
|||
int transparency1;
|
||||
int transparency2;
|
||||
|
||||
int linkdraw1;
|
||||
int linkdraw2;
|
||||
|
||||
// draw bbox after everything else
|
||||
if (spr1->bbox || spr2->bbox)
|
||||
return (spr1->bbox - spr2->bbox);
|
||||
|
||||
// check for precip first, because then sprX->mobj is actually a precipmobj_t and does not have flags2 or tracer
|
||||
int linkdraw1 = !spr1->precip && (spr1->mobj->flags2 & MF2_LINKDRAW) && spr1->mobj->tracer;
|
||||
int linkdraw2 = !spr2->precip && (spr2->mobj->flags2 & MF2_LINKDRAW) && spr2->mobj->tracer;
|
||||
linkdraw1 = !spr1->precip && (spr1->mobj->flags2 & MF2_LINKDRAW) && spr1->mobj->tracer;
|
||||
linkdraw2 = !spr2->precip && (spr2->mobj->flags2 & MF2_LINKDRAW) && spr2->mobj->tracer;
|
||||
|
||||
// ^ is the XOR operation
|
||||
// if comparing a linkdraw and non-linkdraw sprite or 2 linkdraw sprites with different tracers, then use
|
||||
|
@ -4852,6 +4905,9 @@ static void HWR_DrawSprites(void)
|
|||
for (i = 0; i < gl_visspritecount; i++)
|
||||
{
|
||||
gl_vissprite_t *spr = gl_vsprorder[i];
|
||||
if (spr->bbox)
|
||||
HWR_DrawBoundingBox(spr);
|
||||
else
|
||||
#ifdef HWPRECIP
|
||||
if (spr->precip)
|
||||
HWR_DrawPrecipitationSprite(spr);
|
||||
|
@ -4951,8 +5007,15 @@ static void HWR_AddSprites(sector_t *sec)
|
|||
hoop_limit_dist = (fixed_t)(cv_drawdist_nights.value) << FRACBITS;
|
||||
for (thing = sec->thinglist; thing; thing = thing->snext)
|
||||
{
|
||||
if (R_ThingVisibleWithinDist(thing, limit_dist, hoop_limit_dist))
|
||||
HWR_ProjectSprite(thing);
|
||||
if (R_ThingWithinDist(thing, limit_dist, hoop_limit_dist))
|
||||
{
|
||||
if (R_ThingVisible(thing))
|
||||
{
|
||||
HWR_ProjectSprite(thing);
|
||||
}
|
||||
|
||||
HWR_ProjectBoundingBox(thing);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef HWPRECIP
|
||||
|
@ -5010,6 +5073,7 @@ static void HWR_ProjectSprite(mobj_t *thing)
|
|||
#ifdef ROTSPRITE
|
||||
patch_t *rotsprite = NULL;
|
||||
INT32 rollangle = 0;
|
||||
angle_t spriterotangle = 0;
|
||||
#endif
|
||||
|
||||
// uncapped/interpolation
|
||||
|
@ -5031,7 +5095,7 @@ static void HWR_ProjectSprite(mobj_t *thing)
|
|||
return;
|
||||
}
|
||||
|
||||
dispoffset = thing->info->dispoffset;
|
||||
dispoffset = thing->dispoffset;
|
||||
|
||||
|
||||
if (R_UsingFrameInterpolation() && !paused)
|
||||
|
@ -5177,18 +5241,21 @@ static void HWR_ProjectSprite(mobj_t *thing)
|
|||
spr_topoffset = spritecachedinfo[lumpoff].topoffset;
|
||||
|
||||
#ifdef ROTSPRITE
|
||||
if (thing->rollangle
|
||||
spriterotangle = R_SpriteRotationAngle(&interp);
|
||||
|
||||
if (spriterotangle != 0
|
||||
&& !(splat && !(thing->renderflags & RF_NOSPLATROLLANGLE)))
|
||||
{
|
||||
if (papersprite)
|
||||
{
|
||||
// a positive rollangle should should pitch papersprites upwards relative to their facing angle
|
||||
rollangle = R_GetRollAngle(InvAngle(thing->rollangle));
|
||||
rollangle = R_GetRollAngle(InvAngle(spriterotangle));
|
||||
}
|
||||
else
|
||||
{
|
||||
rollangle = R_GetRollAngle(thing->rollangle);
|
||||
rollangle = R_GetRollAngle(spriterotangle);
|
||||
}
|
||||
|
||||
rotsprite = Patch_GetRotatedSprite(sprframe, (thing->frame & FF_FRAMEMASK), rot, flip, false, sprinfo, rollangle);
|
||||
|
||||
if (rotsprite != NULL)
|
||||
|
@ -5254,7 +5321,7 @@ static void HWR_ProjectSprite(mobj_t *thing)
|
|||
}
|
||||
|
||||
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);
|
||||
shadowscale = FIXED_TO_FLOAT(FixedMul(FRACUNIT - floordiff/640, casterinterp.scale));
|
||||
|
@ -5306,7 +5373,7 @@ static void HWR_ProjectSprite(mobj_t *thing)
|
|||
|
||||
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);
|
||||
}
|
||||
else
|
||||
|
@ -5470,6 +5537,7 @@ static void HWR_ProjectSprite(mobj_t *thing)
|
|||
vis->vflip = vflip;
|
||||
|
||||
vis->precip = false;
|
||||
vis->bbox = false;
|
||||
|
||||
vis->angle = interp.angle;
|
||||
}
|
||||
|
@ -5592,6 +5660,7 @@ static void HWR_ProjectPrecipitationSprite(precipmobj_t *thing)
|
|||
vis->gz = vis->gzt - FIXED_TO_FLOAT(spritecachedinfo[lumpoff].height);
|
||||
|
||||
vis->precip = true;
|
||||
vis->bbox = false;
|
||||
|
||||
// okay... this is a hack, but weather isn't networked, so it should be ok
|
||||
if (!(thing->precipflags & PCF_THUNK))
|
||||
|
@ -5605,6 +5674,58 @@ static void HWR_ProjectPrecipitationSprite(precipmobj_t *thing)
|
|||
}
|
||||
#endif
|
||||
|
||||
static void HWR_ProjectBoundingBox(mobj_t *thing)
|
||||
{
|
||||
gl_vissprite_t *vis;
|
||||
float tr_x, tr_y;
|
||||
float tz;
|
||||
|
||||
if (!thing)
|
||||
return;
|
||||
|
||||
if (!R_ThingBoundingBoxVisible(thing))
|
||||
return;
|
||||
|
||||
// uncapped/interpolation
|
||||
boolean interpolate = cv_renderhitboxinterpolation.value;
|
||||
interpmobjstate_t interp = {0};
|
||||
|
||||
if (R_UsingFrameInterpolation() && !paused && interpolate)
|
||||
{
|
||||
R_InterpolateMobjState(thing, rendertimefrac, &interp);
|
||||
}
|
||||
else
|
||||
{
|
||||
R_InterpolateMobjState(thing, FRACUNIT, &interp);
|
||||
}
|
||||
|
||||
// transform the origin point
|
||||
tr_x = FIXED_TO_FLOAT(interp.x) - gl_viewx;
|
||||
tr_y = FIXED_TO_FLOAT(interp.y) - gl_viewy;
|
||||
|
||||
// rotation around vertical axis
|
||||
tz = (tr_x * gl_viewcos) + (tr_y * gl_viewsin);
|
||||
|
||||
// thing is behind view plane?
|
||||
if (tz < ZCLIP_PLANE)
|
||||
return;
|
||||
|
||||
tr_x += gl_viewx;
|
||||
tr_y += gl_viewy;
|
||||
|
||||
vis = HWR_NewVisSprite();
|
||||
vis->x1 = tr_x - FIXED_TO_FLOAT(interp.radius);
|
||||
vis->x2 = tr_x + FIXED_TO_FLOAT(interp.radius);
|
||||
vis->z1 = tr_y - FIXED_TO_FLOAT(interp.radius);
|
||||
vis->z2 = tr_y + FIXED_TO_FLOAT(interp.radius);
|
||||
vis->gz = FIXED_TO_FLOAT(interp.z);
|
||||
vis->gzt = vis->gz + FIXED_TO_FLOAT(interp.height);
|
||||
vis->mobj = thing;
|
||||
|
||||
vis->precip = false;
|
||||
vis->bbox = true;
|
||||
}
|
||||
|
||||
// ==========================================================================
|
||||
// Sky dome rendering, ported from PrBoom+
|
||||
// ==========================================================================
|
||||
|
@ -5788,6 +5909,8 @@ static void HWR_DrawSkyBackground(player_t *player)
|
|||
fixed_t rol = AngleFixed(player->viewrollangle);
|
||||
dometransform.rollangle = FIXED_TO_FLOAT(rol);
|
||||
dometransform.roll = true;
|
||||
dometransform.rollx = 1.0f;
|
||||
dometransform.rollz = 0.0f;
|
||||
}
|
||||
dometransform.splitscreen = splitscreen;
|
||||
|
||||
|
@ -6066,6 +6189,8 @@ void HWR_RenderSkyboxView(INT32 viewnumber, player_t *player)
|
|||
fixed_t rol = AngleFixed(player->viewrollangle);
|
||||
atransform.rollangle = FIXED_TO_FLOAT(rol);
|
||||
atransform.roll = true;
|
||||
atransform.rollx = 1.0f;
|
||||
atransform.rollz = 0.0f;
|
||||
}
|
||||
atransform.splitscreen = splitscreen;
|
||||
|
||||
|
@ -6280,6 +6405,8 @@ void HWR_RenderPlayerView(INT32 viewnumber, player_t *player)
|
|||
fixed_t rol = AngleFixed(player->viewrollangle);
|
||||
atransform.rollangle = FIXED_TO_FLOAT(rol);
|
||||
atransform.roll = true;
|
||||
atransform.rollx = 1.0f;
|
||||
atransform.rollz = 0.0f;
|
||||
}
|
||||
atransform.splitscreen = splitscreen;
|
||||
|
||||
|
|
|
@ -115,6 +115,7 @@ extern float gl_viewwindowx, gl_basewindowcentery;
|
|||
// BP: big hack for a test in lighting ref : 1249753487AB
|
||||
extern fixed_t *hwbbox;
|
||||
extern FTransform atransform;
|
||||
extern float gl_viewsin, gl_viewcos;
|
||||
|
||||
|
||||
// Render stats
|
||||
|
|
|
@ -486,7 +486,7 @@ void HWR_InitModels(void)
|
|||
size_t i;
|
||||
INT32 s;
|
||||
FILE *f;
|
||||
char name[24], filename[32];
|
||||
char name[26], filename[32];
|
||||
float scale, offset;
|
||||
size_t prefixlen;
|
||||
|
||||
|
@ -585,7 +585,7 @@ modelfound:
|
|||
void HWR_AddPlayerModel(int skin) // For skins that were added after startup
|
||||
{
|
||||
FILE *f;
|
||||
char name[24], filename[32];
|
||||
char name[26], filename[32];
|
||||
float scale, offset;
|
||||
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
|
||||
// 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
|
||||
char name[24], filename[32];
|
||||
char name[26], filename[32];
|
||||
float scale, offset;
|
||||
|
||||
if (nomd2s)
|
||||
|
@ -1146,7 +1146,7 @@ static void HWR_GetBlendedTexture(patch_t *patch, patch_t *blendpatch, INT32 ski
|
|||
static boolean HWR_AllowModel(mobj_t *mobj)
|
||||
{
|
||||
// Signpost overlay. Not needed.
|
||||
if (mobj->state-states == S_PLAY_SIGN)
|
||||
if (mobj->sprite2 == SPR2_SIGN || mobj->state-states == S_PLAY_SIGN)
|
||||
return false;
|
||||
|
||||
// Otherwise, render the model.
|
||||
|
@ -1346,10 +1346,7 @@ boolean HWR_DrawModel(gl_vissprite_t *spr)
|
|||
const UINT8 hflip = (UINT8)(!(spr->mobj->mirrored) != !R_ThingHorizontallyFlipped(spr->mobj));
|
||||
spritedef_t *sprdef;
|
||||
spriteframe_t *sprframe;
|
||||
spriteinfo_t *sprinfo;
|
||||
angle_t ang;
|
||||
INT32 mod;
|
||||
float finalscale;
|
||||
interpmobjstate_t interp;
|
||||
|
||||
if (R_UsingFrameInterpolation() && !paused)
|
||||
|
@ -1388,12 +1385,10 @@ boolean HWR_DrawModel(gl_vissprite_t *spr)
|
|||
{
|
||||
md2 = &md2_playermodels[(skin_t*)spr->mobj->skin-skins];
|
||||
md2->skin = (skin_t*)spr->mobj->skin-skins;
|
||||
sprinfo = &((skin_t *)spr->mobj->skin)->sprinfo[spr->mobj->sprite2];
|
||||
}
|
||||
else
|
||||
{
|
||||
md2 = &md2_models[spr->mobj->sprite];
|
||||
sprinfo = &spriteinfo[spr->mobj->sprite];
|
||||
}
|
||||
|
||||
// texture loading before model init, so it knows if sprite graphics are used, which
|
||||
|
@ -1455,7 +1450,6 @@ boolean HWR_DrawModel(gl_vissprite_t *spr)
|
|||
}
|
||||
|
||||
//HWD.pfnSetBlend(blend); // This seems to actually break translucency?
|
||||
finalscale = md2->scale;
|
||||
//Hurdler: arf, I don't like that implementation at all... too much crappy
|
||||
|
||||
if (gpatch && hwrPatch && hwrPatch->mipmap->format) // else if meant that if a texture couldn't be loaded, it would just end up using something else's texture
|
||||
|
@ -1591,7 +1585,7 @@ boolean HWR_DrawModel(gl_vissprite_t *spr)
|
|||
p.y = FIXED_TO_FLOAT(interp.y)+md2->offset;
|
||||
|
||||
if (flip)
|
||||
p.z = FIXED_TO_FLOAT(interp.z + spr->mobj->height);
|
||||
p.z = FIXED_TO_FLOAT(interp.z + interp.height);
|
||||
else
|
||||
p.z = FIXED_TO_FLOAT(interp.z);
|
||||
|
||||
|
@ -1614,61 +1608,56 @@ boolean HWR_DrawModel(gl_vissprite_t *spr)
|
|||
p.angley = FIXED_TO_FLOAT(anglef);
|
||||
}
|
||||
|
||||
p.rollangle = 0.0f;
|
||||
p.rollflip = 1;
|
||||
p.rotaxis = 0;
|
||||
if (spr->mobj->rollangle)
|
||||
{
|
||||
fixed_t anglef = AngleFixed(spr->mobj->rollangle);
|
||||
p.rollangle = FIXED_TO_FLOAT(anglef);
|
||||
p.roll = true;
|
||||
fixed_t anglef = AngleFixed(R_ModelRotationAngle(&interp));
|
||||
|
||||
// rotation pivot
|
||||
p.centerx = FIXED_TO_FLOAT(spr->mobj->radius/2);
|
||||
p.centery = FIXED_TO_FLOAT(spr->mobj->height/(flip ? -2 : 2));
|
||||
p.rollangle = 0.0f;
|
||||
|
||||
// rotation axis
|
||||
if (sprinfo->available)
|
||||
p.rotaxis = (UINT8)(sprinfo->pivot[(spr->mobj->frame & FF_FRAMEMASK)].rotaxis);
|
||||
if (anglef)
|
||||
{
|
||||
fixed_t camAngleDiff = AngleFixed(viewangle) - FLOAT_TO_FIXED(p.angley); // dumb reconversion back, I know
|
||||
|
||||
// for NiGHTS specifically but should work everywhere else
|
||||
ang = R_PointToAngle (interp.x, interp.y) - interp.angle;
|
||||
if ((sprframe->rotate & SRF_RIGHT) && (ang < ANGLE_180)) // See from right
|
||||
p.rollflip = 1;
|
||||
else if ((sprframe->rotate & SRF_LEFT) && (ang >= ANGLE_180)) // See from left
|
||||
p.rollflip = -1;
|
||||
p.rollangle = FIXED_TO_FLOAT(anglef);
|
||||
p.roll = true;
|
||||
|
||||
if (flip)
|
||||
p.rollflip *= -1;
|
||||
// rotation pivot
|
||||
p.centerx = FIXED_TO_FLOAT(interp.radius / 2);
|
||||
p.centery = FIXED_TO_FLOAT(interp.height / 2);
|
||||
|
||||
// rotation axes relative to camera
|
||||
p.rollx = FIXED_TO_FLOAT(FINECOSINE(FixedAngle(camAngleDiff) >> ANGLETOFINESHIFT));
|
||||
p.rollz = FIXED_TO_FLOAT(FINESINE(FixedAngle(camAngleDiff) >> ANGLETOFINESHIFT));
|
||||
}
|
||||
}
|
||||
|
||||
p.anglex = 0.0f;
|
||||
|
||||
#ifdef USE_FTRANSFORM_ANGLEZ
|
||||
// Slope rotation from Kart
|
||||
p.anglez = 0.0f;
|
||||
if (spr->mobj->standingslope)
|
||||
{
|
||||
fixed_t tempz = spr->mobj->standingslope->normal.z;
|
||||
fixed_t tempy = spr->mobj->standingslope->normal.y;
|
||||
fixed_t tempx = spr->mobj->standingslope->normal.x;
|
||||
fixed_t tempangle = AngleFixed(R_PointToAngle2(0, 0, FixedSqrt(FixedMul(tempy, tempy) + FixedMul(tempz, tempz)), tempx));
|
||||
p.anglez = FIXED_TO_FLOAT(tempangle);
|
||||
tempangle = -AngleFixed(R_PointToAngle2(0, 0, tempz, tempy));
|
||||
p.anglex = FIXED_TO_FLOAT(tempangle);
|
||||
}
|
||||
#if 0
|
||||
p.anglez = FIXED_TO_FLOAT(AngleFixed(interp.pitch));
|
||||
p.anglex = FIXED_TO_FLOAT(AngleFixed(interp.roll));
|
||||
#else
|
||||
p.anglez = 0.f;
|
||||
p.anglex = 0.f;
|
||||
#endif
|
||||
|
||||
// SRB2CBTODO: MD2 scaling support
|
||||
finalscale *= FIXED_TO_FLOAT(spr->mobj->scale);
|
||||
|
||||
p.flip = atransform.flip;
|
||||
#ifdef USE_FTRANSFORM_MIRROR
|
||||
p.mirror = atransform.mirror; // from Kart
|
||||
#endif
|
||||
p.mirror = atransform.mirror;
|
||||
|
||||
HWD.pfnSetShader(SHADER_MODEL); // model shader
|
||||
HWD.pfnDrawModel(md2->model, frame, durs, tics, nextFrame, &p, finalscale, flip, hflip, &Surf);
|
||||
{
|
||||
float this_scale = FIXED_TO_FLOAT(interp.scale);
|
||||
|
||||
float xs = this_scale * FIXED_TO_FLOAT(interp.spritexscale);
|
||||
float ys = this_scale * FIXED_TO_FLOAT(interp.spriteyscale);
|
||||
|
||||
float ox = xs * FIXED_TO_FLOAT(interp.spritexoffset);
|
||||
float oy = ys * FIXED_TO_FLOAT(interp.spriteyoffset);
|
||||
|
||||
// offset perpendicular to the camera angle
|
||||
p.x -= ox * gl_viewsin;
|
||||
p.y += ox * gl_viewcos;
|
||||
p.z += oy;
|
||||
|
||||
HWD.pfnDrawModel(md2->model, frame, durs, tics, nextFrame, &p, md2->scale * xs, md2->scale * ys, flip, hflip, &Surf);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
#include "hw_md2load.h"
|
||||
#include "hw_md3load.h"
|
||||
#include "hw_md2.h"
|
||||
#include "u_list.h"
|
||||
#include "../u_list.h"
|
||||
#include <string.h>
|
||||
|
||||
static float PI = (3.1415926535897932384626433832795f);
|
||||
|
@ -672,6 +672,9 @@ void GeneratePolygonNormals(model_t *model, int ztag)
|
|||
|
||||
for (k = 0; k < mesh->numTriangles; k++)
|
||||
{
|
||||
/// TODO: normalize vectors
|
||||
(void)vertices;
|
||||
(void)polyNormals;
|
||||
// Vector::Normal(vertices, polyNormals);
|
||||
vertices += 3 * 3;
|
||||
polyNormals++;
|
||||
|
|
|
@ -1030,6 +1030,12 @@ EXPORT void HWRAPI(LoadCustomShader) (int number, char *code, size_t size, boole
|
|||
EXPORT void HWRAPI(SetShader) (int type)
|
||||
{
|
||||
#ifdef GL_SHADERS
|
||||
if (type == SHADER_NONE)
|
||||
{
|
||||
UnSetShader();
|
||||
return;
|
||||
}
|
||||
|
||||
if (gl_allowshaders != HWD_SHADEROPTION_OFF)
|
||||
{
|
||||
gl_shader_t *shader = gl_shaderstate.current;
|
||||
|
@ -2290,7 +2296,7 @@ EXPORT void HWRAPI(DrawPolygon) (FSurfaceInfo *pSurf, FOutVector *pOutVerts, FUI
|
|||
|
||||
pglVertexPointer(3, GL_FLOAT, sizeof(FOutVector), &pOutVerts[0].x);
|
||||
pglTexCoordPointer(2, GL_FLOAT, sizeof(FOutVector), &pOutVerts[0].s);
|
||||
pglDrawArrays(GL_TRIANGLE_FAN, 0, iNumPts);
|
||||
pglDrawArrays(PolyFlags & PF_WireFrame ? GL_LINES : GL_TRIANGLE_FAN, 0, iNumPts);
|
||||
|
||||
if (PolyFlags & PF_RemoveYWrap)
|
||||
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||
|
@ -2673,7 +2679,7 @@ EXPORT void HWRAPI(CreateModelVBOs) (model_t *model)
|
|||
|
||||
#define BUFFER_OFFSET(i) ((void*)(i))
|
||||
|
||||
static void DrawModelEx(model_t *model, INT32 frameIndex, float duration, float tics, INT32 nextFrameIndex, FTransform *pos, float scale, UINT8 flipped, UINT8 hflipped, FSurfaceInfo *Surface)
|
||||
static void DrawModelEx(model_t *model, INT32 frameIndex, float duration, float tics, INT32 nextFrameIndex, FTransform *pos, float hscale, float vscale, UINT8 flipped, UINT8 hflipped, FSurfaceInfo *Surface)
|
||||
{
|
||||
static GLRGBAFloat poly = {0,0,0,0};
|
||||
static GLRGBAFloat tint = {0,0,0,0};
|
||||
|
@ -2697,10 +2703,11 @@ static void DrawModelEx(model_t *model, INT32 frameIndex, float duration, float
|
|||
#endif
|
||||
|
||||
// Affect input model scaling
|
||||
scale *= 0.5f;
|
||||
scalex = scale;
|
||||
scaley = scale;
|
||||
scalez = scale;
|
||||
hscale *= 0.5f;
|
||||
vscale *= 0.5f;
|
||||
scalex = hscale;
|
||||
scaley = vscale;
|
||||
scalez = hscale;
|
||||
|
||||
if (duration > 0.0 && tics >= 0.0) // don't interpolate if instantaneous or infinite in length
|
||||
{
|
||||
|
@ -2776,7 +2783,6 @@ static void DrawModelEx(model_t *model, INT32 frameIndex, float duration, float
|
|||
pglEnable(GL_CULL_FACE);
|
||||
pglEnable(GL_NORMALIZE);
|
||||
|
||||
#ifdef USE_FTRANSFORM_MIRROR
|
||||
// flipped is if the object is vertically flipped
|
||||
// hflipped is if the object is horizontally flipped
|
||||
// pos->flip is if the screen is flipped vertically
|
||||
|
@ -2789,17 +2795,6 @@ static void DrawModelEx(model_t *model, INT32 frameIndex, float duration, float
|
|||
else
|
||||
pglCullFace(GL_BACK);
|
||||
}
|
||||
#else
|
||||
// pos->flip is if the screen is flipped too
|
||||
if (flipped ^ hflipped ^ pos->flip) // If one or three of these are active, but not two, invert the model's culling
|
||||
{
|
||||
pglCullFace(GL_FRONT);
|
||||
}
|
||||
else
|
||||
{
|
||||
pglCullFace(GL_BACK);
|
||||
}
|
||||
#endif
|
||||
|
||||
pglPushMatrix(); // should be the same as glLoadIdentity
|
||||
//Hurdler: now it seems to work
|
||||
|
@ -2809,22 +2804,14 @@ static void DrawModelEx(model_t *model, INT32 frameIndex, float duration, float
|
|||
if (hflipped)
|
||||
scalez = -scalez;
|
||||
|
||||
#ifdef USE_FTRANSFORM_ANGLEZ
|
||||
pglRotatef(pos->anglez, 0.0f, 0.0f, -1.0f); // rotate by slope from Kart
|
||||
#endif
|
||||
pglRotatef(pos->angley, 0.0f, -1.0f, 0.0f);
|
||||
pglRotatef(pos->anglez, 0.0f, 0.0f, -1.0f);
|
||||
pglRotatef(pos->anglex, 1.0f, 0.0f, 0.0f);
|
||||
pglRotatef(pos->angley, 0.0f, -1.0f, 0.0f);
|
||||
|
||||
if (pos->roll)
|
||||
{
|
||||
float roll = (1.0f * pos->rollflip);
|
||||
pglTranslatef(pos->centerx, pos->centery, 0);
|
||||
if (pos->rotaxis == 2) // Z
|
||||
pglRotatef(pos->rollangle, 0.0f, 0.0f, roll);
|
||||
else if (pos->rotaxis == 1) // Y
|
||||
pglRotatef(pos->rollangle, 0.0f, roll, 0.0f);
|
||||
else // X
|
||||
pglRotatef(pos->rollangle, roll, 0.0f, 0.0f);
|
||||
pglRotatef(pos->rollangle, pos->rollx, 0.0f, pos->rollz);
|
||||
pglTranslatef(-pos->centerx, -pos->centery, 0);
|
||||
}
|
||||
|
||||
|
@ -2978,9 +2965,9 @@ static void DrawModelEx(model_t *model, INT32 frameIndex, float duration, float
|
|||
// -----------------+
|
||||
// HWRAPI DrawModel : Draw a model
|
||||
// -----------------+
|
||||
EXPORT void HWRAPI(DrawModel) (model_t *model, INT32 frameIndex, float duration, float tics, INT32 nextFrameIndex, FTransform *pos, float scale, UINT8 flipped, UINT8 hflipped, FSurfaceInfo *Surface)
|
||||
EXPORT void HWRAPI(DrawModel) (model_t *model, INT32 frameIndex, float duration, float tics, INT32 nextFrameIndex, FTransform *pos, float hscale, float vscale, UINT8 flipped, UINT8 hflipped, FSurfaceInfo *Surface)
|
||||
{
|
||||
DrawModelEx(model, frameIndex, duration, tics, nextFrameIndex, pos, scale, flipped, hflipped, Surface);
|
||||
DrawModelEx(model, frameIndex, duration, tics, nextFrameIndex, pos, hscale, vscale, flipped, hflipped, Surface);
|
||||
}
|
||||
|
||||
// -----------------+
|
||||
|
@ -2997,13 +2984,9 @@ EXPORT void HWRAPI(SetTransform) (FTransform *stransform)
|
|||
if (stransform)
|
||||
{
|
||||
used_fov = stransform->fovxangle;
|
||||
#ifdef USE_FTRANSFORM_MIRROR
|
||||
// mirroring from Kart
|
||||
if (stransform->mirror)
|
||||
pglScalef(-stransform->scalex, stransform->scaley, -stransform->scalez);
|
||||
else
|
||||
#endif
|
||||
if (stransform->flip)
|
||||
else if (stransform->flip)
|
||||
pglScalef(stransform->scalex, -stransform->scaley, -stransform->scalez);
|
||||
else
|
||||
pglScalef(stransform->scalex, stransform->scaley, -stransform->scalez);
|
||||
|
|
|
@ -159,7 +159,7 @@ HMS_connect (const char *format, ...)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
if (cv_masterserver_token.string[0])
|
||||
if (cv_masterserver_token.string && cv_masterserver_token.string[0])
|
||||
{
|
||||
quack_token = curl_easy_escape(curl, cv_masterserver_token.string, 0);
|
||||
token_length = ( sizeof "?token="-1 )+ strlen(quack_token);
|
||||
|
@ -216,7 +216,11 @@ HMS_connect (const char *format, ...)
|
|||
|
||||
curl_easy_setopt(curl, CURLOPT_URL, url);
|
||||
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
|
||||
curl_easy_setopt(curl, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
|
||||
|
||||
#ifndef NO_IPV6
|
||||
if (M_CheckParm("-noipv6"))
|
||||
#endif
|
||||
curl_easy_setopt(curl, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
|
||||
|
||||
curl_easy_setopt(curl, CURLOPT_TIMEOUT, cv_masterserver_timeout.value);
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, HMS_on_read);
|
||||
|
|
|
@ -2025,7 +2025,7 @@ void HU_Drawer(void)
|
|||
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 y = hudinfo[HUD_LIVES].y - 13;
|
||||
|
@ -2862,18 +2862,6 @@ static void HU_DrawRankings(void)
|
|||
V_DrawCenteredString(256, 16, 0, va("%d", cv_pointlimit.value));
|
||||
}
|
||||
}
|
||||
else if (gametyperankings[gametype] == GT_COOP)
|
||||
{
|
||||
INT32 totalscore = 0;
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
if (playeringame[i])
|
||||
totalscore += players[i].score;
|
||||
}
|
||||
|
||||
V_DrawCenteredString(256, 8, 0, "TOTAL SCORE");
|
||||
V_DrawCenteredString(256, 16, 0, va("%u", totalscore));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (circuitmap)
|
||||
|
@ -2994,9 +2982,9 @@ static void HU_DrawCoopOverlay(void)
|
|||
V_DrawSmallScaledPatch(148, 172, 0, tokenicon);
|
||||
}
|
||||
|
||||
if (LUA_HudEnabled(hud_tabemblems) && (!modifiedgame || savemoddata))
|
||||
if (LUA_HudEnabled(hud_tabemblems))
|
||||
{
|
||||
V_DrawString(160, 144, 0, va("- %d/%d", M_CountEmblems(), numemblems+numextraemblems));
|
||||
V_DrawString(160, 144, 0, va("- %d/%d", M_CountEmblems(clientGamedata), numemblems+numextraemblems));
|
||||
V_DrawScaledPatch(128, 144 - emblemicon->height/4, 0, emblemicon);
|
||||
}
|
||||
|
||||
|
@ -3029,6 +3017,15 @@ static void HU_DrawNetplayCoopOverlay(void)
|
|||
V_DrawSmallScaledPatch(148, 6, 0, tokenicon);
|
||||
}
|
||||
|
||||
if (G_CoopGametype() && LUA_HudEnabled(hud_tabemblems))
|
||||
{
|
||||
V_DrawCenteredString(256, 14, 0, "/");
|
||||
V_DrawString(256 + 4, 14, 0, va("%d", numemblems + numextraemblems));
|
||||
V_DrawRightAlignedString(256 - 4, 14, 0, va("%d", M_CountEmblems(clientGamedata)));
|
||||
|
||||
V_DrawSmallScaledPatch(256 - (emblemicon->width / 4), 6, 0, emblemicon);
|
||||
}
|
||||
|
||||
if (!LUA_HudEnabled(hud_coopemeralds))
|
||||
return;
|
||||
|
||||
|
|
11
src/i_net.h
11
src/i_net.h
|
@ -109,6 +109,17 @@ extern boolean (*I_NetCanSend)(void);
|
|||
*/
|
||||
extern void (*I_NetFreeNodenum)(INT32 nodenum);
|
||||
|
||||
/**
|
||||
\brief split a string into address and port
|
||||
|
||||
\param address string to split
|
||||
|
||||
\param port double pointer to hold port component (optional)
|
||||
|
||||
\return address component
|
||||
*/
|
||||
extern char *I_NetSplitAddress(char *address, char **port);
|
||||
|
||||
/** \brief open a connection with specified address
|
||||
|
||||
\param address address to connect to
|
||||
|
|
|
@ -40,7 +40,7 @@ extern UINT8 keyboard_started;
|
|||
|
||||
\return free memory in the system
|
||||
*/
|
||||
UINT32 I_GetFreeMem(UINT32 *total);
|
||||
size_t I_GetFreeMem(size_t *total);
|
||||
|
||||
/** \brief Returns precise time value for performance measurement. The precise
|
||||
time should be a monotonically increasing counter, and will wrap.
|
||||
|
@ -49,6 +49,10 @@ UINT32 I_GetFreeMem(UINT32 *total);
|
|||
*/
|
||||
precise_t I_GetPreciseTime(void);
|
||||
|
||||
/** \brief Fills a buffer with random data, returns amount of data obtained.
|
||||
*/
|
||||
size_t I_GetRandomBytes(char *destination, size_t count);
|
||||
|
||||
/** \brief Get the precision of precise_t in units per second. Invocations of
|
||||
this function for the program's duration MUST return the same value.
|
||||
*/
|
||||
|
|
71
src/i_tcp.c
71
src/i_tcp.c
|
@ -340,8 +340,14 @@ static inline void I_UPnP_rem(const char *port, const char * servicetype)
|
|||
|
||||
static const char *SOCK_AddrToStr(mysockaddr_t *sk)
|
||||
{
|
||||
static char s[64]; // 255.255.255.255:65535 or IPv6:65535
|
||||
static char s[64]; // 255.255.255.255:65535 or
|
||||
// [ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff]:65535
|
||||
#ifdef HAVE_NTOP
|
||||
#ifdef HAVE_IPV6
|
||||
int v6 = (sk->any.sa_family == AF_INET6);
|
||||
#else
|
||||
int v6 = 0;
|
||||
#endif
|
||||
void *addr;
|
||||
|
||||
if(sk->any.sa_family == AF_INET)
|
||||
|
@ -355,14 +361,21 @@ static const char *SOCK_AddrToStr(mysockaddr_t *sk)
|
|||
|
||||
if(addr == NULL)
|
||||
sprintf(s, "No address");
|
||||
else if(inet_ntop(sk->any.sa_family, addr, s, sizeof (s)) == NULL)
|
||||
else if(inet_ntop(sk->any.sa_family, addr, &s[v6], sizeof (s) - v6) == NULL)
|
||||
sprintf(s, "Unknown family type, error #%u", errno);
|
||||
#ifdef HAVE_IPV6
|
||||
else if(sk->any.sa_family == AF_INET6 && sk->ip6.sin6_port != 0)
|
||||
strcat(s, va(":%d", ntohs(sk->ip6.sin6_port)));
|
||||
else if(sk->any.sa_family == AF_INET6)
|
||||
{
|
||||
s[0] = '[';
|
||||
strcat(s, "]");
|
||||
|
||||
if (sk->ip6.sin6_port != 0)
|
||||
strcat(s, va(":%d", ntohs(sk->ip6.sin6_port)));
|
||||
}
|
||||
#endif
|
||||
else if(sk->any.sa_family == AF_INET && sk->ip4.sin_port != 0)
|
||||
strcat(s, va(":%d", ntohs(sk->ip4.sin_port)));
|
||||
|
||||
#else
|
||||
if (sk->any.sa_family == AF_INET)
|
||||
{
|
||||
|
@ -427,7 +440,7 @@ static boolean SOCK_cmpaddr(mysockaddr_t *a, mysockaddr_t *b, UINT8 mask)
|
|||
&& (b->ip4.sin_port == 0 || (a->ip4.sin_port == b->ip4.sin_port));
|
||||
#ifdef HAVE_IPV6
|
||||
else if (b->any.sa_family == AF_INET6)
|
||||
return memcmp(&a->ip6.sin6_addr, &b->ip6.sin6_addr, sizeof(b->ip6.sin6_addr))
|
||||
return !memcmp(&a->ip6.sin6_addr, &b->ip6.sin6_addr, sizeof(b->ip6.sin6_addr))
|
||||
&& (b->ip6.sin6_port == 0 || (a->ip6.sin6_port == b->ip6.sin6_port));
|
||||
#endif
|
||||
else
|
||||
|
@ -735,8 +748,7 @@ static SOCKET_TYPE UDP_Bind(int family, struct sockaddr *addr, socklen_t addrlen
|
|||
unsigned long trueval = true;
|
||||
#endif
|
||||
mysockaddr_t straddr;
|
||||
struct sockaddr_in sin;
|
||||
socklen_t len = sizeof(sin);
|
||||
socklen_t len = sizeof(straddr);
|
||||
|
||||
if (s == (SOCKET_TYPE)ERRSOCKET)
|
||||
return (SOCKET_TYPE)ERRSOCKET;
|
||||
|
@ -754,14 +766,12 @@ static SOCKET_TYPE UDP_Bind(int family, struct sockaddr *addr, socklen_t addrlen
|
|||
}
|
||||
#endif
|
||||
|
||||
straddr.any = *addr;
|
||||
memcpy(&straddr, addr, addrlen);
|
||||
I_OutputMsg("Binding to %s\n", SOCK_AddrToStr(&straddr));
|
||||
|
||||
if (family == AF_INET)
|
||||
{
|
||||
mysockaddr_t tmpaddr;
|
||||
tmpaddr.any = *addr ;
|
||||
if (tmpaddr.ip4.sin_addr.s_addr == htonl(INADDR_ANY))
|
||||
if (straddr.ip4.sin_addr.s_addr == htonl(INADDR_ANY))
|
||||
{
|
||||
opt = true;
|
||||
opts = (socklen_t)sizeof(opt);
|
||||
|
@ -778,7 +788,7 @@ static SOCKET_TYPE UDP_Bind(int family, struct sockaddr *addr, socklen_t addrlen
|
|||
#ifdef HAVE_IPV6
|
||||
else if (family == AF_INET6)
|
||||
{
|
||||
if (memcmp(addr, &in6addr_any, sizeof(in6addr_any)) == 0) //IN6_ARE_ADDR_EQUAL
|
||||
if (memcmp(&straddr.ip6.sin6_addr, &in6addr_any, sizeof(in6addr_any)) == 0) //IN6_ARE_ADDR_EQUAL
|
||||
{
|
||||
opt = true;
|
||||
opts = (socklen_t)sizeof(opt);
|
||||
|
@ -788,7 +798,7 @@ static SOCKET_TYPE UDP_Bind(int family, struct sockaddr *addr, socklen_t addrlen
|
|||
// make it IPv6 ony
|
||||
opt = true;
|
||||
opts = (socklen_t)sizeof(opt);
|
||||
if (setsockopt(s, SOL_SOCKET, IPV6_V6ONLY, (char *)&opt, opts))
|
||||
if (setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, (char *)&opt, opts))
|
||||
{
|
||||
CONS_Alert(CONS_WARNING, M_GetText("Could not limit IPv6 bind\n")); // I do not care anymore
|
||||
}
|
||||
|
@ -830,10 +840,17 @@ static SOCKET_TYPE UDP_Bind(int family, struct sockaddr *addr, socklen_t addrlen
|
|||
CONS_Printf(M_GetText("Network system buffer set to: %dKb\n"), opt>>10);
|
||||
}
|
||||
|
||||
if (getsockname(s, (struct sockaddr *)&sin, &len) == -1)
|
||||
if (getsockname(s, &straddr.any, &len) == -1)
|
||||
CONS_Alert(CONS_WARNING, M_GetText("Failed to get port number\n"));
|
||||
else
|
||||
current_port = (UINT16)ntohs(sin.sin_port);
|
||||
{
|
||||
if (family == AF_INET)
|
||||
current_port = (UINT16)ntohs(straddr.ip4.sin_port);
|
||||
#ifdef HAVE_IPV6
|
||||
else if (family == AF_INET6)
|
||||
current_port = (UINT16)ntohs(straddr.ip6.sin6_port);
|
||||
#endif
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
@ -844,7 +861,7 @@ static boolean UDP_Socket(void)
|
|||
struct my_addrinfo *ai, *runp, hints;
|
||||
int gaie;
|
||||
#ifdef HAVE_IPV6
|
||||
const INT32 b_ipv6 = M_CheckParm("-ipv6");
|
||||
const INT32 b_ipv6 = !M_CheckParm("-noipv6");
|
||||
#endif
|
||||
const char *serv;
|
||||
|
||||
|
@ -1156,6 +1173,7 @@ static SINT8 SOCK_NetMakeNodewPort(const char *address, const char *port)
|
|||
SINT8 newnode = -1;
|
||||
struct my_addrinfo *ai = NULL, *runp, hints;
|
||||
int gaie;
|
||||
size_t i;
|
||||
|
||||
if (!port || !port[0])
|
||||
port = DEFAULTPORT;
|
||||
|
@ -1183,13 +1201,24 @@ static SINT8 SOCK_NetMakeNodewPort(const char *address, const char *port)
|
|||
|
||||
while (runp != NULL)
|
||||
{
|
||||
// find ip of the server
|
||||
if (sendto(mysockets[0], NULL, 0, 0, runp->ai_addr, runp->ai_addrlen) == 0)
|
||||
// test ip address of server
|
||||
for (i = 0; i < mysocketses; ++i)
|
||||
{
|
||||
memcpy(&clientaddress[newnode], runp->ai_addr, runp->ai_addrlen);
|
||||
break;
|
||||
/* sendto tests that there is a network to this
|
||||
address */
|
||||
if (runp->ai_addr->sa_family == myfamily[i] &&
|
||||
sendto(mysockets[i], NULL, 0, 0,
|
||||
runp->ai_addr, runp->ai_addrlen) == 0)
|
||||
{
|
||||
memcpy(&clientaddress[newnode], runp->ai_addr, runp->ai_addrlen);
|
||||
break;
|
||||
}
|
||||
}
|
||||
runp = runp->ai_next;
|
||||
|
||||
if (i < mysocketses)
|
||||
runp = runp->ai_next;
|
||||
else
|
||||
break;
|
||||
}
|
||||
I_freeaddrinfo(ai);
|
||||
return newnode;
|
||||
|
|
121
src/info.c
121
src/info.c
|
@ -7194,7 +7194,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
sfx_cgot, // deathsound
|
||||
EMERALD1, // speed
|
||||
16*FRACUNIT, // radius
|
||||
32*FRACUNIT, // height
|
||||
24*FRACUNIT, // height
|
||||
0, // display offset
|
||||
16, // mass
|
||||
0, // damage
|
||||
|
@ -7220,7 +7220,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
sfx_cgot, // deathsound
|
||||
EMERALD2, // speed
|
||||
16*FRACUNIT, // radius
|
||||
32*FRACUNIT, // height
|
||||
24*FRACUNIT, // height
|
||||
0, // display offset
|
||||
16, // mass
|
||||
0, // damage
|
||||
|
@ -7246,7 +7246,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
sfx_cgot, // deathsound
|
||||
EMERALD3, // speed
|
||||
16*FRACUNIT, // radius
|
||||
32*FRACUNIT, // height
|
||||
24*FRACUNIT, // height
|
||||
0, // display offset
|
||||
16, // mass
|
||||
0, // damage
|
||||
|
@ -7272,7 +7272,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
sfx_cgot, // deathsound
|
||||
EMERALD4, // speed
|
||||
16*FRACUNIT, // radius
|
||||
32*FRACUNIT, // height
|
||||
24*FRACUNIT, // height
|
||||
0, // display offset
|
||||
16, // mass
|
||||
0, // damage
|
||||
|
@ -7298,7 +7298,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
sfx_cgot, // deathsound
|
||||
EMERALD5, // speed
|
||||
16*FRACUNIT, // radius
|
||||
32*FRACUNIT, // height
|
||||
24*FRACUNIT, // height
|
||||
0, // display offset
|
||||
16, // mass
|
||||
0, // damage
|
||||
|
@ -7324,7 +7324,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
sfx_cgot, // deathsound
|
||||
EMERALD6, // speed
|
||||
16*FRACUNIT, // radius
|
||||
32*FRACUNIT, // height
|
||||
24*FRACUNIT, // height
|
||||
0, // display offset
|
||||
16, // mass
|
||||
0, // damage
|
||||
|
@ -7350,7 +7350,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
sfx_cgot, // deathsound
|
||||
EMERALD7, // speed
|
||||
16*FRACUNIT, // radius
|
||||
32*FRACUNIT, // height
|
||||
24*FRACUNIT, // height
|
||||
0, // display offset
|
||||
16, // mass
|
||||
0, // damage
|
||||
|
@ -18344,7 +18344,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
S_NULL, // xdeathstate
|
||||
sfx_itemup, // deathsound
|
||||
60*FRACUNIT, // speed
|
||||
24*FRACUNIT, // radius
|
||||
16*FRACUNIT, // radius
|
||||
24*FRACUNIT, // height
|
||||
0, // display offset
|
||||
pw_bouncering, // mass
|
||||
|
@ -18371,7 +18371,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
S_NULL, // xdeathstate
|
||||
sfx_itemup, // deathsound
|
||||
60*FRACUNIT, // speed
|
||||
24*FRACUNIT, // radius
|
||||
16*FRACUNIT, // radius
|
||||
24*FRACUNIT, // height
|
||||
0, // display offset
|
||||
pw_railring, // mass
|
||||
|
@ -18425,7 +18425,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
S_NULL, // xdeathstate
|
||||
sfx_itemup, // deathsound
|
||||
60*FRACUNIT, // speed
|
||||
24*FRACUNIT, // radius
|
||||
16*FRACUNIT, // radius
|
||||
24*FRACUNIT, // height
|
||||
0, // display offset
|
||||
pw_automaticring, // mass
|
||||
|
@ -18452,7 +18452,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
S_NULL, // xdeathstate
|
||||
sfx_itemup, // deathsound
|
||||
60*FRACUNIT, // speed
|
||||
24*FRACUNIT, // radius
|
||||
16*FRACUNIT, // radius
|
||||
24*FRACUNIT, // height
|
||||
0, // display offset
|
||||
pw_explosionring, // mass
|
||||
|
@ -18479,7 +18479,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
S_NULL, // xdeathstate
|
||||
sfx_itemup, // deathsound
|
||||
60*FRACUNIT, // speed
|
||||
24*FRACUNIT, // radius
|
||||
16*FRACUNIT, // radius
|
||||
24*FRACUNIT, // height
|
||||
0, // display offset
|
||||
pw_scatterring, // mass
|
||||
|
@ -18506,7 +18506,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
S_NULL, // xdeathstate
|
||||
sfx_itemup, // deathsound
|
||||
60*FRACUNIT, // speed
|
||||
24*FRACUNIT, // radius
|
||||
16*FRACUNIT, // radius
|
||||
24*FRACUNIT, // height
|
||||
0, // display offset
|
||||
pw_grenadering, // mass
|
||||
|
@ -18535,7 +18535,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
sfx_ncitem, // deathsound
|
||||
60*FRACUNIT, // speed
|
||||
24*FRACUNIT, // radius
|
||||
24*FRACUNIT, // height
|
||||
40*FRACUNIT, // height
|
||||
0, // display offset
|
||||
pw_bouncering, // mass
|
||||
2*TICRATE, // damage
|
||||
|
@ -18562,7 +18562,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
sfx_ncitem, // deathsound
|
||||
60*FRACUNIT, // speed
|
||||
24*FRACUNIT, // radius
|
||||
24*FRACUNIT, // height
|
||||
40*FRACUNIT, // height
|
||||
0, // display offset
|
||||
pw_railring, // mass
|
||||
2*TICRATE, // damage
|
||||
|
@ -18589,7 +18589,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
sfx_ncitem, // deathsound
|
||||
60*FRACUNIT, // speed
|
||||
24*FRACUNIT, // radius
|
||||
24*FRACUNIT, // height
|
||||
40*FRACUNIT, // height
|
||||
0, // display offset
|
||||
pw_automaticring, // mass
|
||||
2*TICRATE, // damage
|
||||
|
@ -18616,7 +18616,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
sfx_ncitem, // deathsound
|
||||
60*FRACUNIT, // speed
|
||||
24*FRACUNIT, // radius
|
||||
24*FRACUNIT, // height
|
||||
40*FRACUNIT, // height
|
||||
0, // display offset
|
||||
pw_explosionring, // mass
|
||||
2*TICRATE, // damage
|
||||
|
@ -18643,7 +18643,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
sfx_ncitem, // deathsound
|
||||
60*FRACUNIT, // speed
|
||||
24*FRACUNIT, // radius
|
||||
24*FRACUNIT, // height
|
||||
40*FRACUNIT, // height
|
||||
0, // display offset
|
||||
pw_scatterring, // mass
|
||||
2*TICRATE, // damage
|
||||
|
@ -18670,7 +18670,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
sfx_ncitem, // deathsound
|
||||
60*FRACUNIT, // speed
|
||||
24*FRACUNIT, // radius
|
||||
24*FRACUNIT, // height
|
||||
40*FRACUNIT, // height
|
||||
0, // display offset
|
||||
pw_grenadering, // mass
|
||||
2*TICRATE, // damage
|
||||
|
@ -21584,68 +21584,113 @@ 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
|
||||
|
||||
// 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
|
||||
{"Slate", {0x00, 0x02, 0x04, 0x06, 0x08, 0x0a, 0xaa, 0xaa, 0xaa, 0xab, 0xac, 0xac, 0xad, 0xad, 0xae, 0xaf}, SKINCOLOR_SILVER, 12, 0, true}, // SKINCOLOR_SLATE
|
||||
{"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
|
||||
{"Yogurt", {0xd0, 0x30, 0xd8, 0xd9, 0xda, 0xdb, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 0xe0, 0xe3, 0xe6, 0xe8, 0xe9}, SKINCOLOR_RUST, 7, V_BROWNMAP, true}, // SKINCOLOR_YOGURT
|
||||
{"Brown", {0xdf, 0xe0, 0xe1, 0xe2, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef}, SKINCOLOR_TAN, 2, V_BROWNMAP, true}, // SKINCOLOR_BROWN
|
||||
{"Bronze", {0xde, 0xe0, 0xe1, 0xe4, 0xe7, 0xe9, 0xeb, 0xec, 0xed, 0xed, 0xed, 0x19, 0x19, 0x1b, 0x1d, 0x1e}, SKINCOLOR_KETCHUP, 0, V_BROWNMAP, true}, // SKINCOLOR_BRONZE
|
||||
{"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
|
||||
{"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
|
||||
{"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
|
||||
{"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
|
||||
{"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
|
||||
{"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
|
||||
{"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
|
||||
{"Yogurt", {0xd0, 0x30, 0xd8, 0xd9, 0xda, 0xdb, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 0xe0, 0xe3, 0xe6, 0xe8, 0xe9}, SKINCOLOR_RUST, 7, V_BROWNMAP, true}, // SKINCOLOR_YOGURT
|
||||
{"Latte", { 48, 217, 219, 221, 223, 224, 226, 228, 68, 69, 70, 70, 44, 45, 46, 47}, SKINCOLOR_BOTTLE, 12, V_BROWNMAP, true}, // SKINCOLOR_LATTE
|
||||
{"Brown", {0xdf, 0xe0, 0xe1, 0xe2, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef}, SKINCOLOR_TAN, 2, V_BROWNMAP, true}, // SKINCOLOR_BROWN
|
||||
{"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
|
||||
{"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_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
|
||||
{"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
|
||||
{"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
|
||||
{"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_GOLD, 4, V_PURPLEMAP, true}, // SKINCOLOR_LAVENDER
|
||||
|
||||
// Viv's vivid colours (toast 21/07/17)
|
||||
// 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
|
||||
{"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
|
||||
{"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_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
|
||||
{"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
|
||||
{"Ketchup", {0x48, 0x49, 0x40, 0x33, 0x34, 0x36, 0x22, 0x24, 0x26, 0x28, 0x2a, 0x2b, 0x2c, 0x47, 0x2e, 0x2f}, SKINCOLOR_BRONZE, 8, V_REDMAP, true}, // SKINCOLOR_KETCHUP
|
||||
{"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
|
||||
{"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
|
||||
{"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
|
||||
{"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
|
||||
{"Orange", {0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x2c}, 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
|
||||
{"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
|
||||
{"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_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
|
||||
{"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
|
||||
{"Olive", {0x4b, 0x4b, 0x4c, 0x4c, 0x4d, 0x4e, 0xe7, 0xe7, 0xe9, 0xc5, 0xc5, 0xc6, 0xc6, 0xc7, 0xc7, 0xfd}, SKINCOLOR_DUSK, 3, V_YELLOWMAP, true}, // SKINCOLOR_OLIVE
|
||||
{"Pear", { 88, 89, 188, 189, 189, 76, 76, 67, 67, 68, 69, 70, 45, 46, 47, 47}, SKINCOLOR_MARINE, 9, V_PERIDOTMAP, true}, // SKINCOLOR_PEAR
|
||||
{"Lemon", { 0, 80, 81, 83, 73, 73, 74, 74, 76, 76, 191, 191, 79, 79, 110, 111}, SKINCOLOR_FUCHSIA, 8, V_YELLOWMAP, true}, // SKINCOLOR_LEMON
|
||||
{"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
|
||||
{"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
|
||||
{"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
|
||||
{"Emerald", {0x70, 0x70, 0x71, 0x71, 0x72, 0x72, 0x73, 0x73, 0x73, 0x74, 0x75, 0x75, 0x76, 0x76, 0x77, 0x77}, SKINCOLOR_RUBY, 4, V_GREENMAP, true}, // SKINCOLOR_EMERALD
|
||||
{"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_TAFFY, 10, V_GREENMAP, true}, // SKINCOLOR_JADE
|
||||
{"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
|
||||
{"Seafoam", {0x01, 0x58, 0x59, 0x5a, 0x7d, 0x7d, 0x7e, 0x7e, 0x7e, 0x8f, 0x8f, 0x8a, 0x8a, 0x8a, 0xfd, 0xfd}, SKINCOLOR_PLUM, 6, V_AQUAMAP, true}, // SKINCOLOR_SEAFOAM
|
||||
{"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
|
||||
{"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
|
||||
{"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
|
||||
{"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
|
||||
{"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
|
||||
{"Aquamarine", { 0, 120, 121, 131, 132, 133, 134, 134, 135, 135, 149, 149, 172, 173, 174, 175}, SKINCOLOR_GARNET, 8, V_SKYMAP, true}, // SKINCOLOR_AQUAMARINE
|
||||
{"Sky", {0x80, 0x80, 0x81, 0x82, 0x83, 0x83, 0x84, 0x85, 0x85, 0x86, 0x87, 0x88, 0x89, 0x89, 0x8a, 0x8b}, SKINCOLOR_SANDY, 1, V_SKYMAP, true}, // SKINCOLOR_SKY
|
||||
{"Marine", { 144, 146, 147, 147, 148, 135, 136, 136, 137, 137, 127, 118, 119, 111, 111, 111}, SKINCOLOR_PEAR, 13, V_SKYMAP, true}, // SKINCOLOR_MARINE
|
||||
{"Cerulean", {0x85, 0x86, 0x87, 0x88, 0x88, 0x89, 0x89, 0x89, 0x8a, 0x8a, 0xfd, 0xfd, 0xfd, 0x1f, 0x1f, 0x1f}, SKINCOLOR_NEON, 4, V_SKYMAP, true}, // SKINCOLOR_CERULEAN
|
||||
{"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
|
||||
{"Sapphire", {0x80, 0x83, 0x86, 0x87, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xfd, 0xfe}, SKINCOLOR_SUNSET, 5, V_SKYMAP, true}, // SKINCOLOR_SAPPHIRE
|
||||
{"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_BLUEMAP, true}, // SKINCOLOR_SAPPHIRE
|
||||
{"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
|
||||
{"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", {0x93, 0x94, 0x95, 0x96, 0x98, 0x9a, 0x9b, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xfd, 0xfd, 0xfe, 0xfe}, 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, 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
|
||||
{"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
|
||||
{"Majesty", { 0, 1, 176, 160, 160, 161, 162, 162, 163, 172, 173, 174, 174, 175, 139, 139}, SKINCOLOR_GOLDENROD, 9, V_PURPLEMAP, true}, // SKINCOLOR_MAJESTY
|
||||
{"Pastel", {0x90, 0x90, 0xa0, 0xa0, 0xa1, 0xa1, 0xa2, 0xa2, 0xa2, 0xa3, 0xa4, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8}, SKINCOLOR_BUBBLEGUM, 9, V_PURPLEMAP, true}, // SKINCOLOR_PASTEL
|
||||
{"Purple", {0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa4, 0xa5, 0xa5, 0xa5, 0xa6, 0xa7, 0xa7, 0xa8, 0xa8, 0xa9, 0xa9}, SKINCOLOR_FLAME, 7, V_PURPLEMAP, true}, // SKINCOLOR_PURPLE
|
||||
{"Bubblegum", {0x00, 0xd0, 0xd0, 0xc8, 0xc8, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8}, SKINCOLOR_PASTEL, 8, V_MAGENTAMAP, true}, // SKINCOLOR_BUBBLEGUM
|
||||
{"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
|
||||
{"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
|
||||
{"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
|
||||
{"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
|
||||
{"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
|
||||
{"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
|
||||
{"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
|
||||
{"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_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
|
||||
{"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", { 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 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
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include "d_think.h"
|
||||
#include "sounds.h"
|
||||
#include "m_fixed.h"
|
||||
#include "dehacked.h" // MAX_ACTION_RECURSION
|
||||
|
||||
// deh_tables.c now has lists for the more named enums! PLEASE keep them up to date!
|
||||
// For great modding!!
|
||||
|
@ -151,6 +152,7 @@ enum actionnum
|
|||
A_BOSS3TAKEDAMAGE,
|
||||
A_BOSS3PATH,
|
||||
A_BOSS3SHOCKTHINK,
|
||||
A_SHOCKWAVE,
|
||||
A_LINEDEFEXECUTE,
|
||||
A_LINEDEFEXECUTEFROMARG,
|
||||
A_PLAYSEESOUND,
|
||||
|
@ -415,6 +417,7 @@ void A_Boss1Spikeballs();
|
|||
void A_Boss3TakeDamage();
|
||||
void A_Boss3Path();
|
||||
void A_Boss3ShockThink();
|
||||
void A_Shockwave();
|
||||
void A_LinedefExecute();
|
||||
void A_LinedefExecuteFromArg();
|
||||
void A_PlaySeeSound();
|
||||
|
@ -564,7 +567,7 @@ void A_DragonWing();
|
|||
void A_DragonSegment();
|
||||
void A_ChangeHeight();
|
||||
|
||||
extern boolean actionsoverridden[NUMACTIONS];
|
||||
extern int actionsoverridden[NUMACTIONS][MAX_ACTION_RECURSION];
|
||||
|
||||
// ratio of states to sprites to mobj types is roughly 6 : 1 : 1
|
||||
#define NUMMOBJFREESLOTS 512
|
||||
|
|
|
@ -581,6 +581,11 @@ static inline void libdivide_u128_shift(uint64_t *u1, uint64_t *u0, int32_t sign
|
|||
|
||||
////////// UINT32
|
||||
|
||||
#if defined(__GNUC__) || defined(__clang__) // Suppress intentional compiler warnings
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Waggregate-return"
|
||||
#endif
|
||||
|
||||
static inline struct libdivide_u32_t libdivide_internal_u32_gen(uint32_t d, int branchfree) {
|
||||
struct libdivide_u32_t result;
|
||||
uint32_t floor_log_2_d;
|
||||
|
@ -647,6 +652,10 @@ struct libdivide_u32_t libdivide_u32_gen(uint32_t d) {
|
|||
return ret;
|
||||
}*/
|
||||
|
||||
#if defined(__GNUC__) || defined(__clang__) // Stop suppressing intentional compiler warnings
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
uint32_t libdivide_u32_do(uint32_t numer, const struct libdivide_u32_t *denom) {
|
||||
uint8_t more = denom->more;
|
||||
if (!denom->magic) {
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue