Merge branch 'next' into showinput

This commit is contained in:
Alam Ed Arias 2023-10-25 14:24:17 -04:00
commit 1403f93176
239 changed files with 16891 additions and 20971 deletions

View file

@ -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
View file

@ -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
View file

@ -22,4 +22,5 @@ Win32_LIB_ASM_Release
/make
/bin
/build
/build.*
/build/*
/CMakeUserPresets.json

434
.gitlab-ci.yml Normal file
View file

@ -0,0 +1,434 @@
variables:
GIT_STRATEGY: clone
GIT_CLONE_PATH: $CI_BUILDS_DIR/$CI_CONCURRENT_ID/$CI_PROJECT_PATH
default:
image: debian:stable-slim
cache:
- key: ccache-$CI_PROJECT_PATH_SLUG-$CI_JOB_NAME_SLUG
fallback_keys:
- cache-$CI_PROJECT_PATH_SLUG-$CI_DEFAULT_BRANCH
- cache-$CI_PROJECT_PATH_SLUG-default
paths:
- ccache
- ccache_statslog
- key: apt-$CI_JOB_IMAGE
paths:
- apt-cache
unprotect: true
before_script:
- - |
# debconf
echo -e "\e[0Ksection_start:`date +%s`:debconf[collapsed=true]\r\e[0KSetup debconf's environment"
- export DEBIAN_FRONTEND="noninteractive"
- export DEBIAN_PRIORITY="low"
- export DEBCONF_NONINTERACTIVE_SEEN="true"
- |
# debconf
echo -e "\e[0Ksection_end:`date +%s`:debconf\r\e[0K"
- - |
# dpkg_aa
echo -e "\e[0Ksection_start:`date +%s`:dpkg_aa[collapsed=true]\r\e[0KAdding architectures to dpkg"
- dpkg --add-architecture i386
- dpkg --add-architecture amd64
- dpkg --add-architecture arm64
- |
# dpkg_aa
echo -e "\e[0Ksection_end:`date +%s`:dpkg_aa\r\e[0K"
- - |
# apt_conf
echo -e "\e[0Ksection_start:`date +%s`:apt_conf[collapsed=true]\r\e[0KSetting up APT conf"
- export APT_CACHE_DIR=`pwd`/apt-cache
- mkdir --parents --verbose $APT_CACHE_DIR/partial/
- touch /etc/apt/apt.conf.d/99build
- |
# apt.conf
echo Adding options to apt.conf':'
- |
# APT::Install-Recommends
echo APT::Install-Recommends "false"\; | tee --append /etc/apt/apt.conf.d/99build
- |
# quit
echo quiet "1"\; | tee --append /etc/apt/apt.conf.d/99build
- |
# APT::Get::Assume-Yes
echo APT::Get::Assume-Yes "true"\; | tee --append /etc/apt/apt.conf.d/99build
- |
# Dir::Cache::Archives
echo Dir::Cache::Archives "$APT_CACHE_DIR"\; | tee --append /etc/apt/apt.conf.d/99build
- |
# apt_conf
echo -e "\e[0Ksection_end:`date +%s`:apt_conf\r\e[0K"
- - |
# apt_update
echo -e "\e[0Ksection_start:`date +%s`:apt_update[collapsed=true]\r\e[0KUpdating APT listing"
- apt-get update
- |
# apt_update
echo -e "\e[0Ksection_end:`date +%s`:apt_update\r\e[0K"
- - |
# apt_pre
echo -e "\e[0Ksection_start:`date +%s`:apt_pre[collapsed=true]\r\e[0KInstalling pre packages"
- apt-get install apt-utils
- |
# apt_pre
echo -e "\e[0Ksection_end:`date +%s`:apt_pre\r\e[0K"
- - |
# apt_upgrade
echo -e "\e[0Ksection_start:`date +%s`:apt_upgrade[collapsed=true]\r\e[0KUpdating existing packages"
- apt-get upgrade
- |
# apt_update
echo -e "\e[0Ksection_end:`date +%s`:apt_upgrade\r\e[0K"
- - |
# apt_common
echo -e "\e[0Ksection_start:`date +%s`:apt_common[collapsed=true]\r\e[0KInstalling common packages"
- apt-get install make git ccache nasm
- |
# apt_common
echo -e "\e[0Ksection_end:`date +%s`:apt_common\r\e[0K"
- - |
# ccache_config
echo -e "\e[0Ksection_start:`date +%s`:ccache_config[collapsed=true]\r\e[0KSetting up ccache config"
- mkdir --parents --verbose ~/.ccache/
- touch ~/.ccache/ccache.conf
- |
# cache.conf
echo Adding ccache configution option
- |
# base_dir
echo base_dir = $PWD | tee --append ~/.ccache/ccache.conf
- |
# cache_dir
echo cache_dir = $PWD/ccache | tee --append ~/.ccache/ccache.conf
- |
# compiler_check
echo compiler_check = content | tee --append ~/.ccache/ccache.conf
- |
# stats_log
echo stats_log = $PWD/ccache_statslog | tee --append ~/.ccache/ccache.conf
- |
# max_size
echo max_size = 50M | tee --append ~/.ccache/ccache.conf
- |
# ccache_config
echo -e "\e[0Ksection_end:`date +%s`:ccache_config\r\e[0K"
- - |
# cache_reset
echo -e "\e[0Ksection_start:`date +%s`:ccache_reset[collapsed=true]\r\e[0KResetting ccache statistics"
- ccache --zero-stats
- ccache --show-stats
- |
# ccache_reset
echo -e "\e[0Ksection_end:`date +%s`:ccache_reset\r\e[0K"
artifacts:
paths:
- "bin/"
- "src/comptime.h"
name: "$CI_PROJECT_PATH_SLUG-$CI_COMMIT_REF_SLUG-$CI_COMMIT_SHORT_SHA-$CI_JOB_NAME_SLUG"
after_script:
- - |
# apt_clean
echo -e "\e[0Ksection_start:`date +%s`:apt_clean[collapsed=true]\r\e[0KCleaning of unneeded APT packages"
- apt-get autoclean
- |
# apt_clean
echo -e "\e[0Ksection_end:`date +%s`:apt_clean\r\e[0K"
- - |
# ccache_stats
echo -e "\e[0Ksection_start:`date +%s`:ccache_stats[collapsed=true]\r\e[0Kccache statistics:"
- ccache --show-stats --verbose
- ccache --show-log-stats --verbose
- |
# ccahe_stats
echo -e "\e[0Ksection_end:`date +%s`:ccache_stats\r\e[0K"
stages:
- build
Debian testing GCC:
stage: build
image: debian:testing-slim
allow_failure: true
artifacts:
name: "$CI_PROJECT_PATH_SLUG-$CI_COMMIT_REF_SLUG-$CI_COMMIT_SHORT_SHA-testing-gcc"
variables:
CC: gcc
LDFLAGS: -Wl,-fuse-ld=gold
script:
- - |
# apt_toolchain
echo -e "\e[0Ksection_start:`date +%s`:apt_toolchain[collapsed=true]\r\e[0KInstalling toolchain packages"
- apt-get install gcc
- |
# apt_toolchain
echo -e "\e[0Ksection_end:`date +%s`:apt_toolchain\r\e[0K"
- - |
# apt_development
echo -e "\e[0Ksection_start:`date +%s`:apt_development[collapsed=true]\r\e[0KInstalling development packages"
- apt-get install libsdl2-mixer-dev libpng-dev libcurl4-openssl-dev libgme-dev libopenmpt-dev
- |
# apt_development
echo -e "\e[0Ksection_end:`date +%s`:apt_development\r\e[0K"
- - |
# make
echo -e "\e[0Ksection_start:`date +%s`:make[collapsed=false]\r\e[0KCompiling SRB2"
- make --directory=src --keep-going CCACHE=1 ERRORMODE=1 NONX86=1 || make --directory=src --keep-going CCACHE=1 ERRORMODE=1 NONX86=1
- |
# make
echo -e "\e[0Ksection_end:`date +%s`:make\r\e[0K"
Windows x86:
stage: build
artifacts:
paths:
- "bin/"
- "src/comptime.h"
expose_as: "Win32"
name: "$CI_PROJECT_PATH_SLUG-$CI_COMMIT_REF_SLUG-$CI_COMMIT_SHORT_SHA-Win32"
variables:
PREFIX: i686-w64-mingw32
script:
- - |
# apt_toolchain
echo -e "\e[0Ksection_start:`date +%s`:apt_toolchain[collapsed=true]\r\e[0KInstalling toolchain packages"
- apt-get install gcc-mingw-w64-i686-win32
- |
# apt_toolchain
echo -e "\e[0Ksection_end:`date +%s`:apt_toolchain\r\e[0K"
- - |
# make
echo -e "\e[0Ksection_start:`date +%s`:make[collapsed=false]\r\e[0KCompiling SRB2"
- make --directory=src --keep-going CCACHE=1 ERRORMODE=1 MINGW=1 SDL=1 || make --directory=src --keep-going CCACHE=1 ERRORMODE=1 MINGW=1 SDL=1
- |
# make
echo -e "\e[0Ksection_end:`date +%s`:make\r\e[0K"
Debian stable:amd64:
stage: build
artifacts:
paths:
- "bin/"
- "src/comptime.h"
expose_as: "Debian amd64"
name: "$CI_PROJECT_PATH_SLUG-$CI_COMMIT_REF_SLUG-$CI_COMMIT_SHORT_SHA-x86-64"
variables:
CC: x86_64-linux-gnu-gcc
LDFLAGS: -Wl,-fuse-ld=gold
OBJCOPY: x86_64-linux-gnu-objcopy
OBJDUMP: x86_64-linux-gnu-objdump
PKG_CONFIG_PATH: /usr/lib/x86_64-linux-gnu/pkgconfig
script:
- - |
# apt_toolchain
echo -e "\e[0Ksection_start:`date +%s`:apt_toolchain[collapsed=true]\r\e[0KInstalling toolchain packages"
- apt-get install gcc-x86-64-linux-gnu || apt-get install gcc
- |
# apt_toolchain
echo -e "\e[0Ksection_end:`date +%s`:apt_toolchain\r\e[0K"
- - |
# apt_development
echo -e "\e[0Ksection_start:`date +%s`:apt_development[collapsed=true]\r\e[0KInstalling development packages"
- apt-get install libsdl2-mixer-dev:amd64 libpng-dev:amd64 libcurl4-openssl-dev:amd64 libgme-dev:amd64 libopenmpt-dev:amd64
- |
# apt_development
echo -e "\e[0Ksection_end:`date +%s`:apt_development\r\e[0K"
- - |
# make
echo -e "\e[0Ksection_start:`date +%s`:make[collapsed=false]\r\e[0KCompiling SRB2"
- make --directory=src --keep-going CCACHE=1 ERRORMODE=1 LINUX64=1 || make --directory=src --keep-going CCACHE=1 ERRORMODE=1 LINUX64=1
- |
# make
echo -e "\e[0Ksection_end:`date +%s`:make\r\e[0K"
Debian stable:i386:
stage: build
artifacts:
paths:
- "bin/"
- "src/comptime.h"
expose_as: "Debian i386"
name: "$CI_PROJECT_PATH_SLUG-$CI_COMMIT_REF_SLUG-$CI_COMMIT_SHORT_SHA-i686"
variables:
CC: i686-linux-gnu-gcc
OBJCOPY: i686-linux-gnu-objcopy
OBJDUMP: i686-linux-gnu-objdump
PKG_CONFIG_PATH: /usr/lib/i386-linux-gnu/pkgconfig
script:
- - |
# apt_toolchain
echo -e "\e[0Ksection_start:`date +%s`:apt_toolchain[collapsed=true]\r\e[0KInstalling toolchain packages"
- apt-get install gcc-i686-linux-gnu || apt-get install gcc
- |
# apt_toolchain
echo -e "\e[0Ksection_end:`date +%s`:apt_toolchain\r\e[0K"
- - |
# apt_development
echo -e "\e[0Ksection_start:`date +%s`:apt_development[collapsed=true]\r\e[0KInstalling development packages"
- apt-get install libsdl2-mixer-dev:i386 libpng-dev:i386 libcurl4-openssl-dev:i386 libgme-dev:i386 libopenmpt-dev:i386
- |
# apt_development
echo -e "\e[0Ksection_end:`date +%s`:apt_development\r\e[0K"
- - |
# make
echo -e "\e[0Ksection_start:`date +%s`:make[collapsed=false]\r\e[0KCompiling SRB2"
- make --directory=src --keep-going CCACHE=1 ERRORMODE=1 LINUX=1 || make --directory=src --keep-going CCACHE=1 ERRORMODE=1 LINUX=1
- |
# make
echo -e "\e[0Ksection_end:`date +%s`:make\r\e[0K"
Debian stable:arm64:
stage: build
artifacts:
paths:
- "bin/"
- "src/comptime.h"
expose_as: "Debian arm64"
name: "$CI_PROJECT_PATH_SLUG-$CI_COMMIT_REF_SLUG-$CI_COMMIT_SHORT_SHA-aarch64"
variables:
CC: aarch64-linux-gnu-gcc
LDFLAGS: -Wl,-fuse-ld=gold
OBJCOPY: aarch64-linux-gnu-objcopy
OBJDUMP: aarch64-linux-gnu-objdump
PKG_CONFIG_PATH: /usr/lib/aarch64-linux-gnu/pkgconfig
script:
- - |
# apt_toolchain
echo -e "\e[0Ksection_start:`date +%s`:apt_toolchain[collapsed=true]\r\e[0KInstalling toolchain packages"
- apt-get install gcc-aarch64-linux-gnu || apt-get install gcc
- |
# apt_toolchain
echo -e "\e[0Ksection_end:`date +%s`:apt_toolchain\r\e[0K"
- - |
# apt_development
echo -e "\e[0Ksection_start:`date +%s`:apt_development[collapsed=true]\r\e[0KInstalling development packages"
- apt-get install libsdl2-mixer-dev:arm64 libpng-dev:arm64 libcurl4-openssl-dev:arm64 libgme-dev:arm64 libopenmpt-dev:arm64
- |
# apt_development
echo -e "\e[0Ksection_end:`date +%s`:apt_development\r\e[0K"
- - |
# make
echo -e "\e[0Ksection_start:`date +%s`:make[collapsed=false]\r\e[0KCompiling SRB2"
- make --directory=src --keep-going CCACHE=1 ERRORMODE=1 LINUX64=1 ERRORMODE=1 NONX86=1 || make --directory=src --keep-going CCACHE=1 ERRORMODE=1 LINUX64=1 NONX86=1
- |
# make
echo -e "\e[0Ksection_end:`date +%s`:make\r\e[0K"
Windows x64:
stage: build
artifacts:
paths:
- "bin/"
- "src/comptime.h"
expose_as: "Win64"
name: "$CI_PROJECT_PATH_SLUG-$CI_COMMIT_REF_SLUG-$CI_COMMIT_SHORT_SHA-Win64"
variables:
PREFIX: x86_64-w64-mingw32
script:
- - |
# apt_toolchain
echo -e "\e[0Ksection_start:`date +%s`:apt_toolchain[collapsed=true]\r\e[0KInstalling toolchain packages"
- apt-get install gcc-mingw-w64-x86-64-win32
- |
# apt_toolchain
echo -e "\e[0Ksection_end:`date +%s`:apt_toolchain\r\e[0K"
- - |
# make
echo -e "\e[0Ksection_start:`date +%s`:make[collapsed=false]\r\e[0KCompiling SRB2"
- make --directory=src --keep-going CCACHE=1 ERRORMODE=1 MINGW64=1 SDL=1 || make --directory=src --keep-going CCACHE=1 ERRORMODE=1 MINGW64=1 SDL=1
- |
# make
echo -e "\e[0Ksection_end:`date +%s`:make\r\e[0K"
Debian stable Clang:
stage: build
allow_failure: true
artifacts:
name: "$CI_PROJECT_PATH_SLUG-$CI_COMMIT_REF_SLUG-$CI_COMMIT_SHORT_SHA-clang"
variables:
CC: clang
WFLAGS: -Wno-cast-align
CFLAGS: -Wno-cast-align
LDFLAGS: -Wl,-fuse-ld=gold
script:
- - |
# apt_toolchain
echo -e "\e[0Ksection_start:`date +%s`:apt_toolchain[collapsed=true]\r\e[0KInstalling toolchain packages"
- apt-get install clang
- |
# apt_toolchain
echo -e "\e[0Ksection_end:`date +%s`:apt_toolchain\r\e[0K"
- - |
# apt_development
echo -e "\e[0Ksection_start:`date +%s`:apt_development[collapsed=true]\r\e[0KInstalling development packages"
- apt-get install libsdl2-mixer-dev libpng-dev libcurl4-openssl-dev libgme-dev libopenmpt-dev
- |
# apt_development
echo -e "\e[0Ksection_end:`date +%s`:apt_development\r\e[0K"
- - |
# make
echo -e "\e[0Ksection_start:`date +%s`:make[collapsed=false]\r\e[0KCompiling SRB2"
- make --directory=src --keep-going CCACHE=1 ERRORMODE=1 NONX86=1 || make --directory=src --keep-going CCACHE=1 ERRORMODE=1 NONX86=1
- |
# make
echo -e "\e[0Ksection_end:`date +%s`:make\r\e[0K"
Debian testing Clang:
extends: Debian stable Clang
image: debian:testing-slim
artifacts:
name: "$CI_PROJECT_PATH_SLUG-$CI_COMMIT_REF_SLUG-$CI_COMMIT_SHORT_SHA-testing-clang"
variables:
CC: clang
WFLAGS: -Wno-cast-align -Wno-deprecated-non-prototype
CFLAGS: -Wno-cast-align -Wno-deprecated-non-prototype
LDFLAGS: -Wl,-fuse-ld=gold

View file

@ -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
View 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"
}
]
}

View file

@ -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)

View file

@ -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>

View file

@ -25,9 +25,6 @@
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(PlatformTarget)'=='x86'">
<ClCompile>
<PreprocessorDefinitions>USEASM;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<Link>
<ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
</Link>

View file

@ -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
View 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'

View file

@ -1,4 +1,4 @@
version: 2.2.11.{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

32
cmake/Comptime.cmake Normal file
View 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")

View file

@ -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)

View file

@ -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)

View file

@ -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)

View file

@ -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)
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()

View 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()

View file

@ -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

View file

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

View file

@ -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
@ -223,8 +94,16 @@ 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

View file

@ -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

View file

@ -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

View file

@ -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");
}

View file

@ -8,11 +8,7 @@ LOCAL_SRC_FILES := am_map.c \
command.c \
comptime.c \
console.c \
d_clisrv.c \
d_main.c \
d_net.c \
d_netcmd.c \
d_netfil.c \
dehacked.c \
f_finale.c \
f_wipe.c \
@ -20,7 +16,6 @@ LOCAL_SRC_FILES := am_map.c \
g_game.c \
g_input.c \
hu_stuff.c \
i_tcp.c \
info.c \
lzf.c \
m_argv.c \
@ -32,7 +27,6 @@ LOCAL_SRC_FILES := am_map.c \
m_queue.c \
m_random.c \
md5.c \
mserv.c \
p_ceilng.c \
p_enemy.c \
p_fab.c \
@ -61,6 +55,7 @@ LOCAL_SRC_FILES := am_map.c \
r_things.c \
s_sound.c \
screen.c \
snake.c \
sounds.c \
st_stuff.c \
string.c \
@ -76,7 +71,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

View file

@ -1,27 +1,149 @@
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}")
add_executable(SRB2SDL2 MACOSX_BUNDLE WIN32
comptime.c
md5.c
config.h.in
string.c
d_main.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
lzf.c
b_bot.c
u_list.c
snake.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.")
add_subdirectory(blua)
add_subdirectory(netcode)
# OS macros
if (UNIX)
@ -74,33 +196,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 +384,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 +427,11 @@ if("${CMAKE_SYSTEM_NAME}" STREQUAL Windows AND NOT "${SRB2_CONFIG_INTERNAL_LIBRA
COMMENT "Copying runtime DLLs"
)
endif()
# Setup clang-tidy
if(SRB2_CONFIG_ENABLE_CLANG_TIDY_C)
target_set_default_clang_tidy(SRB2SDL2 C "-*,clang-analyzer-*,-clang-analyzer-cplusplus-*")
endif()
if(SRB2_CONFIG_ENABLE_CLANG_TIDY_CXX)
target_set_default_clang_tidy(SRB2SDL2 CXX "-*,clang-analyzer-*,modernize-*")
endif()

View file

@ -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.
@ -64,7 +62,6 @@
#
# Netplay incompatible
# --------------------
# NONET=1 - Disable online capability.
# NOMD5=1 - Disable MD5 checksum (validation tool).
# NOPOSTPROCESSING=1 - ?
# MOBJCONSISTANCY=1 - ??
@ -88,7 +85,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 +140,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 +167,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:=
@ -208,6 +186,7 @@ objdir:=$(makedir)/objs
sources+=\
$(call List,Sourcefile)\
$(call List,blua/Sourcefile)\
$(call List,netcode/Sourcefile)\
depends:=$(basename $(filter %.c %.s,$(sources)))
objects:=$(basename $(filter %.c %.s %.nas,$(sources)))
@ -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.)

View file

@ -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))

View file

@ -3,7 +3,7 @@
#
passthru_opts+=\
NONET NO_IPV6 NOHW NOMD5 NOPOSTPROCESSING\
NO_IPV6 NOHW NOMD5 NOPOSTPROCESSING\
MOBJCONSISTANCY PACKETDROP ZDEBUG\
HAVE_MINIUPNPC\
@ -18,13 +18,6 @@ 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
@ -46,13 +39,11 @@ 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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -17,8 +17,6 @@ sources+=win32/Srb2win.rc
opts+=-DSTDC_HEADERS
libs+=-ladvapi32 -lkernel32 -lmsvcrt -luser32
nasm_format:=win32
SDL?=1
ifndef NOHW
@ -35,12 +33,10 @@ libs+=-lws2_32
endif
endif
ifndef NONET
ifndef MINGW64 # miniupnc is broken with MINGW64
opts+=-I../libs -DSTATIC_MINIUPNPC
libs+=-L../libs/miniupnpc/mingw$(32) -lws2_32 -liphlpapi
endif
endif
ifndef MINGW64
32=32

View file

@ -1,9 +1,5 @@
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
@ -64,6 +60,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
@ -76,12 +73,10 @@ s_sound.c
sounds.c
w_wad.c
filesrch.c
mserv.c
http-mserv.c
i_tcp.c
lzf.c
vid_copy.s
b_bot.c
u_list.c
snake.c
lua_script.c
lua_baselib.c
lua_mathlib.c

View file

@ -1071,7 +1071,6 @@ static inline void AM_drawPlayers(void)
return;
}
// multiplayer (how??)
for (i = 0; i < MAXPLAYERS; i++)
{
if (!playeringame[i] || players[i].spectator)

View file

@ -1,4 +1,4 @@
#include "../i_net.h"
#include "../netcode/i_net.h"
boolean I_InitNetwork(void)
{

View file

@ -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"

View file

@ -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

View file

@ -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;

View file

@ -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
)

View file

@ -23,3 +23,4 @@ lstring.c
ltable.c
ltm.c
lvm.c
loslib.c

View file

@ -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}
};

View file

@ -19,7 +19,8 @@
#include "lualib.h"
#include "../i_system.h"
#include "../g_game.h"
#include "../d_netfil.h"
#include "../netcode/d_netfil.h"
#include "../netcode/net_command.h"
#include "../lua_libs.h"
#include "../byteptr.h"
#include "../lua_script.h"

167
src/blua/loslib.c Normal file
View 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;
}

View file

@ -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);

View file

@ -28,11 +28,12 @@
#include "byteptr.h"
#include "p_saveg.h"
#include "g_game.h" // for player_names
#include "d_netcmd.h"
#include "netcode/d_netcmd.h"
#include "netcode/net_command.h"
#include "hu_stuff.h"
#include "p_setup.h"
#include "lua_script.h"
#include "d_netfil.h" // findfile
#include "netcode/d_netfil.h" // findfile
#include "r_data.h" // Color_cons_t
#include "d_main.h" // D_IsPathAllowed
@ -76,6 +77,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)
@ -680,25 +682,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
@ -710,8 +745,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.
@ -863,9 +898,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)
@ -1016,7 +1053,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;
@ -1507,12 +1544,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)

View file

@ -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;

View file

@ -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__;

View file

@ -13,6 +13,16 @@
#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
@ -28,12 +38,14 @@
* 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 "1c8adf8d079ecb87d00081f158acf3c7"
#define ASSET_HASH_PLAYER_DTA "2e7aaae8a6b1b77d90ffe7606ceadb6c"
#ifdef USE_PATCH_DTA
#define ASSET_HASH_PATCH_PK3 "2e69558bce3b9610624549a75e29e19b"
#define ASSET_HASH_PATCH_PK3 "3c7b73f34af7e9a7bceb2d5260f76172"
#endif
#endif

View file

@ -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
@ -126,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)
@ -181,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();
@ -477,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);
@ -792,9 +790,8 @@ void CON_Ticker(void)
// make overlay messages disappear after a while
for (i = 0; i < con_hudlines; i++)
{
if (con_hudtime[i])
con_hudtime[i]--;
if (con_hudtime[i] < 0)
con_hudtime[i] = 0;
}
Unlock_state();
@ -1343,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;
@ -1699,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)
@ -1707,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;
@ -1889,7 +1887,7 @@ void CON_Drawer(void)
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();

File diff suppressed because it is too large Load diff

View file

@ -34,7 +34,7 @@
#include "doomdef.h"
#include "am_map.h"
#include "console.h"
#include "d_net.h"
#include "netcode/d_net.h"
#include "f_finale.h"
#include "g_game.h"
#include "hu_stuff.h"
@ -56,11 +56,11 @@
#include "w_wad.h"
#include "z_zone.h"
#include "d_main.h"
#include "d_netfil.h"
#include "netcode/d_netfil.h"
#include "m_cheat.h"
#include "y_inter.h"
#include "p_local.h" // chasecam
#include "mserv.h" // ms_RoomId
#include "netcode/mserv.h" // ms_RoomId
#include "m_misc.h" // screenshot functionality
#include "deh_tables.h" // Dehacked list test
#include "m_cond.h" // condition initialization
@ -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;
@ -972,6 +981,7 @@ void D_StartTitle(void)
emeralds = 0;
memset(&luabanks, 0, sizeof(luabanks));
lastmaploaded = 0;
pickedchar = R_SkinAvailable(cv_defaultskin.string);
// In case someone exits out at the same time they start a time attack run,
// reset modeattacking
@ -1208,6 +1218,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 +1240,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 +1358,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());
@ -1356,6 +1381,8 @@ void D_SRB2Main(void)
// 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")))
@ -1600,6 +1627,8 @@ void D_SRB2Main(void)
autostart = true;
}
pickedchar = R_SkinAvailable(cv_defaultskin.string);
// user settings come before "+" parameters.
if (dedicated)
COM_ImmedExecute(va("exec \"%s"PATHSEP"adedserv.cfg\"\n", srb2home));
@ -1711,14 +1740,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, serverGamedata))
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);
}
}

View file

@ -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

View file

@ -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

View file

@ -187,25 +187,31 @@ 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 void CacheAndPushConstant(lua_State *L, const char *name, lua_Integer value)
@ -271,8 +277,8 @@ static int ScanConstants(lua_State *L, boolean mathlib, const char *word)
}
else if (fastncmp("MTF_", word, 4)) {
p = word+4;
for (i = 0; i < 4; i++)
if (MAPTHINGFLAG_LIST[i] && fastcmp(p, MAPTHINGFLAG_LIST[i])) {
for (i = 0; MAPTHINGFLAG_LIST[i]; i++)
if (fastcmp(p, MAPTHINGFLAG_LIST[i])) {
CacheAndPushConstant(L, word, ((lua_Integer)1<<i));
return 1;
}
@ -606,42 +612,62 @@ static inline int lib_getenum(lua_State *L)
if (!mathlib && fastncmp("A_",word,2)) {
char *caps;
// Try to get a Lua action first.
/// \todo Push a closure that sets superactions[] and superstack.
// 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
// 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)
if (!luaactionstack)
{
// Not in A_ action routine
lua_pushcfunction(L, lib_dummysuper);
return 1;
}
for (i = 0; actionpointers[i].name; i++)
if (fasticmp(superactions[superstack-1], actionpointers[i].name)) {
{
if (fasticmp(luaactions[luaactionstack-1], actionpointers[i].name))
{
LUA_PushUserdata(L, &actionpointers[i].action, META_ACTION);
return 1;
}
return 0;
}
// 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;

View file

@ -34,7 +34,7 @@
#include "r_sky.h"
#include "fastcmp.h"
#include "lua_script.h" // Reluctantly included for LUA_EvalMath
#include "d_clisrv.h"
#include "netcode/d_clisrv.h"
#ifdef HWRENDER
#include "hardware/hw_light.h"
@ -912,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;

View file

@ -35,7 +35,7 @@
#include "r_sky.h"
#include "fastcmp.h"
#include "lua_script.h" // Reluctantly included for LUA_EvalMath
#include "d_clisrv.h"
#include "netcode/d_clisrv.h"
#ifdef HWRENDER
#include "hardware/hw_light.h"

View file

@ -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,
"SEPIA", // SKINCOLOR_SEPIA,
"ECRU", // SKINCOLOR_ECRU,
"TAN", // SKINCOLOR_TAN,
"BEIGE", // SKINCOLOR_BEIGE,
"ROSEBUSH", // SKINCOLOR_ROSEBUSH,
"MOSS", // SKINCOLOR_MOSS,
"AZURE", // SKINCOLOR_AZURE,
"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,
"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[] = {
@ -4832,7 +4884,7 @@ const char *const MENUTYPES_LIST[] = {
"MP_SERVER",
"MP_CONNECT",
"MP_ROOM",
"MP_PLAYERSETUP", // MP_PlayerSetupDef shared with SPLITSCREEN if #defined NONET
"MP_PLAYERSETUP",
"MP_SERVER_OPTIONS",
// Options
@ -5122,6 +5174,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},

View file

@ -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

View file

@ -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

View file

@ -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;

View file

@ -56,7 +56,6 @@
#endif
#ifdef _WINDOWS
#define NONET
#if !defined (HWRENDER) && !defined (NOHW)
#define HWRENDER
#endif
@ -108,6 +107,14 @@ 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
@ -261,66 +268,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,
@ -592,7 +644,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
@ -662,7 +723,7 @@ extern const char *compdate, *comptime, *comprevision, *compbranch;
/// Maintain compatibility with older 2.2 demos
#define OLD22DEMOCOMPAT
#if defined (HAVE_CURL) && ! defined (NONET)
#ifdef HAVE_CURL
#define MASTERSERVER
#else
#undef UPDATE_ALERT

View file

@ -249,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
@ -633,7 +634,7 @@ extern boolean singletics;
// Netgame stuff
// =============
#include "d_clisrv.h"
#include "netcode/d_clisrv.h"
extern consvar_t cv_timetic; // display high resolution timer
extern consvar_t cv_powerupdisplay; // display powerups

View file

@ -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,34 +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
int startswith (const char *base, const char *tag);
int endswith (const char *base, const char *tag);
#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
#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
@ -129,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
@ -144,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__
//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
// 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
typedef enum {false, true} boolean;
#define boolean BOOL
#endif
#ifndef __cplusplus
#ifndef _WIN32
enum {false = 0, true = 1};
#else
#define false FALSE
#define true TRUE
#endif
#endif
#endif // __BYTEBOOL__
/* 7.18.2.1 Limits of exact-width integer types */
@ -387,4 +389,8 @@ unset_bit_array (bitarray_t * const array, const int value)
typedef UINT64 precise_t;
#ifdef __cplusplus
} // extern "C"
#endif
#endif //__DOOMTYPE__

View file

@ -1,4 +1,4 @@
#include "../i_net.h"
#include "../netcode/i_net.h"
boolean I_InitNetwork(void)
{

View file

@ -14,13 +14,18 @@ size_t I_GetFreeMem(size_t *total)
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,6 +185,13 @@ const char *I_ClipboardPaste(void)
return NULL;
}
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)

View file

@ -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){}

View file

@ -14,7 +14,7 @@
#include "doomdef.h"
#include "doomstat.h"
#include "d_main.h"
#include "d_netcmd.h"
#include "netcode/d_netcmd.h"
#include "f_finale.h"
#include "g_game.h"
#include "hu_stuff.h"
@ -224,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";
@ -240,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)
{
@ -1068,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\"",
@ -1096,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:
@ -1203,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
@ -1280,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++)
@ -1641,7 +1648,7 @@ void F_GameEvaluationTicker(void)
sparklloop = 0;
}
if (finalecount == 5*TICRATE)
if (G_CoopGametype() && !stagefailed && finalecount == 5*TICRATE)
{
serverGamedata->timesBeaten++;
clientGamedata->timesBeaten++;
@ -2253,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;
@ -3506,6 +3513,7 @@ void F_TitleScreenTicker(boolean run)
}
titledemo = true;
demofileoverride = DFILE_OVERRIDE_NONE;
G_DoPlayDemo(dname);
}
}
@ -4666,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);
}

View file

@ -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;

View file

@ -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;

View file

@ -26,7 +26,7 @@
#include <string.h>
#include "filesrch.h"
#include "d_netfil.h"
#include "netcode/d_netfil.h"
#include "m_misc.h"
#include "z_zone.h"
#include "m_menu.h" // Addons_option_Onchange

View file

@ -5,7 +5,7 @@
#define __FILESRCH_H__
#include "doomdef.h"
#include "d_netfil.h"
#include "netcode/d_netfil.h"
#include "m_menu.h" // MAXSTRINGLENGTH
#include "w_wad.h"

View file

@ -15,7 +15,7 @@
#include "console.h"
#include "d_main.h"
#include "d_player.h"
#include "d_clisrv.h"
#include "netcode/d_clisrv.h"
#include "p_setup.h"
#include "i_time.h"
#include "i_system.h"
@ -39,6 +39,7 @@
#include "v_video.h"
#include "lua_hook.h"
#include "md5.h" // demo checksums
#include "netcode/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,6 +1442,26 @@ 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
@ -1473,8 +1500,12 @@ void G_BeginRecording(void)
demo_p += 16;
// Color
for (i = 0; i < MAXCOLORNAME && cv_playercolor.string[i]; i++)
name[i] = cv_playercolor.string[i];
UINT16 skincolor = players[0].skincolor;
if (skincolor >= numskincolors)
skincolor = SKINCOLOR_NONE;
const char *skincolor_name = skincolors[skincolor].name;
for (i = 0; i < MAXCOLORNAME && skincolor_name[i]; i++)
name[i] = skincolor_name[i];
for (; i < MAXCOLORNAME; i++)
name[i] = '\0';
M_Memcpy(demo_p,name,MAXCOLORNAME);
@ -1483,18 +1514,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 +1621,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 +1826,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 +1844,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)
@ -1684,15 +1891,9 @@ UINT8 G_CmpDemoTime(char *oldname, char *newname)
p++; // VERSION
p++; // SUBVERSION
oldversion = READUINT16(p);
switch(oldversion) // demoversion
if (oldversion < 0x000c || oldversion > DEMOVERSION)
{
case DEMOVERSION: // latest always supported
case 0x000e: // The previous demoversions also supported
case 0x000d: // all that changed between then and now was longer color name
case 0x000c:
break;
// too old, cannot support.
default:
// too old (or new), cannot support
CONS_Alert(CONS_NOTICE, M_GetText("File '%s' invalid format. It will be overwritten.\n"), oldname);
Z_Free(buffer);
return UINT8_MAX;
@ -1710,6 +1911,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);
@ -1764,14 +1966,11 @@ void G_DoPlayDemo(char *defdemoname)
UINT8 i;
lumpnum_t l;
char skin[17],color[MAXCOLORNAME+1],*n,*pdemoname;
UINT8 version,subversion,charability,charability2,thrustfactor,accelstart,acceleration,cnamelen;
UINT8 version,subversion,charability,charability2,thrustfactor,accelstart,acceleration;
pflags_t pflags;
UINT32 randseed, followitem;
fixed_t camerascale,shieldscale,actionspd,mindash,maxdash,normalspeed,runspeed,jumpfactor,height,spinheight;
char msg[1024];
#ifdef OLD22DEMOCOMPAT
boolean use_old_demo_vars = false;
#endif
skin[16] = '\0';
color[MAXCOLORNAME] = '\0';
@ -1829,22 +2028,14 @@ void G_DoPlayDemo(char *defdemoname)
version = READUINT8(demo_p);
subversion = READUINT8(demo_p);
demoversion = READUINT16(demo_p);
switch(demoversion)
{
case 0x000d:
case 0x000e:
case DEMOVERSION: // latest always supported
cnamelen = MAXCOLORNAME;
break;
demo_forwardmove_rng = (demoversion < 0x0010);
#ifdef OLD22DEMOCOMPAT
// all that changed between then and now was longer color name
case 0x000c:
cnamelen = 16;
use_old_demo_vars = true;
break;
if (demoversion < 0x000c || demoversion > DEMOVERSION)
#else
if (demoversion < 0x000d || demoversion > DEMOVERSION)
#endif
// too old, cannot support.
default:
{
// too old (or new), cannot support
snprintf(msg, 1024, M_GetText("%s is an incompatible replay format and cannot be played.\n"), pdemoname);
CONS_Alert(CONS_ERROR, "%s", msg);
M_StartMessage(msg, NULL, MM_NOTHING);
@ -1871,6 +2062,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();
@ -1908,23 +2162,23 @@ void G_DoPlayDemo(char *defdemoname)
demo_p += 16;
// Color
M_Memcpy(color,demo_p,cnamelen);
demo_p += cnamelen;
M_Memcpy(color, demo_p, (demoversion < 0x000d) ? 16 : MAXCOLORNAME);
demo_p += (demoversion < 0x000d) ? 16 : MAXCOLORNAME;
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);
@ -1945,7 +2199,7 @@ void G_DoPlayDemo(char *defdemoname)
// net var data
#ifdef OLD22DEMOCOMPAT
if (use_old_demo_vars)
if (demoversion < 0x000d)
CV_LoadOldDemoVars(&demo_p);
else
#endif
@ -1993,7 +2247,6 @@ void G_DoPlayDemo(char *defdemoname)
players[0].skincolor = i;
break;
}
CV_StealthSetValue(&cv_playercolor, players[0].skincolor);
if (players[0].mo)
{
players[0].mo->color = players[0].skincolor;
@ -2026,12 +2279,87 @@ 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);
#ifdef OLD22DEMOCOMPAT
if (our_demo_version < 0x000c || our_demo_version > DEMOVERSION)
#else
if (our_demo_version < 0x000d || our_demo_version > DEMOVERSION)
#endif
{
// too old (or new), cannot support
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;
lumpnum_t l;
char name[17],skin[17],color[MAXCOLORNAME+1],*n,*pdemoname,md5[16];
UINT8 cnamelen;
demoghost *gh;
UINT8 flags, subversion;
UINT8 *buffer,*p;
@ -2083,19 +2411,9 @@ void G_AddGhost(char *defdemoname)
p++; // VERSION
subversion = READUINT8(p); // SUBVERSION
ghostversion = READUINT16(p);
switch(ghostversion)
if (ghostversion < 0x000c || ghostversion > DEMOVERSION)
{
case 0x000d:
case 0x000e:
case DEMOVERSION: // latest always supported
cnamelen = MAXCOLORNAME;
break;
// all that changed between then and now was longer color name
case 0x000c:
cnamelen = 16;
break;
// too old, cannot support.
default:
// too old (or new), cannot support
CONS_Alert(CONS_NOTICE, M_GetText("Ghost %s: Demo version incompatible.\n"), pdemoname);
Z_Free(pdemoname);
Z_Free(buffer);
@ -2130,6 +2448,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
@ -2155,23 +2476,18 @@ void G_AddGhost(char *defdemoname)
p += 16;
// Color
M_Memcpy(color, p,cnamelen);
p += cnamelen;
M_Memcpy(color, p, (ghostversion < 0x000d) ? 16 : MAXCOLORNAME);
p += (ghostversion < 0x000d) ? 16 : MAXCOLORNAME;
// 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
@ -2344,15 +2660,9 @@ void G_DoPlayMetal(void)
metal_p++; // VERSION
metal_p++; // SUBVERSION
metalversion = READUINT16(metal_p);
switch(metalversion)
if (metalversion < 0x000c || metalversion > DEMOVERSION)
{
case DEMOVERSION: // latest always supported
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:
break;
// too old, cannot support.
default:
// too old (or new), cannot support
CONS_Alert(CONS_WARNING, M_GetText("Failed to load bot recording for this map, format version incompatible.\n"));
Z_Free(metalbuffer);
return;

View file

@ -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__

View file

@ -15,7 +15,8 @@
#include "console.h"
#include "d_main.h"
#include "d_player.h"
#include "d_clisrv.h"
#include "netcode/d_clisrv.h"
#include "netcode/net_command.h"
#include "f_finale.h"
#include "p_setup.h"
#include "p_saveg.h"
@ -55,6 +56,8 @@ gameaction_t gameaction;
gamestate_t gamestate = GS_NULL;
UINT8 ultimatemode = false;
INT32 pickedchar;
boolean botingame;
UINT8 botskin;
UINT16 botcolor;
@ -156,6 +159,7 @@ textprompt_t *textprompts[MAX_PROMPTS];
INT16 nextmapoverride;
UINT8 skipstats;
INT16 nextgametype = -1;
// Pointers to each CTF flag
mobj_t *redflag;
@ -315,6 +319,8 @@ consvar_t cv_consolechat = CVAR_INIT ("chatmode", "Window", CV_SAVE, consolechat
// Pause game upon window losing focus
consvar_t cv_pauseifunfocused = CVAR_INIT ("pauseifunfocused", "Yes", CV_SAVE, CV_YesNo, NULL);
consvar_t cv_instantretry = CVAR_INIT ("instantretry", "No", CV_SAVE, CV_YesNo, NULL);
consvar_t cv_crosshair = CVAR_INIT ("crosshair", "Cross", CV_SAVE, crosshair_cons_t, NULL);
consvar_t cv_crosshair2 = CVAR_INIT ("crosshair2", "Cross", CV_SAVE, crosshair_cons_t, NULL);
consvar_t cv_invertmouse = CVAR_INIT ("invertmouse", "Off", CV_SAVE, CV_OnOff, NULL);
@ -519,48 +525,57 @@ UINT8 G_GetBestNightsGrade(INT16 map, UINT8 mare, gamedata_t *data)
}
// For easy adding of NiGHTS records
void G_AddTempNightsRecords(UINT32 pscore, tic_t ptime, UINT8 mare)
void G_AddTempNightsRecords(player_t *player, UINT32 pscore, tic_t ptime, UINT8 mare)
{
ntemprecords.score[mare] = pscore;
ntemprecords.grade[mare] = P_GetGrade(pscore, gamemap, mare - 1);
ntemprecords.time[mare] = ptime;
const UINT8 playerID = player - players;
I_Assert(player != NULL);
ntemprecords[playerID].score[mare] = pscore;
ntemprecords[playerID].grade[mare] = P_GetGrade(pscore, gamemap, mare - 1);
ntemprecords[playerID].time[mare] = ptime;
// Update nummares
// Note that mare "0" is overall, mare "1" is the first real mare
if (ntemprecords.nummares < mare)
ntemprecords.nummares = mare;
if (ntemprecords[playerID].nummares < mare)
ntemprecords[playerID].nummares = mare;
}
//
// G_UpdateRecordReplays
// G_SetMainRecords
//
// Update replay files/data, etc. for Record Attack
// See G_SetNightsRecords for NiGHTS Attack.
//
static void G_UpdateRecordReplays(gamedata_t *data)
static void G_SetMainRecords(gamedata_t *data, player_t *player)
{
const size_t glen = strlen(srb2home)+1+strlen("replay")+1+strlen(timeattackfolder)+1+strlen("MAPXX")+1;
char *gpath;
char lastdemo[256], bestdemo[256];
UINT8 earnedEmblems;
I_Assert(player != NULL);
// Record new best time
if (!data->mainrecords[gamemap-1])
G_AllocMainRecordData(gamemap-1, data);
if (players[consoleplayer].score > data->mainrecords[gamemap-1]->score)
data->mainrecords[gamemap-1]->score = players[consoleplayer].score;
if (player->recordscore > data->mainrecords[gamemap-1]->score)
data->mainrecords[gamemap-1]->score = player->recordscore;
if ((data->mainrecords[gamemap-1]->time == 0) || (players[consoleplayer].realtime < data->mainrecords[gamemap-1]->time))
data->mainrecords[gamemap-1]->time = players[consoleplayer].realtime;
if ((data->mainrecords[gamemap-1]->time == 0) || (player->realtime < data->mainrecords[gamemap-1]->time))
data->mainrecords[gamemap-1]->time = player->realtime;
if ((UINT16)(players[consoleplayer].rings) > data->mainrecords[gamemap-1]->rings)
data->mainrecords[gamemap-1]->rings = (UINT16)(players[consoleplayer].rings);
if ((UINT16)(player->rings) > data->mainrecords[gamemap-1]->rings)
data->mainrecords[gamemap-1]->rings = (UINT16)(player->rings);
if (modeattacking)
{
const size_t glen = strlen(srb2home)+1+strlen("replay")+1+strlen(timeattackfolder)+1+strlen("MAPXX")+1;
char *gpath;
char lastdemo[256], bestdemo[256];
// Save demo!
bestdemo[255] = '\0';
lastdemo[255] = '\0';
G_SetDemoTime(players[consoleplayer].realtime, players[consoleplayer].score, (UINT16)(players[consoleplayer].rings));
G_SetDemoTime(player->realtime, player->recordscore, (UINT16)(player->rings));
G_CheckDemoStatus();
I_mkdir(va("%s"PATHSEP"replay", srb2home), 0755);
@ -609,50 +624,55 @@ static void G_UpdateRecordReplays(gamedata_t *data)
Z_Free(buf);
}
free(gpath);
}
// Check emblems when level data is updated
if ((earnedEmblems = M_CheckLevelEmblems(data)))
{
CONS_Printf(M_GetText("\x82" "Earned %hu emblem%s for Record Attack records.\n"), (UINT16)earnedEmblems, earnedEmblems > 1 ? "s" : "");
}
// Update timeattack menu's replay availability.
Nextmap_OnChange();
}
void G_SetNightsRecords(gamedata_t *data)
static void G_SetNightsRecords(gamedata_t *data, player_t *player)
{
INT32 i;
nightsdata_t *const ntemprecord = &ntemprecords[player - players];
UINT32 totalscore = 0;
tic_t totaltime = 0;
INT32 i;
UINT8 earnedEmblems;
const size_t glen = strlen(srb2home)+1+strlen("replay")+1+strlen(timeattackfolder)+1+strlen("MAPXX")+1;
char *gpath;
char lastdemo[256], bestdemo[256];
if (!ntemprecords.nummares)
if (!ntemprecord->nummares)
{
return;
}
// Set overall
{
UINT8 totalrank = 0, realrank = 0;
for (i = 1; i <= ntemprecords.nummares; ++i)
for (i = 1; i <= ntemprecord->nummares; ++i)
{
totalscore += ntemprecords.score[i];
totalrank += ntemprecords.grade[i];
totaltime += ntemprecords.time[i];
totalscore += ntemprecord->score[i];
totalrank += ntemprecord->grade[i];
totaltime += ntemprecord->time[i];
}
// Determine overall grade
realrank = (UINT8)((FixedDiv((fixed_t)totalrank << FRACBITS, ntemprecords.nummares << FRACBITS) + (FRACUNIT/2)) >> FRACBITS);
realrank = (UINT8)((FixedDiv((fixed_t)totalrank << FRACBITS, ntemprecord->nummares << FRACBITS) + (FRACUNIT/2)) >> FRACBITS);
// You need ALL rainbow As to get a rainbow A overall
if (realrank == GRADE_S && (totalrank / ntemprecords.nummares) != GRADE_S)
if (realrank == GRADE_S && (totalrank / ntemprecord->nummares) != GRADE_S)
{
realrank = GRADE_A;
}
ntemprecords.score[0] = totalscore;
ntemprecords.grade[0] = realrank;
ntemprecords.time[0] = totaltime;
ntemprecord->score[0] = totalscore;
ntemprecord->grade[0] = realrank;
ntemprecord->time[0] = totaltime;
}
// Now take all temp records and put them in the actual records
@ -660,24 +680,35 @@ void G_SetNightsRecords(gamedata_t *data)
nightsdata_t *maprecords;
if (!data->nightsrecords[gamemap-1])
{
G_AllocNightsRecordData(gamemap-1, data);
}
maprecords = data->nightsrecords[gamemap-1];
if (maprecords->nummares != ntemprecords.nummares)
maprecords->nummares = ntemprecords.nummares;
for (i = 0; i < ntemprecords.nummares + 1; ++i)
if (maprecords->nummares != ntemprecord->nummares)
{
if (maprecords->score[i] < ntemprecords.score[i])
maprecords->score[i] = ntemprecords.score[i];
if (maprecords->grade[i] < ntemprecords.grade[i])
maprecords->grade[i] = ntemprecords.grade[i];
if (!maprecords->time[i] || maprecords->time[i] > ntemprecords.time[i])
maprecords->time[i] = ntemprecords.time[i];
maprecords->nummares = ntemprecord->nummares;
}
for (i = 0; i < ntemprecord->nummares + 1; ++i)
{
if (maprecords->score[i] < ntemprecord->score[i])
maprecords->score[i] = ntemprecord->score[i];
if (maprecords->grade[i] < ntemprecord->grade[i])
maprecords->grade[i] = ntemprecord->grade[i];
if (!maprecords->time[i] || maprecords->time[i] > ntemprecord->time[i])
maprecords->time[i] = ntemprecord->time[i];
}
}
memset(&ntemprecords, 0, sizeof(nightsdata_t));
memset(&ntemprecords[player - players], 0, sizeof(nightsdata_t));
if (modeattacking)
{
const size_t glen = strlen(srb2home)+1+strlen("replay")+1+strlen(timeattackfolder)+1+strlen("MAPXX")+1;
char *gpath;
char lastdemo[256], bestdemo[256];
// Save demo!
bestdemo[255] = '\0';
@ -722,9 +753,12 @@ void G_SetNightsRecords(gamedata_t *data)
Z_Free(buf);
}
free(gpath);
}
if ((earnedEmblems = M_CheckLevelEmblems(data)))
{
CONS_Printf(M_GetText("\x82" "Earned %hu emblem%s for NiGHTS records.\n"), (UINT16)earnedEmblems, earnedEmblems > 1 ? "s" : "");
}
// If the mare count changed, this will update the score display
Nextmap_OnChange();
@ -1413,6 +1447,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer)
// I assume this is netgame-safe because gunslinger spawns this for only the local player...... *sweats intensely*
newtarget = P_SpawnMobj(ticcmd_ztargetfocus[forplayer]->x, ticcmd_ztargetfocus[forplayer]->y, ticcmd_ztargetfocus[forplayer]->z, MT_LOCKON); // positioning, flip handled in P_SceneryThinker
P_SetTarget(&newtarget->target, ticcmd_ztargetfocus[forplayer]);
newtarget->drawonlyforplayer = player; // Hide it from the other player in splitscreen, and yourself when spectating
if (player->mo && P_AproxDistance(
player->mo->x - ticcmd_ztargetfocus[forplayer]->x,
@ -1915,6 +1950,7 @@ void G_PreLevelTitleCard(void)
ST_runTitleCard();
ST_preLevelTitleCardDrawer();
I_FinishUpdate(); // page flip or blit buffer
NetKeepAlive(); // Prevent timeouts
if (moviemode)
M_SaveFrame();
@ -2049,7 +2085,7 @@ boolean G_Responder(event_t *ev)
if (gameaction == ga_nothing && !singledemo &&
((demoplayback && !modeattacking && !titledemo) || gamestate == GS_TITLESCREEN))
{
if (ev->type == ev_keydown && ev->key != 301 && !(gamestate == GS_TITLESCREEN && finalecount < TICRATE))
if (ev->type == ev_keydown && ev->key != 301 && !(gamestate == GS_TITLESCREEN && finalecount < (cv_tutorialprompt.value ? TICRATE : 0)))
{
M_StartControlPanel();
return true;
@ -2107,7 +2143,7 @@ boolean G_Responder(event_t *ev)
if (! netgame)
F_StartGameEvaluation();
else if (server || IsPlayerAdmin(consoleplayer))
SendNetXCmd(XD_EXITLEVEL, NULL, 0);
D_SendExitLevel(false);
return true;
}
}
@ -2142,9 +2178,9 @@ boolean G_Responder(event_t *ev)
if (menuactive || pausedelay < 0 || leveltime < 2)
return true;
if (pausedelay < 1+(NEWTICRATE/2))
if (!cv_instantretry.value && pausedelay < 1+(NEWTICRATE/2))
pausedelay = 1+(NEWTICRATE/2);
else if (++pausedelay > 1+(NEWTICRATE/2)+(NEWTICRATE/3))
else if (cv_instantretry.value || ++pausedelay > 1+(NEWTICRATE/2)+(NEWTICRATE/3))
{
G_SetModeAttackRetryFlag();
return true;
@ -2287,7 +2323,7 @@ void G_Ticker(boolean run)
p->lives = startinglivesbalance[0];
p->continues = 1;
p->score = 0;
p->score = p->recordscore = 0;
// The latter two should clear by themselves, but just in case
p->pflags &= ~(PF_TAGIT|PF_GAMETYPEOVER|PF_FULLSTASIS);
@ -2437,14 +2473,17 @@ void G_Ticker(boolean run)
case GS_TITLESCREEN:
if (titlemapinaction)
P_Ticker(run);
// then intentionally fall through
/* FALLTHRU */
case GS_WAITINGPLAYERS:
if (run)
F_MenuPresTicker();
F_TitleScreenTicker(run);
break;
case GS_WAITINGPLAYERS:
if (netgame)
F_WaitingPlayersTicker();
HU_Ticker();
break;
case GS_DEDICATEDSERVER:
case GS_NULL:
break; // do nothing
@ -2715,25 +2754,6 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
//if ((netgame || multiplayer) && !p->spectator) -- moved into P_SpawnPlayer to account for forced changes there
//p->powers[pw_flashing] = flashingtics-1; // Babysitting deterrent
// Check to make sure their color didn't change somehow...
if (G_GametypeHasTeams())
{
if (p->ctfteam == 1 && p->skincolor != skincolor_redteam)
{
if (p == &players[consoleplayer])
CV_SetValue(&cv_playercolor, skincolor_redteam);
else if (p == &players[secondarydisplayplayer])
CV_SetValue(&cv_playercolor2, skincolor_redteam);
}
else if (p->ctfteam == 2 && p->skincolor != skincolor_blueteam)
{
if (p == &players[consoleplayer])
CV_SetValue(&cv_playercolor, skincolor_blueteam);
else if (p == &players[secondarydisplayplayer])
CV_SetValue(&cv_playercolor2, skincolor_blueteam);
}
}
if (betweenmaps)
return;
@ -3165,6 +3185,7 @@ void G_DoReborn(INT32 playernum)
{
if (!playeringame[i])
continue;
players[i].recordscore = 0;
players[i].starpostscale = 0;
players[i].starpostangle = 0;
players[i].starposttime = 0;
@ -3427,9 +3448,7 @@ UINT32 gametypedefaultrules[NUMGAMETYPES] =
};
//
// G_SetGametype
//
// Set a new gametype, also setting gametype rules accordingly. Yay!
// Sets a new gametype.
//
void G_SetGametype(INT16 gtype)
{
@ -3827,7 +3846,7 @@ static INT16 RandMap(UINT32 tolflags, INT16 pprevmap)
for (ix = 0; ix < NUMMAPS; ix++)
if (mapheaderinfo[ix] && (mapheaderinfo[ix]->typeoflevel & tolflags) == tolflags
&& ix != pprevmap // Don't pick the same map.
&& (dedicated || !M_MapLocked(ix+1, serverGamedata)) // Don't pick locked maps.
&& (!M_MapLocked(ix+1, serverGamedata)) // Don't pick locked maps.
)
okmaps[numokmaps++] = ix;
@ -3844,15 +3863,16 @@ static INT16 RandMap(UINT32 tolflags, INT16 pprevmap)
//
// G_UpdateVisited
//
static void G_UpdateVisited(gamedata_t *data, boolean silent)
static void G_UpdateVisited(gamedata_t *data, player_t *player, boolean silent)
{
boolean spec = G_IsSpecialStage(gamemap);
// Update visitation flags?
if (!demoplayback
&& G_CoopGametype() // Campaign mode
&& !stagefailed) // Did not fail the stage
{
UINT8 earnedEmblems;
UINT16 totalrings = 0;
INT32 i;
// Update visitation flags
data->mapvisited[gamemap-1] |= MV_BEATEN;
@ -3861,36 +3881,62 @@ static void G_UpdateVisited(gamedata_t *data, boolean silent)
if (ultimatemode)
data->mapvisited[gamemap-1] |= MV_ULTIMATE;
for (i = 0; i < MAXPLAYERS; i++)
{
if (!playeringame[i])
{
continue;
}
totalrings += players[i].rings;
}
// may seem incorrect but IS possible in what the main game uses as mp special stages, and nummaprings will be -1 in NiGHTS
if (nummaprings > 0 && players[consoleplayer].rings >= nummaprings)
if (nummaprings > 0 && totalrings >= nummaprings)
{
data->mapvisited[gamemap-1] |= MV_PERFECT;
if (modeattacking)
data->mapvisited[gamemap-1] |= MV_PERFECTRA;
}
if (!spec)
if (!G_IsSpecialStage(gamemap))
{
// not available to special stages because they can only really be done in one order in an unmodified game, so impossible for first six and trivial for seventh
if (ALL7EMERALDS(emeralds))
data->mapvisited[gamemap-1] |= MV_ALLEMERALDS;
}
if ((earnedEmblems = M_CompletionEmblems(data)) && !silent)
{
CONS_Printf(M_GetText("\x82" "Earned %hu emblem%s for level completion.\n"), (UINT16)earnedEmblems, earnedEmblems > 1 ? "s" : "");
}
if (silent)
{
if (modeattacking)
M_CheckLevelEmblems(data);
}
else
{
if (modeattacking == ATTACKING_RECORD)
G_UpdateRecordReplays(data);
else if (modeattacking == ATTACKING_NIGHTS)
G_SetNightsRecords(data);
if (mapheaderinfo[gamemap-1]->menuflags & LF2_RECORDATTACK)
G_SetMainRecords(data, player);
else if (mapheaderinfo[gamemap-1]->menuflags & LF2_NIGHTSATTACK)
G_SetNightsRecords(data, player);
}
}
}
if ((earnedEmblems = M_CompletionEmblems(data)) && !silent)
CONS_Printf(M_GetText("\x82" "Earned %hu emblem%s for level completion.\n"), (UINT16)earnedEmblems, earnedEmblems > 1 ? "s" : "");
static void G_UpdateAllVisited(void)
{
// Update server
G_UpdateVisited(serverGamedata, &players[serverplayer], true);
// Update client
G_UpdateVisited(clientGamedata, &players[consoleplayer], false);
if (splitscreen)
{
// Allow P2 to get emblems too, why not :)
G_UpdateVisited(clientGamedata, &players[secondarydisplayplayer], false);
}
}
@ -3914,6 +3960,9 @@ static boolean CanSaveLevel(INT32 mapnum)
static void G_HandleSaveLevel(void)
{
// Update records & emblems
G_UpdateAllVisited();
// do this before running the intermission or custom cutscene, mostly for the sake of marathon mode but it also massively reduces redundant file save events in f_finale.c
if (nextmap >= 1100-1)
{
@ -3989,6 +4038,13 @@ static void G_DoCompleted(void)
nextmap = 1100-1; // No infinite loop for you
}
INT16 gametype_to_use;
if (nextgametype >= 0 && nextgametype < gametypecount)
gametype_to_use = nextgametype;
else
gametype_to_use = gametype;
// If nextmap is actually going to get used, make sure it points to
// a map of the proper gametype -- skip levels that don't support
// the current gametype. (Helps avoid playing boss levels in Race,
@ -3997,8 +4053,8 @@ static void G_DoCompleted(void)
{
if (nextmap >= 0 && nextmap < NUMMAPS)
{
register INT16 cm = nextmap;
UINT32 tolflag = G_TOLFlag(gametype);
INT16 cm = nextmap;
UINT32 tolflag = G_TOLFlag(gametype_to_use);
UINT8 visitedmap[(NUMMAPS+7)/8];
memset(visitedmap, 0, sizeof (visitedmap));
@ -4053,7 +4109,7 @@ static void G_DoCompleted(void)
{
token--;
if (!nextmapoverride)
// if (!nextmapoverride) // Having a token should pull the player into the special stage before going to the overridden map (Issue #933)
for (i = 0; i < 7; i++)
if (!(emeralds & (1<<i)))
{
@ -4078,7 +4134,7 @@ static void G_DoCompleted(void)
if (cv_advancemap.value == 0) // Stay on same map.
nextmap = prevmap;
else if (cv_advancemap.value == 2) // Go to random map.
nextmap = RandMap(G_TOLFlag(gametype), prevmap);
nextmap = RandMap(G_TOLFlag(gametype_to_use), prevmap);
}
// We are committed to this map now.
@ -4087,13 +4143,10 @@ static void G_DoCompleted(void)
if (nextmap < NUMMAPS && !mapheaderinfo[nextmap])
P_AllocMapHeader(nextmap);
// If the current gametype has no intermission screen set, then don't start it.
Y_DetermineIntermissionType();
if ((skipstats && !modeattacking) || (modeattacking && stagefailed) || (intertype == int_none))
{
G_UpdateVisited(serverGamedata, true);
G_UpdateVisited(clientGamedata, false);
G_HandleSaveLevel();
G_AfterIntermission();
}
@ -4102,8 +4155,6 @@ static void G_DoCompleted(void)
G_SetGamestate(GS_INTERMISSION);
Y_StartIntermission();
Y_LoadIntermissionData();
G_UpdateVisited(serverGamedata, true);
G_UpdateVisited(clientGamedata, false);
G_HandleSaveLevel();
}
}
@ -4157,12 +4208,21 @@ static void G_DoWorldDone(void)
{
if (server)
{
INT16 gametype_to_use;
if (nextgametype >= 0 && nextgametype < gametypecount)
gametype_to_use = nextgametype;
else
gametype_to_use = gametype;
if (gametyperules & GTR_CAMPAIGN)
// don't reset player between maps
D_MapChange(nextmap+1, gametype, ultimatemode, false, 0, false, false);
D_MapChange(nextmap+1, gametype_to_use, ultimatemode, false, 0, false, false);
else
// resetplayer in match/chaos/tag/CTF/race for more equality
D_MapChange(nextmap+1, gametype, ultimatemode, true, 0, false, false);
D_MapChange(nextmap+1, gametype_to_use, ultimatemode, true, 0, false, false);
nextgametype = -1;
}
gameaction = ga_nothing;
@ -4205,7 +4265,7 @@ static void G_DoContinued(void)
{
player_t *pl = &players[consoleplayer];
I_Assert(!netgame && !multiplayer);
I_Assert(pl->continues > 0);
//I_Assert(pl->continues > 0);
if (pl->continues)
pl->continues--;
@ -4309,6 +4369,12 @@ void G_LoadGameData(gamedata_t *data)
// Stop saving, until we successfully load it again.
data->loaded = false;
// Backwards compat stuff
INT32 max_emblems = MAXEMBLEMS;
INT32 max_extraemblems = MAXEXTRAEMBLEMS;
INT32 max_unlockables = MAXUNLOCKABLES;
INT32 max_conditionsets = MAXCONDITIONSETS;
// Clear things so previously read gamedata doesn't transfer
// to new gamedata
G_ClearRecords(data); // main and nights records
@ -4355,6 +4421,14 @@ void G_LoadGameData(gamedata_t *data)
I_Error("Game data is from another version of SRB2.\nDelete %s(maybe in %s) and try again.", gamedatafilename, gdfolder);
}
#ifdef COMPAT_GAMEDATA_ID // Account for lower MAXUNLOCKABLES and MAXEXTRAEMBLEMS from older versions
if (versionID == COMPAT_GAMEDATA_ID)
{
max_extraemblems = 16;
max_unlockables = 32;
}
#endif
data->totalplaytime = READUINT32(save_p);
#ifdef COMPAT_GAMEDATA_ID
@ -4372,6 +4446,17 @@ void G_LoadGameData(gamedata_t *data)
{
goto datacorrupt;
}
// make a backup of the old data
char currentfilename[64];
char backupfilename[69];
char bak[5];
strcpy(bak, ".bak");
strcpy(currentfilename, gamedatafilename);
STRBUFCPY(backupfilename, strcat(currentfilename, bak));
FIL_WriteFile(va(pandf, srb2home, backupfilename), savebuffer, length);
}
else
#endif
@ -4393,31 +4478,31 @@ void G_LoadGameData(gamedata_t *data)
goto datacorrupt;
// To save space, use one bit per collected/achieved/unlocked flag
for (i = 0; i < MAXEMBLEMS;)
for (i = 0; i < max_emblems;)
{
rtemp = READUINT8(save_p);
for (j = 0; j < 8 && j+i < MAXEMBLEMS; ++j)
for (j = 0; j < 8 && j+i < max_emblems; ++j)
data->collected[j+i] = ((rtemp >> j) & 1);
i += j;
}
for (i = 0; i < MAXEXTRAEMBLEMS;)
for (i = 0; i < max_extraemblems;)
{
rtemp = READUINT8(save_p);
for (j = 0; j < 8 && j+i < MAXEXTRAEMBLEMS; ++j)
for (j = 0; j < 8 && j+i < max_extraemblems; ++j)
data->extraCollected[j+i] = ((rtemp >> j) & 1);
i += j;
}
for (i = 0; i < MAXUNLOCKABLES;)
for (i = 0; i < max_unlockables;)
{
rtemp = READUINT8(save_p);
for (j = 0; j < 8 && j+i < MAXUNLOCKABLES; ++j)
for (j = 0; j < 8 && j+i < max_unlockables; ++j)
data->unlocked[j+i] = ((rtemp >> j) & 1);
i += j;
}
for (i = 0; i < MAXCONDITIONSETS;)
for (i = 0; i < max_conditionsets;)
{
rtemp = READUINT8(save_p);
for (j = 0; j < 8 && j+i < MAXCONDITIONSETS; ++j)
for (j = 0; j < 8 && j+i < max_conditionsets; ++j)
data->achieved[j+i] = ((rtemp >> j) & 1);
i += j;
}
@ -4704,12 +4789,9 @@ void G_LoadGame(UINT32 slot, INT16 mapoverride)
Z_Free(savebuffer);
save_p = savebuffer = NULL;
// gameaction = ga_nothing;
// G_SetGamestate(GS_LEVEL);
displayplayer = consoleplayer;
multiplayer = splitscreen = false;
// G_DeferedInitNew(sk_medium, G_BuildMapName(1), 0, 0, 1);
if (setsizeneeded)
R_ExecuteSetViewSize();
@ -4902,9 +4984,9 @@ cleanup:
// Can be called by the startup code or the menu task,
// consoleplayer, displayplayer, playeringame[] should be set.
//
void G_DeferedInitNew(boolean pultmode, const char *mapname, INT32 pickedchar, boolean SSSG, boolean FLS)
void G_DeferedInitNew(boolean pultmode, const char *mapname, INT32 character, boolean SSSG, boolean FLS)
{
UINT16 color = skins[pickedchar].prefcolor;
pickedchar = character;
paused = false;
if (demoplayback)
@ -4925,10 +5007,7 @@ void G_DeferedInitNew(boolean pultmode, const char *mapname, INT32 pickedchar, b
SplitScreen_OnChange();
}
color = skins[pickedchar].prefcolor;
SetPlayerSkinByNum(consoleplayer, pickedchar);
CV_StealthSet(&cv_skin, skins[pickedchar].name);
CV_StealthSetValue(&cv_playercolor, color);
SetPlayerSkinByNum(consoleplayer, character);
if (mapname)
D_MapChange(M_MapNumber(mapname[3], mapname[4]), gametype, pultmode, true, 1, false, FLS);
@ -4962,12 +5041,20 @@ void G_InitNew(UINT8 pultmode, const char *mapname, boolean resetplayer, boolean
numgameovers = tokenlist = token = sstimer = redscore = bluescore = lastmap = 0;
countdown = countdown2 = exitfadestarted = 0;
if (!FLS)
{
emeralds = 0;
memset(&luabanks, 0, sizeof(luabanks));
}
for (i = 0; i < MAXPLAYERS; i++)
{
players[i].playerstate = PST_REBORN;
players[i].starpostscale = players[i].starpostangle = players[i].starpostnum = players[i].starposttime = 0;
players[i].starpostx = players[i].starposty = players[i].starpostz = 0;
players[i].recordscore = 0;
// default lives, continues and score
if (netgame || multiplayer)
{
if (!FLS || (players[i].lives < 1))
@ -5000,6 +5087,10 @@ void G_InitNew(UINT8 pultmode, const char *mapname, boolean resetplayer, boolean
CV_StealthSetValue(&cv_itemfinder, 0);
}
// Restore each player's skin if it was previously forced to be a specific one
// (Looks a bit silly, but it works.)
boolean reset_skin = netgame && mapheaderinfo[gamemap-1] && mapheaderinfo[gamemap-1]->forcecharacter[0] != '\0';
// internal game map
// well this check is useless because it is done before (d_netcmd.c::command_map_f)
// but in case of for demos....
@ -5027,6 +5118,22 @@ void G_InitNew(UINT8 pultmode, const char *mapname, boolean resetplayer, boolean
automapactive = false;
imcontinuing = false;
if (reset_skin)
D_SendPlayerConfig();
// fetch saved data if available
if (savedata.lives > 0)
{
numgameovers = savedata.numgameovers;
players[consoleplayer].continues = savedata.continues;
players[consoleplayer].lives = savedata.lives;
players[consoleplayer].score = savedata.score;
if ((botingame = ((botskin = savedata.botskin) != 0)))
botcolor = skins[botskin-1].prefcolor;
emeralds = savedata.emeralds;
savedata.lives = 0;
}
if ((gametyperules & GTR_CUTSCENES) && !skipprecutscene && mapheaderinfo[gamemap-1]->precutscenenum && !modeattacking && !(marathonmode & MA_NOCUTSCENES)) // Start a custom cutscene.
F_StartCustomCutscene(mapheaderinfo[gamemap-1]->precutscenenum-1, true, resetplayer, FLS);
else

View file

@ -49,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;
@ -174,8 +176,7 @@ void G_SpawnPlayer(INT32 playernum);
// Can be called by the startup code or M_Responder.
// A normal game starts at map 1, but a warp test can start elsewhere
void G_DeferedInitNew(boolean pultmode, const char *mapname, INT32 pickedchar,
boolean SSSG, boolean FLS);
void G_DeferedInitNew(boolean pultmode, const char *mapname, INT32 character, boolean SSSG, boolean FLS);
void G_DoLoadLevel(boolean resetplayer);
void G_StartTitleCard(void);
void G_PreLevelTitleCard(void);
@ -260,8 +261,7 @@ 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(gamedata_t *data);
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);

View file

@ -16,7 +16,7 @@
#include "g_input.h"
#include "keys.h"
#include "hu_stuff.h" // need HUFONT start & end
#include "d_net.h"
#include "netcode/d_net.h"
#include "console.h"
#define MAXMOUSESENSITIVITY 100 // sensitivity steps

View file

@ -53,9 +53,11 @@ typedef enum
extern gamestate_t gamestate;
extern UINT8 titlemapinaction;
extern UINT8 ultimatemode; // was sk_insane
extern UINT8 ultimatemode;
extern gameaction_t gameaction;
extern INT32 pickedchar;
extern boolean botingame;
extern UINT8 botskin;
extern UINT16 botcolor;

View file

@ -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
)

View file

@ -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

View file

@ -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
};

View file

@ -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__

View file

@ -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

View file

@ -29,7 +29,7 @@
#include "../r_patch.h"
#include "../r_picformats.h"
#include "../r_bsp.h"
#include "../d_clisrv.h"
#include "../netcode/d_clisrv.h"
#include "../w_wad.h"
#include "../z_zone.h"
#include "../r_splats.h"
@ -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,9 +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);
if ((thing->scale != thing->old_scale) && (thing->scale >= FRACUNIT/1024)) // Interpolate shadows when scaling mobjs
scalemul = FixedMul(scalemul, FixedDiv(interp.scale, thing->scale));
scalemul = FixedMul(scalemul, (interp.radius*2) / gpatch->height);
fscale = FIXED_TO_FLOAT(scalemul);
fx = FIXED_TO_FLOAT(interp.x);
@ -3719,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
{
@ -4038,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, ...)
@ -4094,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;
@ -4109,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;
@ -4482,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
@ -4854,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);
@ -4953,10 +5007,17 @@ 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))
if (R_ThingWithinDist(thing, limit_dist, hoop_limit_dist))
{
if (R_ThingVisible(thing))
{
HWR_ProjectSprite(thing);
}
HWR_ProjectBoundingBox(thing);
}
}
#ifdef HWPRECIP
// no, no infinite draw distance for precipitation. this option at zero is supposed to turn it off
if ((limit_dist = (fixed_t)cv_drawdist_precip.value << FRACBITS))
@ -5012,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
@ -5179,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)
@ -5256,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));
@ -5308,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
@ -5472,6 +5537,7 @@ static void HWR_ProjectSprite(mobj_t *thing)
vis->vflip = vflip;
vis->precip = false;
vis->bbox = false;
vis->angle = interp.angle;
}
@ -5594,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))
@ -5607,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+
// ==========================================================================
@ -5790,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;
@ -6068,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;
@ -6282,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;

View file

@ -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

View file

@ -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);
fixed_t anglef = AngleFixed(R_ModelRotationAngle(&interp));
p.rollangle = 0.0f;
if (anglef)
{
fixed_t camAngleDiff = AngleFixed(viewangle) - FLOAT_TO_FIXED(p.angley); // dumb reconversion back, I know
p.rollangle = FIXED_TO_FLOAT(anglef);
p.roll = true;
// rotation pivot
p.centerx = FIXED_TO_FLOAT(spr->mobj->radius/2);
p.centery = FIXED_TO_FLOAT(spr->mobj->height/(flip ? -2 : 2));
p.centerx = FIXED_TO_FLOAT(interp.radius / 2);
p.centery = FIXED_TO_FLOAT(interp.height / 2);
// rotation axis
if (sprinfo->available)
p.rotaxis = (UINT8)(sprinfo->pivot[(spr->mobj->frame & FF_FRAMEMASK)].rotaxis);
// 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;
if (flip)
p.rollflip *= -1;
// 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;

View file

@ -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++;

View file

@ -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);

View file

@ -19,7 +19,9 @@
#include "m_cond.h" // emblems
#include "m_misc.h" // word jumping
#include "d_clisrv.h"
#include "netcode/d_clisrv.h"
#include "netcode/net_command.h"
#include "netcode/gamestate.h"
#include "g_game.h"
#include "g_input.h"
@ -175,14 +177,12 @@ static huddrawlist_h luahuddrawlist_scores;
static tic_t resynch_ticker = 0;
#ifndef NONET
// just after
static void Command_Say_f(void);
static void Command_Sayto_f(void);
static void Command_Sayteam_f(void);
static void Command_CSay_f(void);
static void Got_Saycmd(UINT8 **p, INT32 playernum);
#endif
void HU_LoadGraphics(void)
{
@ -327,13 +327,11 @@ void HU_LoadGraphics(void)
//
void HU_Init(void)
{
#ifndef NONET
COM_AddCommand("say", Command_Say_f, COM_LUA);
COM_AddCommand("sayto", Command_Sayto_f, COM_LUA);
COM_AddCommand("sayteam", Command_Sayteam_f, COM_LUA);
COM_AddCommand("csay", Command_CSay_f, COM_LUA);
RegisterNetXCmd(XD_SAY, Got_Saycmd);
#endif
// set shift translation table
shiftxform = english_shiftxform;
@ -363,8 +361,6 @@ void HU_Start(void)
// EXECUTION
//======================================================================
#ifndef NONET
// EVERY CHANGE IN THIS SCRIPT IS LOL XD! BY VINCYTM
static UINT32 chat_nummsg_log = 0;
@ -412,11 +408,9 @@ static void HU_removeChatText_Log(void)
}
chat_nummsg_log--; // lost 1 msg.
}
#endif
void HU_AddChatText(const char *text, boolean playsound)
{
#ifndef NONET
if (playsound && cv_consolechat.value != 2) // Don't play the sound if we're using hidden chat.
S_StartSound(NULL, sfx_radio);
// reguardless of our preferences, put all of this in the chat buffer in case we decide to change from oldchat mid-game.
@ -438,14 +432,8 @@ void HU_AddChatText(const char *text, boolean playsound)
CONS_Printf("%s\n", text);
else // if we aren't, still save the message to log.txt
CON_LogMessage(va("%s\n", text));
#else
(void)playsound;
CONS_Printf("%s\n", text);
#endif
}
#ifndef NONET
/** Runs a say command, sending an ::XD_SAY message.
* A say command consists of a signed 8-bit integer for the target, an
* unsigned 8-bit flag variable, and then the message itself.
@ -865,8 +853,6 @@ static void Got_Saycmd(UINT8 **p, INT32 playernum)
#endif
}
#endif
//
//
void HU_Ticker(void)
@ -882,7 +868,6 @@ void HU_Ticker(void)
else
hu_showscores = false;
#ifndef NONET
if (chat_on)
{
// count down the scroll timer.
@ -910,7 +895,6 @@ void HU_Ticker(void)
HU_removeChatText_Mini();
}
}
#endif
if (cechotimer > 0) --cechotimer;
@ -918,8 +902,6 @@ void HU_Ticker(void)
resynch_ticker++;
}
#ifndef NONET
static boolean teamtalk = false;
static boolean justscrolleddown;
static boolean justscrolledup;
@ -1027,8 +1009,6 @@ static void HU_sendChatMessage(void)
}
}
#endif
void HU_clearChatChars(void)
{
memset(w_chat, '\0', sizeof(w_chat));
@ -1043,9 +1023,7 @@ void HU_clearChatChars(void)
//
boolean HU_Responder(event_t *ev)
{
#ifndef NONET
INT32 c=0;
#endif
if (ev->type != ev_keydown)
return false;
@ -1072,7 +1050,6 @@ boolean HU_Responder(event_t *ev)
return false;
}*/ //We don't actually care about that unless we get splitscreen netgames. :V
#ifndef NONET
c = (INT32)ev->key;
if (!chat_on)
@ -1222,7 +1199,6 @@ boolean HU_Responder(event_t *ev)
return true;
}
#endif
return false;
}
@ -1232,8 +1208,6 @@ boolean HU_Responder(event_t *ev)
// HEADS UP DRAWING
//======================================================================
#ifndef NONET
// Precompile a wordwrapped string to any given width.
// This is a muuuch better method than V_WORDWRAP.
// again stolen and modified a bit from video.c, don't mind me, will need to rearrange this one day.
@ -1813,7 +1787,6 @@ static void HU_DrawChat_Old(void)
if (hu_tick < 4)
V_DrawCharacter(HU_INPUTX + c, y, '_' | cv_constextsize.value |V_NOSCALESTART|t, true);
}
#endif
// Draw crosshairs at the exact center of the view.
// In splitscreen, crosshairs are stretched vertically to compensate for V_PERPLAYER squishing them.
@ -1953,7 +1926,6 @@ static void HU_DrawDemoInfo(void)
//
void HU_Drawer(void)
{
#ifndef NONET
// draw chat string plus cursor
if (chat_on)
{
@ -1970,7 +1942,6 @@ void HU_Drawer(void)
if (!OLDCHAT && cv_consolechat.value < 2 && netgame) // Don't display minimized chat if you set the mode to Window (Hidden)
HU_drawMiniChat(); // draw messages in a cool fashion.
}
#endif
if (cechotimer)
HU_DrawCEcho();
@ -2025,7 +1996,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;

View file

@ -49,6 +49,10 @@ size_t I_GetFreeMem(size_t *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.
*/

View file

@ -17,7 +17,7 @@
#include "command.h"
#include "doomtype.h"
#include "d_netcmd.h"
#include "netcode/d_netcmd.h"
#include "m_fixed.h"
#include "i_system.h"

View file

@ -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
{"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
{"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
{"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

View file

@ -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

View file

@ -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) {

View file

@ -26,11 +26,11 @@
#include "y_inter.h"
#include "hu_stuff.h" // HU_AddChatText
#include "console.h"
#include "d_netcmd.h" // IsPlayerAdmin
#include "netcode/d_netcmd.h" // IsPlayerAdmin
#include "m_menu.h" // Player Setup menu color stuff
#include "m_misc.h" // M_MapNumber
#include "b_bot.h" // B_UpdateBotleader
#include "d_clisrv.h" // CL_RemovePlayer
#include "netcode/d_clisrv.h" // CL_RemovePlayer
#include "i_system.h" // I_GetPreciseTime, I_GetPrecisePrecision
#include "lua_script.h"
@ -689,11 +689,12 @@ static int lib_pSpawnLockOn(lua_State *L)
return LUA_ErrInvalid(L, "player_t");
if (state >= NUMSTATES)
return luaL_error(L, "state %d out of range (0 - %d)", state, NUMSTATES-1);
if (P_IsLocalPlayer(player)) // Only display it on your own view.
if (P_IsLocalPlayer(player)) // Only display it on your own view. Don't display it for spectators
{
mobj_t *visual = P_SpawnMobj(lockon->x, lockon->y, lockon->z, MT_LOCKON); // positioning, flip handled in P_SceneryThinker
P_SetTarget(&visual->target, lockon);
visual->flags2 |= MF2_DONTDRAW;
visual->drawonlyforplayer = player; // Hide it from the other player in splitscreen, and yourself when spectating
P_SetMobjStateNF(visual, state);
}
return 0;
@ -1078,6 +1079,7 @@ static int lib_pZMovement(lua_State *L)
if (!actor)
return LUA_ErrInvalid(L, "mobj_t");
lua_pushboolean(L, P_ZMovement(actor));
if (!P_MobjWasRemoved(actor))
P_CheckPosition(actor, actor->x, actor->y);
P_SetTarget(&tmthing, ptmthing);
return 1;
@ -1106,6 +1108,7 @@ static int lib_pSceneryZMovement(lua_State *L)
if (!actor)
return LUA_ErrInvalid(L, "mobj_t");
lua_pushboolean(L, P_SceneryZMovement(actor));
if (!P_MobjWasRemoved(actor))
P_CheckPosition(actor, actor->x, actor->y);
P_SetTarget(&tmthing, ptmthing);
return 1;
@ -2453,7 +2456,7 @@ static int lib_pFadeLight(lua_State *L)
static int lib_pIsFlagAtBase(lua_State *L)
{
mobjtype_t flag = luaL_checkinteger(L, 1);
NOHUD
//HUDSAFE
INLEVEL
if (flag >= NUMMOBJTYPES)
return luaL_error(L, "mobj type %d out of range (0 - %d)", flag, NUMMOBJTYPES-1);
@ -2846,6 +2849,22 @@ static int lib_rTextureNumForName(lua_State *L)
return 1;
}
static int lib_rCheckTextureNameForNum(lua_State *L)
{
INT32 num = (INT32)luaL_checkinteger(L, 1);
//HUDSAFE
lua_pushstring(L, R_CheckTextureNameForNum(num));
return 1;
}
static int lib_rTextureNameForNum(lua_State *L)
{
INT32 num = (INT32)luaL_checkinteger(L, 1);
//HUDSAFE
lua_pushstring(L, R_TextureNameForNum(num));
return 1;
}
// R_DRAW
////////////
static int lib_rGetColorByName(lua_State *L)
@ -3525,7 +3544,7 @@ static int lib_gAddGametype(lua_State *L)
// Partly lifted from Got_AddPlayer
static int lib_gAddPlayer(lua_State *L)
{
INT16 i, newplayernum, botcount = 1;
INT16 i, newplayernum;
player_t *newplayer;
SINT8 skinnum = 0, bot;
@ -3533,10 +3552,8 @@ static int lib_gAddPlayer(lua_State *L)
{
if (!playeringame[i])
break;
if (players[i].bot)
botcount++; // How many of us are there already?
}
if (i >= MAXPLAYERS)
{
lua_pushnil(L);
@ -3807,7 +3824,7 @@ static int lib_gDoReborn(lua_State *L)
}
// Another Lua function that doesn't actually exist!
// Sets nextmapoverride & skipstats without instantly ending the level, for instances where other sources should be exiting the level, like normal signposts.
// Sets nextmapoverride, skipstats and nextgametype without instantly ending the level, for instances where other sources should be exiting the level, like normal signposts.
static int lib_gSetCustomExitVars(lua_State *L)
{
int n = lua_gettop(L); // Num arguments
@ -3820,14 +3837,17 @@ static int lib_gSetCustomExitVars(lua_State *L)
// G_SetCustomExitVars(int) [nextmap override only]
// G_SetCustomExitVars(nil, int) [skipstats only]
// G_SetCustomExitVars(int, int) [both of the above]
// G_SetCustomExitVars(int, int, int) [nextmapoverride, skipstats and nextgametype]
nextmapoverride = 0;
skipstats = 0;
nextgametype = -1;
if (n >= 1)
{
nextmapoverride = (INT16)luaL_optinteger(L, 1, 0);
skipstats = (INT16)luaL_optinteger(L, 2, 0);
nextgametype = (INT16)luaL_optinteger(L, 3, -1);
}
return 0;
@ -4203,6 +4223,8 @@ static luaL_Reg lib[] = {
// r_data
{"R_CheckTextureNumForName",lib_rCheckTextureNumForName},
{"R_TextureNumForName",lib_rTextureNumForName},
{"R_CheckTextureNameForNum", lib_rCheckTextureNameForNum},
{"R_TextureNameForNum", lib_rTextureNameForNum},
// r_draw
{"R_GetColorByName", lib_rGetColorByName},

View file

@ -16,6 +16,7 @@
#include "g_game.h"
#include "byteptr.h"
#include "z_zone.h"
#include "netcode/net_command.h"
#include "lua_script.h"
#include "lua_libs.h"
@ -357,7 +358,7 @@ static int lib_cvRegisterVar(lua_State *L)
if (lua_islightuserdata(L, 4))
{
CV_PossibleValue_t *pv = lua_touserdata(L, 4);
if (pv == CV_OnOff || pv == CV_YesNo || pv == CV_Unsigned || pv == CV_Natural)
if (pv == CV_OnOff || pv == CV_YesNo || pv == CV_Unsigned || pv == CV_Natural || pv == CV_TrueFalse)
cvar->PossibleValue = pv;
else
FIELDERROR("PossibleValue", "CV_PossibleValue_t expected, got unrecognised pointer")
@ -566,27 +567,59 @@ static luaL_Reg lib[] = {
{NULL, NULL}
};
enum cvar_e
{
cvar_name,
cvar_defaultvalue,
cvar_flags,
cvar_value,
cvar_string,
cvar_changed,
};
static const char *const cvar_opt[] = {
"name",
"defaultvalue",
"flags",
"value",
"string",
"changed",
NULL,
};
static int cvar_fields_ref = LUA_NOREF;
static int cvar_get(lua_State *L)
{
consvar_t *cvar = *(consvar_t **)luaL_checkudata(L, 1, META_CVAR);
const char *field = luaL_checkstring(L, 2);
enum cvar_e field = Lua_optoption(L, 2, -1, cvar_fields_ref);
if(fastcmp(field,"name"))
switch (field)
{
case cvar_name:
lua_pushstring(L, cvar->name);
else if(fastcmp(field,"defaultvalue"))
break;
case cvar_defaultvalue:
lua_pushstring(L, cvar->defaultvalue);
else if(fastcmp(field,"flags"))
break;
case cvar_flags:
lua_pushinteger(L, cvar->flags);
else if(fastcmp(field,"value"))
break;
case cvar_value:
lua_pushinteger(L, cvar->value);
else if(fastcmp(field,"string"))
break;
case cvar_string:
lua_pushstring(L, cvar->string);
else if(fastcmp(field,"changed"))
break;
case cvar_changed:
lua_pushboolean(L, cvar->changed);
else if (devparm)
return luaL_error(L, LUA_QL("consvar_t") " has no field named " LUA_QS, field);
break;
default:
if (devparm)
return luaL_error(L, LUA_QL("consvar_t") " has no field named " LUA_QS ".", lua_tostring(L, 2));
else
return 0;
}
return 1;
}
@ -598,6 +631,8 @@ int LUA_ConsoleLib(lua_State *L)
lua_setfield(L, -2, "__index");
lua_pop(L,1);
cvar_fields_ref = Lua_CreateFieldTable(L, cvar_opt);
// Set empty registry tables
lua_newtable(L);
lua_setfield(L, LUA_REGISTRYINDEX, "COM_Command");
@ -618,6 +653,8 @@ int LUA_ConsoleLib(lua_State *L)
lua_setglobal(L, "CV_Unsigned");
lua_pushlightuserdata(L, CV_Natural);
lua_setglobal(L, "CV_Natural");
lua_pushlightuserdata(L, CV_TrueFalse);
lua_setglobal(L, "CV_TrueFalse");
// Set global functions
lua_pushvalue(L, LUA_GLOBALSINDEX);

View file

@ -24,7 +24,7 @@
#include "lua_hud.h" // hud_running errors
#include "m_perfstats.h"
#include "d_netcmd.h" // for cv_perfstats
#include "netcode/d_netcmd.h" // for cv_perfstats
#include "i_system.h" // I_GetPreciseTime
/* =========================================================================

View file

@ -95,6 +95,8 @@ static const char *const patch_opt[] = {
"topoffset",
NULL};
static int patch_fields_ref = LUA_NOREF;
// alignment types for v.drawString
enum align {
align_left = 0,
@ -196,6 +198,8 @@ static const char *const camera_opt[] = {
"momz",
NULL};
static int camera_fields_ref = LUA_NOREF;
static int lib_getHudInfo(lua_State *L)
{
UINT32 i;
@ -276,9 +280,8 @@ static int colormap_get(lua_State *L)
static int patch_get(lua_State *L)
{
patch_t *patch = *((patch_t **)luaL_checkudata(L, 1, META_PATCH));
enum patch field = luaL_checkoption(L, 2, NULL, patch_opt);
enum patch field = Lua_optoption(L, 2, -1, patch_fields_ref);
// patches are invalidated when switching renderers
if (!patch) {
if (field == patch_valid) {
lua_pushboolean(L, 0);
@ -316,7 +319,7 @@ static int patch_set(lua_State *L)
static int camera_get(lua_State *L)
{
camera_t *cam = *((camera_t **)luaL_checkudata(L, 1, META_CAMERA));
enum cameraf field = luaL_checkoption(L, 2, NULL, camera_opt);
enum cameraf field = Lua_optoption(L, 2, -1, camera_fields_ref);
// cameras should always be valid unless I'm a nutter
I_Assert(cam != NULL);
@ -372,7 +375,7 @@ static int camera_get(lua_State *L)
static int camera_set(lua_State *L)
{
camera_t *cam = *((camera_t **)luaL_checkudata(L, 1, META_CAMERA));
enum cameraf field = luaL_checkoption(L, 2, NULL, camera_opt);
enum cameraf field = Lua_optoption(L, 2, -1, camera_fields_ref);
I_Assert(cam != NULL);
@ -432,7 +435,7 @@ static int camera_set(lua_State *L)
cam->momz = luaL_checkfixed(L, 3);
break;
default:
return luaL_error(L, LUA_QL("camera_t") " has no field named " LUA_QS, camera_opt[field]);
return luaL_error(L, LUA_QL("camera_t") " has no field named " LUA_QS ".", lua_tostring(L, 2));
}
return 0;
}
@ -1252,8 +1255,6 @@ static int libd_RandomKey(lua_State *L)
INT32 a = (INT32)luaL_checkinteger(L, 1);
HUDONLY
if (a > 65536)
LUA_UsageWarning(L, "v.RandomKey: range > 65536 is undefined behavior");
lua_pushinteger(L, M_RandomKey(a));
return 1;
}
@ -1264,13 +1265,6 @@ static int libd_RandomRange(lua_State *L)
INT32 b = (INT32)luaL_checkinteger(L, 2);
HUDONLY
if (b < a) {
INT32 c = a;
a = b;
b = c;
}
if ((b-a+1) > 65536)
LUA_UsageWarning(L, "v.RandomRange: range > 65536 is undefined behavior");
lua_pushinteger(L, M_RandomRange(a, b));
return 1;
}
@ -1444,6 +1438,8 @@ int LUA_HudLib(lua_State *L)
lua_setfield(L, -2, "__newindex");
lua_pop(L,1);
patch_fields_ref = Lua_CreateFieldTable(L, patch_opt);
luaL_newmetatable(L, META_CAMERA);
lua_pushcfunction(L, camera_get);
lua_setfield(L, -2, "__index");
@ -1452,6 +1448,8 @@ int LUA_HudLib(lua_State *L)
lua_setfield(L, -2, "__newindex");
lua_pop(L,1);
camera_fields_ref = Lua_CreateFieldTable(L, camera_opt);
luaL_register(L, "hud", lib_hud);
return 0;
}
@ -1488,7 +1486,6 @@ void LUA_SetHudHook(int hook, huddrawlist_h list)
break;
case HUD_HOOK(intermission):
lua_pushboolean(gL, intertype == int_spec &&
stagefailed);
lua_pushboolean(gL, stagefailed);
}
}

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