Merge branch SRB2:next into fix-segfault-polyvertex-null

This commit is contained in:
Alam Ed Arias 2023-10-25 18:21:13 +00:00
commit 3f29140ecb
198 changed files with 11472 additions and 13714 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)
endfunction()
if(output STREQUAL "")
set(${variable} FALSE PARENT_SCOPE)
else()
set(${variable} TRUE PARENT_SCOPE)
endif()
endfunction()
function(git_subject variable)
_git_easy_command(log -1 --format=%s)
endfunction()
function(get_git_dir variable)
_git_easy_command(rev-parse --git-dir)
endfunction()

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

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

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}")
# On MinGW with internal libraries, link the standard library statically
target_link_options(SRB2SDL2 PRIVATE "-static")
add_executable(SRB2SDL2 MACOSX_BUNDLE WIN32
comptime.c
md5.c
config.h.in
string.c
d_main.c
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

@ -1,75 +1,66 @@
#
# Makefile for feature flags.
#
passthru_opts+=\
NONET NO_IPV6 NOHW NOMD5 NOPOSTPROCESSING\
MOBJCONSISTANCY PACKETDROP ZDEBUG\
HAVE_MINIUPNPC\
# build with debugging information
ifdef DEBUGMODE
PACKETDROP=1
opts+=-DPARANOIA -DRANGECHECK
endif
ifndef NOHW
opts+=-DHWRENDER
sources+=$(call List,hardware/Sourcefile)
endif
ifndef NOASM
ifndef NONX86
sources+=tmap.nas tmap_mmx.nas
opts+=-DUSEASM
endif
endif
ifndef NOMD5
sources+=md5.c
endif
ifndef NOZLIB
ifndef NOPNG
ifdef PNG_PKGCONFIG
$(eval $(call Use_pkg_config,PNG_PKGCONFIG))
else
PNG_CONFIG?=$(call Prefix,libpng-config)
$(eval $(call Configure,PNG,$(PNG_CONFIG) \
$(if $(PNG_STATIC),--static),,--ldflags))
endif
ifdef LINUX
opts+=-D_LARGEFILE64_SOURCE
endif
opts+=-DHAVE_PNG
sources+=apng.c
endif
endif
ifndef NONET
ifndef NOCURL
CURLCONFIG?=curl-config
$(eval $(call Configure,CURL,$(CURLCONFIG)))
opts+=-DHAVE_CURL
endif
endif
ifdef HAVE_MINIUPNPC
libs+=-lminiupnpc
endif
# (Valgrind is a memory debugger.)
ifdef VALGRIND
VALGRIND_PKGCONFIG?=valgrind
$(eval $(call Use_pkg_config,VALGRIND))
ZDEBUG=1
opts+=-DHAVE_VALGRIND
endif
default_packages:=\
GME/libgme/LIBGME\
OPENMPT/libopenmpt/LIBOPENMPT\
ZLIB/zlib\
$(foreach p,$(default_packages),\
$(eval $(call Check_pkg_config,$(p))))
#
# Makefile for feature flags.
#
passthru_opts+=\
NO_IPV6 NOHW NOMD5 NOPOSTPROCESSING\
MOBJCONSISTANCY PACKETDROP ZDEBUG\
HAVE_MINIUPNPC\
# build with debugging information
ifdef DEBUGMODE
PACKETDROP=1
opts+=-DPARANOIA -DRANGECHECK
endif
ifndef NOHW
opts+=-DHWRENDER
sources+=$(call List,hardware/Sourcefile)
endif
ifndef NOMD5
sources+=md5.c
endif
ifndef NOZLIB
ifndef NOPNG
ifdef PNG_PKGCONFIG
$(eval $(call Use_pkg_config,PNG_PKGCONFIG))
else
PNG_CONFIG?=$(call Prefix,libpng-config)
$(eval $(call Configure,PNG,$(PNG_CONFIG) \
$(if $(PNG_STATIC),--static),,--ldflags))
endif
ifdef LINUX
opts+=-D_LARGEFILE64_SOURCE
endif
opts+=-DHAVE_PNG
sources+=apng.c
endif
endif
ifndef NOCURL
CURLCONFIG?=curl-config
$(eval $(call Configure,CURL,$(CURLCONFIG)))
opts+=-DHAVE_CURL
endif
ifdef HAVE_MINIUPNPC
libs+=-lminiupnpc
endif
# (Valgrind is a memory debugger.)
ifdef VALGRIND
VALGRIND_PKGCONFIG?=valgrind
$(eval $(call Use_pkg_config,VALGRIND))
ZDEBUG=1
opts+=-DHAVE_VALGRIND
endif
default_packages:=\
GME/libgme/LIBGME\
OPENMPT/libopenmpt/LIBOPENMPT\
ZLIB/zlib\
$(foreach p,$(default_packages),\
$(eval $(call Check_pkg_config,$(p))))

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
@ -77,13 +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

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

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

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

@ -11,8 +11,18 @@
#ifdef CMAKECONFIG
#define SRB2_COMP_REVISION "${SRB2_COMP_REVISION}"
#define SRB2_COMP_BRANCH "${SRB2_COMP_BRANCH}"
#define SRB2_COMP_REVISION "${SRB2_COMP_REVISION}"
#define SRB2_COMP_BRANCH "${SRB2_COMP_BRANCH}"
#define SRB2_COMP_NOTE "${SRB2_COMP_NOTE}"
// This is done with configure_file instead of defines in order to avoid
// recompiling the whole target whenever the working directory state changes
#cmakedefine SRB2_COMP_UNCOMMITTED
#ifdef SRB2_COMP_UNCOMMITTED
#define COMPVERSION_UNCOMMITTED
#endif
#define CMAKE_BUILD_TYPE "${CMAKE_BUILD_TYPE}"
#cmakedefine01 SRB2_COMP_OPTIMIZED
#endif
@ -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

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"
@ -979,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
@ -1215,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
//
@ -1228,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"
@ -1341,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());
@ -1363,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")))
@ -1607,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));
@ -1718,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

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

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

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"

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

@ -4410,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[] = {
@ -4551,6 +4552,7 @@ const char *const MSF_LIST[] = {
const char *const SSF_LIST[] = {
"OUTERSPACE",
"DOUBLESTEPUP",
"NOSTEPDOWN",
"WINDCURRENT",
"CONVEYOR",
"SPEEDPAD",
@ -4567,6 +4569,8 @@ const char *const SSF_LIST[] = {
"ZOOMTUBEEND",
"FINISHLINE",
"ROPEHANG",
"JUMPFLIP",
"GRAVITYOVERRIDE",
NULL
};
@ -4610,8 +4614,7 @@ const char *COLOR_ENUMS[] = {
// Desaturated
"AETHER", // SKINCOLOR_AETHER,
"SLATE", // SKINCOLOR_SLATE,
"METEORITE", // SKINCOLOR_METEORITE,
"MERCURY", // SKINCOLOR_MERCURY,
"MOONSTONE", // SKINCOLOR_MOONSTONE,
"BLUEBELL", // SKINCOLOR_BLUEBELL,
"PINK", // SKINCOLOR_PINK,
"ROSEWOOD", // SKINCOLOR_ROSEWOOD,
@ -4648,10 +4651,10 @@ const char *COLOR_ENUMS[] = {
"COPPER", // SKINCOLOR_COPPER,
"APRICOT", // SKINCOLOR_APRICOT,
"ORANGE", // SKINCOLOR_ORANGE,
"PUMPKIN", // SKINCOLOR_PUMPKIN,
"RUST", // SKINCOLOR_RUST,
"GOLD", // SKINCOLOR_GOLD,
"TANGERINE", // SKINCOLOR_TANGERINE,
"TOPAZ", // SKINCOLOR_TOPAZ,
"GOLD", // SKINCOLOR_GOLD,
"SANDY", // SKINCOLOR_SANDY,
"GOLDENROD", // SKINCOLOR_GOLDENROD,
"YELLOW", // SKINCOLOR_YELLOW,
@ -4661,20 +4664,21 @@ const char *COLOR_ENUMS[] = {
"LIME", // SKINCOLOR_LIME,
"PERIDOT", // SKINCOLOR_PERIDOT,
"APPLE", // SKINCOLOR_APPLE,
"HEADLIGHT", // SKINCOLOR_HEADLIGHT,
"CHARTREUSE", // SKINCOLOR_CHARTREUSE,
"GREEN", // SKINCOLOR_GREEN,
"FOREST", // SKINCOLOR_FOREST,
"SHAMROCK", // SKINCOLOR_SHAMROCK,
"JADE", // SKINCOLOR_JADE,
"HEADLIGHT", // SKINCOLOR_HEADLIGHT,
"MINT", // SKINCOLOR_MINT,
"MASTER", // SKINCOLOR_MASTER,
"EMERALD", // SKINCOLOR_EMERALD,
"BOTTLE", // SKINCOLOR_BOTTLE,
"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,
@ -4700,7 +4704,7 @@ const char *COLOR_ENUMS[] = {
"NOBLE", // SKINCOLOR_NOBLE,
"FUCHSIA", // SKINCOLOR_FUCHSIA,
"BUBBLEGUM", // SKINCOLOR_BUBBLEGUM,
"CRYSTAL", // SKINCOLOR_CRYSTAL,
"SIBERITE", // SKINCOLOR_SIBERITE,
"MAGENTA", // SKINCOLOR_MAGENTA,
"NEON", // SKINCOLOR_NEON,
"VIOLET", // SKINCOLOR_VIOLET,
@ -4879,7 +4883,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

View file

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

@ -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,8 +268,7 @@ typedef enum
// Desaturated
SKINCOLOR_AETHER,
SKINCOLOR_SLATE,
SKINCOLOR_METEORITE,
SKINCOLOR_MERCURY,
SKINCOLOR_MOONSTONE,
SKINCOLOR_BLUEBELL,
SKINCOLOR_PINK,
SKINCOLOR_ROSEWOOD,
@ -299,10 +305,10 @@ typedef enum
SKINCOLOR_COPPER,
SKINCOLOR_APRICOT,
SKINCOLOR_ORANGE,
SKINCOLOR_PUMPKIN,
SKINCOLOR_RUST,
SKINCOLOR_GOLD,
SKINCOLOR_TANGERINE,
SKINCOLOR_TOPAZ,
SKINCOLOR_GOLD,
SKINCOLOR_SANDY,
SKINCOLOR_GOLDENROD,
SKINCOLOR_YELLOW,
@ -312,20 +318,21 @@ typedef enum
SKINCOLOR_LIME,
SKINCOLOR_PERIDOT,
SKINCOLOR_APPLE,
SKINCOLOR_HEADLIGHT,
SKINCOLOR_CHARTREUSE,
SKINCOLOR_GREEN,
SKINCOLOR_FOREST,
SKINCOLOR_SHAMROCK,
SKINCOLOR_JADE,
SKINCOLOR_HEADLIGHT,
SKINCOLOR_MINT,
SKINCOLOR_MASTER,
SKINCOLOR_EMERALD,
SKINCOLOR_BOTTLE,
SKINCOLOR_SEAFOAM,
SKINCOLOR_ISLAND,
SKINCOLOR_BOTTLE,
SKINCOLOR_AQUA,
SKINCOLOR_TEAL,
SKINCOLOR_OCEAN,
SKINCOLOR_WAVE,
SKINCOLOR_CYAN,
SKINCOLOR_TURQUOISE,
@ -351,7 +358,7 @@ typedef enum
SKINCOLOR_NOBLE,
SKINCOLOR_FUCHSIA,
SKINCOLOR_BUBBLEGUM,
SKINCOLOR_CRYSTAL,
SKINCOLOR_SIBERITE,
SKINCOLOR_MAGENTA,
SKINCOLOR_NEON,
SKINCOLOR_VIOLET,
@ -637,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
@ -707,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__
// Note: C++ bool and C99/C11 _Bool are NOT compatible.
// Historically, boolean was win32 BOOL on Windows. For equivalence, it's now
// int32_t. "true" and "false" are only declared for C code; in C++, conversion
// between "bool" and "int32_t" takes over.
#ifndef _WIN32
typedef int32_t boolean;
#else
#define boolean BOOL
#endif
//faB: clean that up !!
#if defined( _MSC_VER) && (_MSC_VER >= 1800) // MSVC 2013 and forward
#include "stdbool.h"
#elif defined (_WIN32)
#define false FALSE // use windows types
#define true TRUE
#define boolean BOOL
#else
typedef enum {false, true} boolean;
#endif
#endif // __BYTEBOOL__
#ifndef __cplusplus
#ifndef _WIN32
enum {false = 0, true = 1};
#else
#define false FALSE
#define true TRUE
#endif
#endif
/* 7.18.2.1 Limits of exact-width integer types */
@ -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,7 +185,14 @@ const char *I_ClipboardPaste(void)
return NULL;
}
void I_RegisterSysCommands(void) {}
size_t I_GetRandomBytes(char *destination, size_t amount)
{
(void)destination;
(void)amount;
return 0;
}
void I_RegisterSysCommands(void){}
void I_GetCursorPosition(INT32 *x, INT32 *y)
{

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"
@ -1062,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\"",
@ -1090,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:
@ -1197,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
@ -1644,7 +1648,7 @@ void F_GameEvaluationTicker(void)
sparklloop = 0;
}
if (finalecount == 5*TICRATE)
if (G_CoopGametype() && !stagefailed && finalecount == 5*TICRATE)
{
serverGamedata->timesBeaten++;
clientGamedata->timesBeaten++;
@ -2256,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;
@ -3509,6 +3513,7 @@ void F_TitleScreenTicker(boolean run)
}
titledemo = true;
demofileoverride = DFILE_OVERRIDE_NONE;
G_DoPlayDemo(dname);
}
}

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,23 +1442,43 @@ void G_BeginRecording(void)
M_Memcpy(demo_p, mapmd5, 16); demo_p += 16;
WRITEUINT8(demo_p,demoflags);
// file list
m = demo_p;/* file count */
demo_p += 2;
totalfiles = 0;
for (i = mainwads; ++i < numwadfiles; )
{
if (wadfiles[i]->important)
{
nameonly(( filename = va("%s", wadfiles[i]->filename) ));
WRITESTRINGL(demo_p, filename, MAX_WADPATH);
WRITEMEM(demo_p, wadfiles[i]->md5sum, 16);
totalfiles++;
}
}
WRITEUINT16(m, totalfiles);
switch ((demoflags & DF_ATTACKMASK)>>DF_ATTACKSHIFT)
{
case ATTACKING_NONE: // 0
break;
case ATTACKING_RECORD: // 1
demotime_p = demo_p;
WRITEUINT32(demo_p,UINT32_MAX); // time
WRITEUINT32(demo_p,0); // score
WRITEUINT16(demo_p,0); // rings
break;
case ATTACKING_NIGHTS: // 2
demotime_p = demo_p;
WRITEUINT32(demo_p,UINT32_MAX); // time
WRITEUINT32(demo_p,0); // score
break;
default: // 3
break;
case ATTACKING_NONE: // 0
break;
case ATTACKING_RECORD: // 1
demotime_p = demo_p;
WRITEUINT32(demo_p,UINT32_MAX); // time
WRITEUINT32(demo_p,0); // score
WRITEUINT16(demo_p,0); // rings
break;
case ATTACKING_NIGHTS: // 2
demotime_p = demo_p;
WRITEUINT32(demo_p,UINT32_MAX); // time
WRITEUINT32(demo_p,0); // score
break;
default: // 3
break;
}
WRITEUINT32(demo_p,P_GetInitSeed());
@ -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);
@ -1441,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,
@ -2078,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;
@ -2136,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;
}
}
@ -2171,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;
@ -2522,7 +2529,6 @@ static inline void G_PlayerFinishLevel(INT32 player)
memset(p->powers, 0, sizeof (p->powers));
p->ringweapons = 0;
p->recordscore = 0;
p->mo->flags2 &= ~MF2_SHADOW; // cancel invisibility
P_FlashPal(p, 0, 0); // Resets
@ -2546,7 +2552,6 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
{
player_t *p;
INT32 score;
INT32 recordscore;
INT32 lives;
INT32 continues;
fixed_t camerascale;
@ -2749,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;
@ -3462,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)
{
@ -3862,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;
@ -4054,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,
@ -4062,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));
@ -4118,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)))
{
@ -4143,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.
@ -4152,7 +4143,6 @@ 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))
@ -4218,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;
@ -4266,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--;
@ -4790,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();
@ -4988,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)
@ -5011,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);
@ -5048,6 +5041,12 @@ 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;
@ -5055,6 +5054,7 @@ void G_InitNew(UINT8 pultmode, const char *mapname, boolean resetplayer, boolean
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))
@ -5087,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....
@ -5114,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);

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

@ -42,10 +42,10 @@ int unsortedVertexArrayAllocSize = 65536;
// Call HWR_RenderBatches to render all the collected geometry.
void HWR_StartBatching(void)
{
if (currently_batching)
I_Error("Repeat call to HWR_StartBatching without HWR_RenderBatches");
if (currently_batching)
I_Error("Repeat call to HWR_StartBatching without HWR_RenderBatches");
// init arrays if that has not been done yet
// init arrays if that has not been done yet
if (!finalVertexArray)
{
finalVertexArray = malloc(finalVertexArrayAllocSize * sizeof(FOutVector));
@ -55,7 +55,7 @@ void HWR_StartBatching(void)
unsortedVertexArray = malloc(unsortedVertexArrayAllocSize * sizeof(FOutVector));
}
currently_batching = true;
currently_batching = true;
}
// This replaces the direct calls to pfnSetTexture in cases where batching is available.

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"
@ -1731,7 +1731,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)
@ -1854,7 +1854,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)
@ -3159,7 +3159,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);
}
@ -3205,7 +3205,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);
}
@ -3659,7 +3659,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;
@ -3670,9 +3670,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);
@ -3784,7 +3782,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
{
@ -4119,32 +4117,32 @@ static void HWR_DrawBoundingBox(gl_vissprite_t *vis)
// repeat this 4 times (overhead)
//
//
// 17 20 21 11
// 16 15 14 10
// 27 22 *--* 07 12
// 15 16 17 09
// 14 13 12 08
// 23 18 *--* 07 10
// | |
// 26 23 *--* 06 13
// 24 00 01 02
// 25 05 04 03
// 22 19 *--* 06 11
// 20 00 01 02
// 21 05 04 03
//
v[000].x = v[005].x = v[015].x = v[016].x = v[017].x = v[020].x =
v[022].x = v[023].x = v[024].x = v[025].x = v[026].x = v[027].x = vis->x1; // west
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[001].x = v[002].x = v[003].x = v[004].x = v[006].x = v[007].x =
v[010].x = v[011].x = v[012].x = v[013].x = v[014].x = v[021].x = vis->x2; // east
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[000].z = v[001].z = v[002].z = v[003].z = v[004].z = v[005].z =
v[006].z = v[013].z = v[023].z = v[024].z = v[025].z = v[026].z = vis->z1; // south
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[007].z = v[010].z = v[011].z = v[012].z = v[014].z = v[015].z =
v[016].z = v[017].z = v[020].z = v[021].z = v[022].z = v[027].z = vis->z2; // north
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[000].y = v[001].y = v[002].y = v[006].y = v[007].y = v[010].y =
v[014].y = v[015].y = v[016].y = v[022].y = v[023].y = v[024].y = vis->gz; // bottom
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[003].y = v[004].y = v[005].y = v[011].y = v[012].y = v[013].y =
v[017].y = v[020].y = v[021].y = v[025].y = v[026].y = v[027].y = vis->gzt; // top
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));
@ -4207,14 +4205,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;
@ -5390,7 +5385,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));
@ -5442,7 +5437,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
@ -5748,7 +5743,6 @@ static void HWR_ProjectBoundingBox(mobj_t *thing)
gl_vissprite_t *vis;
float tr_x, tr_y;
float tz;
float rad;
if (!thing)
return;
@ -5783,15 +5777,13 @@ static void HWR_ProjectBoundingBox(mobj_t *thing)
tr_x += gl_viewx;
tr_y += gl_viewy;
rad = FIXED_TO_FLOAT(thing->radius);
vis = HWR_NewVisSprite();
vis->x1 = tr_x - rad;
vis->x2 = tr_x + rad;
vis->z1 = tr_y - rad;
vis->z2 = tr_y + rad;
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(thing->height);
vis->gzt = vis->gz + FIXED_TO_FLOAT(interp.height);
vis->mobj = thing;
vis->precip = false;

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.
@ -1585,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);
@ -1621,8 +1621,8 @@ boolean HWR_DrawModel(gl_vissprite_t *spr)
p.roll = true;
// rotation pivot
p.centerx = FIXED_TO_FLOAT(spr->mobj->radius / 2);
p.centery = FIXED_TO_FLOAT(spr->mobj->height / 2);
p.centerx = FIXED_TO_FLOAT(interp.radius / 2);
p.centery = FIXED_TO_FLOAT(interp.height / 2);
// rotation axes relative to camera
p.rollx = FIXED_TO_FLOAT(FINECOSINE(FixedAngle(camAngleDiff) >> ANGLETOFINESHIFT));

View file

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

@ -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,10 +21584,9 @@ skincolor_t skincolors[MAXSKINCOLORS] = {
{"Black", {0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1b, 0x1b, 0x1c, 0x1d, 0x1d, 0x1e, 0x1e, 0x1f, 0x1f}, SKINCOLOR_WHITE, 7, V_GRAYMAP, true}, // SKINCOLOR_BLACK
// 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
{"Meteorite", { 0, 4, 8, 9, 11, 12, 14, 15, 171, 172, 173, 174, 175, 27, 29, 31}, SKINCOLOR_TOPAZ, 15, V_GRAYMAP, true}, // SKINCOLOR_METEORITE
{"Mercury", { 0, 3, 4, 7, 11, 12, 14, 15, 171, 172, 173, 155, 157, 159, 253, 254}, SKINCOLOR_ECRU, 15, V_AZUREMAP, true}, // SKINCOLOR_MERCURY
{"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
@ -21597,37 +21596,37 @@ skincolor_t skincolors[MAXSKINCOLORS] = {
{"Boulder", {0xde, 0xe0, 0xe1, 0xe4, 0xe7, 0xe9, 0xeb, 0xec, 0xed, 0xed, 0xed, 0x19, 0x19, 0x1b, 0x1d, 0x1e}, SKINCOLOR_KETCHUP, 0, V_BROWNMAP, true}, // SKINCOLOR_BOULDER
{"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_MERCURY, 15, V_BROWNMAP, true}, // SKINCOLOR_ECRU
{"Ecru", { 80, 83, 84, 85, 86, 242, 243, 245, 230, 232, 234, 236, 238, 239, 47, 47}, SKINCOLOR_ARCTIC, 12, V_BROWNMAP, true}, // SKINCOLOR_ECRU
{"Tan", {0x51, 0x51, 0x54, 0x54, 0x55, 0x55, 0x56, 0x56, 0x56, 0x57, 0xf5, 0xf5, 0xf9, 0xf9, 0xed, 0xed}, SKINCOLOR_BROWN, 12, V_BROWNMAP, true}, // SKINCOLOR_TAN
{"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_HEADLIGHT, 8, V_PURPLEMAP, true}, // SKINCOLOR_LAVENDER
{"Lavender", {0xc0, 0xc0, 0xc1, 0xc1, 0xc2, 0xc2, 0xc3, 0xc3, 0xc3, 0xc4, 0xc5, 0xc5, 0xc6, 0xc6, 0xc7, 0xc7}, SKINCOLOR_GOLD, 4, V_PURPLEMAP, true}, // SKINCOLOR_LAVENDER
// Viv's vivid colours (toast 21/07/17)
// Tweaks & additions (Lach, sphere, Alice, MotorRoach 26/10/22)
// Tweaks & additions (Lach, Chrispy, sphere, Alice, MotorRoach & Saneko 26/10/22)
{"Ruby", {0xb0, 0xb0, 0xc9, 0xca, 0xcc, 0x26, 0x27, 0x28, 0x29, 0x2a, 0xb9, 0xb9, 0xba, 0xba, 0xbb, 0xfd}, SKINCOLOR_EMERALD, 10, V_REDMAP, true}, // SKINCOLOR_RUBY
{"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_GREEN, 10, V_REDMAP, true}, // SKINCOLOR_PEPPER
{"Red", {0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x47, 0x2e, 0x2f}, SKINCOLOR_MASTER, 8, V_REDMAP, true}, // SKINCOLOR_RED
{"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
{"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, 195, 196, 186, 187, 30}, SKINCOLOR_DREAM, 6, V_ORANGEMAP, true}, // SKINCOLOR_FOUNDATION
{"Foundation", { 80, 81, 82, 84, 219, 221, 221, 212, 213, 214, 215, 197, 186, 187, 187, 30}, SKINCOLOR_DREAM, 6, V_ORANGEMAP, true}, // SKINCOLOR_FOUNDATION
{"Sunset", {0x51, 0x52, 0x40, 0x40, 0x34, 0x36, 0xd5, 0xd5, 0xd6, 0xd7, 0xcf, 0xcf, 0xc6, 0xc6, 0xc7, 0xfe}, SKINCOLOR_SAPPHIRE, 5, V_ORANGEMAP, true}, // SKINCOLOR_SUNSET
{"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", { 49, 50, 51, 52, 53, 54, 55, 57, 58, 59, 60, 42, 44, 45, 46, 46}, SKINCOLOR_BLUE, 4, V_ORANGEMAP, true}, // SKINCOLOR_ORANGE
{"Pumpkin", { 51, 52, 53, 54, 56, 58, 59, 59, 61, 61, 63, 45, 46, 47, 47, 31}, SKINCOLOR_ARCTIC, 12, V_ORANGEMAP, true}, // SKINCOLOR_PUMPKIN
{"Rust", {0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3c, 0x3d, 0x3d, 0x3d, 0x3f, 0x2c, 0x2d, 0x47, 0x2e, 0x2f, 0x2f}, SKINCOLOR_YOGURT, 8, V_ORANGEMAP, true}, // SKINCOLOR_RUST
{"Gold", {0x51, 0x51, 0x54, 0x54, 0x41, 0x42, 0x43, 0x43, 0x44, 0x45, 0x46, 0x3f, 0x2d, 0x2e, 0x2f, 0x2f}, SKINCOLOR_MAUVE, 8, V_YELLOWMAP, true}, // SKINCOLOR_GOLD
{"Topaz", { 0, 81, 83, 73, 74, 74, 65, 52, 53, 54, 56, 58, 60, 42, 43, 45}, SKINCOLOR_METEORITE, 10, V_YELLOWMAP, true}, // SKINCOLOR_TOPAZ
{"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
@ -21637,20 +21636,21 @@ skincolor_t skincolors[MAXSKINCOLORS] = {
{"Lime", {0x50, 0x51, 0x52, 0x53, 0x48, 0xbc, 0xbd, 0xbe, 0xbe, 0xbf, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f}, SKINCOLOR_MAGENTA, 9, V_PERIDOTMAP, true}, // SKINCOLOR_LIME
{"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_PEPPER, 8, V_GREENMAP, true}, // SKINCOLOR_GREEN
{"Green", {0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f}, SKINCOLOR_RED, 6, V_GREENMAP, true}, // SKINCOLOR_GREEN
{"Forest", {0x65, 0x66, 0x67, 0x68, 0x69, 0x69, 0x6a, 0x6b, 0x6b, 0x6c, 0x6d, 0x6d, 0x6e, 0x6e, 0x6e, 0x6f}, SKINCOLOR_SALMON, 9, V_GREENMAP, true}, // SKINCOLOR_FOREST
{"Shamrock", {0x70, 0x70, 0x71, 0x71, 0x72, 0x72, 0x73, 0x73, 0x73, 0x74, 0x75, 0x75, 0x76, 0x76, 0x77, 0x77}, SKINCOLOR_CRYSTAL, 10, V_GREENMAP, true}, // SKINCOLOR_SHAMROCK
{"Jade", { 128, 120, 121, 122, 122, 113, 114, 114, 115, 116, 117, 118, 119, 110, 111, 30}, SKINCOLOR_ROSY, 7, V_GREENMAP, true}, // SKINCOLOR_JADE
{"Headlight", { 0, 80, 81, 82, 73, 84, 64, 65, 91, 91, 124, 125, 126, 137, 138, 139}, SKINCOLOR_LAVENDER, 10, V_YELLOWMAP, true}, // SKINCOLOR_HEADLIGHT
{"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
{"Master", { 0, 80, 88, 96, 112, 113, 99, 100, 124, 125, 126, 117, 107, 118, 119, 111}, SKINCOLOR_RED, 6, V_GREENMAP, true}, // SKINCOLOR_MASTER
{"Master", { 0, 80, 88, 96, 112, 113, 99, 100, 124, 125, 126, 117, 107, 118, 119, 111}, SKINCOLOR_PEPPER, 8, V_GREENMAP, true}, // SKINCOLOR_MASTER
{"Emerald", { 80, 96, 112, 113, 114, 114, 125, 125, 126, 126, 137, 137, 138, 138, 139, 139}, SKINCOLOR_RUBY, 9, V_GREENMAP, true}, // SKINCOLOR_EMERALD
{"Bottle", { 0, 1, 3, 4, 5, 140, 141, 141, 124, 125, 126, 127, 118, 119, 111, 111}, SKINCOLOR_LATTE, 14, V_AQUAMAP, true}, // SKINCOLOR_BOTTLE
{"Seafoam", {0x01, 0x58, 0x59, 0x5a, 0x7c, 0x7d, 0x7d, 0x7e, 0x7e, 0x8f, 0x8f, 0x8a, 0x8a, 0x8b, 0xfd, 0xfd}, SKINCOLOR_PLUM, 6, V_AQUAMAP, true}, // SKINCOLOR_SEAFOAM
{"Island", { 96, 97, 113, 113, 114, 124, 142, 136, 136, 150, 151, 153, 168, 168, 169, 169}, SKINCOLOR_GALAXY, 7, V_AQUAMAP, true}, // SKINCOLOR_ISLAND
{"Aqua", {0x78, 0x79, 0x7a, 0x7a, 0x7b, 0x7b, 0x7c, 0x7c, 0x7c, 0x7d, 0x7e, 0x7e, 0x7f, 0x7f, 0x76, 0x77}, SKINCOLOR_TAFFY, 10, V_AQUAMAP, true}, // SKINCOLOR_AQUA
{"Bottle", { 0, 1, 3, 4, 5, 140, 141, 141, 124, 125, 126, 127, 118, 119, 111, 111}, SKINCOLOR_LATTE, 14, V_AQUAMAP, true}, // SKINCOLOR_BOTTLE
{"Aqua", {0x78, 0x79, 0x7a, 0x7a, 0x7b, 0x7b, 0x7c, 0x7c, 0x7c, 0x7d, 0x7e, 0x7e, 0x7f, 0x7f, 0x76, 0x77}, SKINCOLOR_ROSY, 7, V_AQUAMAP, true}, // SKINCOLOR_AQUA
{"Teal", {0x78, 0x78, 0x8c, 0x8c, 0x8d, 0x8d, 0x8d, 0x8e, 0x8e, 0x8f, 0x8f, 0x8f, 0x8a, 0x8a, 0x8a, 0x8a}, SKINCOLOR_PEACHY, 7, V_SKYMAP, true}, // SKINCOLOR_TEAL
{"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
@ -21661,12 +21661,12 @@ skincolor_t skincolors[MAXSKINCOLORS] = {
{"Dream", { 80, 208, 200, 200, 146, 146, 133, 134, 135, 136, 137, 138, 139, 139, 254, 254}, SKINCOLOR_FOUNDATION, 9, V_SKYMAP, true}, // SKINCOLOR_DREAM
{"Icy", {0x00, 0x00, 0x00, 0x00, 0x80, 0x81, 0x83, 0x83, 0x86, 0x87, 0x95, 0x95, 0xad, 0xad, 0xae, 0xaf}, SKINCOLOR_CRIMSON, 0, V_SKYMAP, true}, // SKINCOLOR_ICY
{"Daybreak", { 80, 81, 82, 72, 64, 9, 11, 171, 149, 150, 151, 153, 156, 157, 159, 253}, SKINCOLOR_EVENTIDE, 12, V_BLUEMAP, true}, // SKINCOLOR_DAYBREAK
{"Sapphire", {0x80, 0x82, 0x86, 0x87, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xfd, 0xfe}, SKINCOLOR_SUNSET, 5, V_SKYMAP, true}, // SKINCOLOR_SAPPHIRE
{"Arctic", { 0, 1, 3, 4, 146, 146, 147, 148, 148, 149, 150, 153, 156, 159, 253, 254}, SKINCOLOR_PUMPKIN, 6, V_BLUEMAP, true}, // SKINCOLOR_ARCTIC
{"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", { 145, 147, 149, 150, 151, 153, 154, 155, 156, 157, 158, 159, 253, 253, 254, 254}, SKINCOLOR_PERIDOT, 5, V_BLUEMAP, true}, // SKINCOLOR_COBALT
{"Midnight", { 171, 171, 172, 173, 173, 174, 155, 156, 157, 159, 253, 253, 254, 254, 31, 31}, SKINCOLOR_CHERRY, 10, V_GRAYMAP, true}, // SKINCOLOR_MIDNIGHT
{"Midnight", { 171, 171, 172, 173, 173, 174, 175, 157, 158, 159, 253, 253, 254, 254, 31, 31}, SKINCOLOR_CHERRY, 10, V_GRAYMAP, true}, // SKINCOLOR_MIDNIGHT
{"Galaxy", { 160, 161, 162, 163, 164, 165, 166, 166, 154, 155, 156, 157, 159, 253, 254, 31}, SKINCOLOR_ISLAND, 7, V_PURPLEMAP, true}, // SKINCOLOR_GALAXY
{"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
@ -21676,21 +21676,21 @@ skincolor_t skincolors[MAXSKINCOLORS] = {
{"Noble", { 144, 146, 147, 148, 149, 164, 164, 165, 166, 185, 186, 186, 187, 187, 28, 29}, SKINCOLOR_CHARTREUSE, 12, V_PURPLEMAP, true}, // SKINCOLOR_NOBLE
{"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
{"Crystal", { 252, 177, 179, 180, 181, 181, 182, 182, 183, 164, 166, 167, 167, 168, 169, 159}, SKINCOLOR_EMERALD, 8, V_MAGENTAMAP, true}, // SKINCOLOR_CRYSTAL
{"Siberite", { 252, 177, 179, 180, 181, 181, 182, 182, 183, 164, 166, 167, 167, 168, 169, 159}, SKINCOLOR_EMERALD, 8, V_MAGENTAMAP, true}, // SKINCOLOR_SIBERITE
{"Magenta", {0xb3, 0xb3, 0xb4, 0xb5, 0xb6, 0xb6, 0xb7, 0xb7, 0xb7, 0xb8, 0xb9, 0xb9, 0xba, 0xba, 0xbb, 0xbb}, SKINCOLOR_LIME, 6, V_MAGENTAMAP, true}, // SKINCOLOR_MAGENTA
{"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_GOLD, 4, V_PURPLEMAP, true}, // SKINCOLOR_MAUVE
{"Mauve", { 176, 177, 178, 192, 193, 194, 195, 195, 196, 185, 185, 186, 186, 187, 187, 253}, SKINCOLOR_HEADLIGHT, 8, V_PURPLEMAP, true}, // SKINCOLOR_MAUVE
{"Eventide", { 51, 52, 53, 33, 34, 204, 183, 183, 184, 184, 166, 167, 168, 169, 253, 254}, SKINCOLOR_DAYBREAK, 13, V_MAGENTAMAP, true}, // SKINCOLOR_EVENTIDE
{"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_AQUA, 1, V_ROSYMAP, true}, // SKINCOLOR_TAFFY
{"Rosy", {0xfc, 0xc8, 0xc8, 0xc9, 0xc9, 0xca, 0xca, 0xcb, 0xcb, 0xcc, 0xcc, 0xcd, 0xcd, 0xce, 0xce, 0xcf}, SKINCOLOR_JADE, 8, V_ROSYMAP, true}, // SKINCOLOR_ROSY
{"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", { 35, 38, 41, 42, 44, 46, 46, 169, 169, 159, 253, 254, 30, 30, 31, 31}, SKINCOLOR_BRONZE, 9, V_REDMAP, true}, // SKINCOLOR_VOLCANIC
{"Volcanic", { 54, 36, 42, 44, 45, 46, 46, 47, 28, 253, 253, 254, 254, 30, 31, 31}, SKINCOLOR_BRONZE, 9, V_REDMAP, true}, // SKINCOLOR_VOLCANIC
// super
{"Super 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

@ -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,7 +1079,8 @@ static int lib_pZMovement(lua_State *L)
if (!actor)
return LUA_ErrInvalid(L, "mobj_t");
lua_pushboolean(L, P_ZMovement(actor));
P_CheckPosition(actor, actor->x, actor->y);
if (!P_MobjWasRemoved(actor))
P_CheckPosition(actor, actor->x, actor->y);
P_SetTarget(&tmthing, ptmthing);
return 1;
}
@ -1106,7 +1108,8 @@ static int lib_pSceneryZMovement(lua_State *L)
if (!actor)
return LUA_ErrInvalid(L, "mobj_t");
lua_pushboolean(L, P_SceneryZMovement(actor));
P_CheckPosition(actor, actor->x, actor->y);
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);
@ -3541,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;
@ -3549,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);
@ -3823,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
@ -3832,18 +3833,21 @@ static int lib_gSetCustomExitVars(lua_State *L)
// LUA EXTENSION: Custom exit like support
// Supported:
// G_SetCustomExitVars(); [reset to defaults]
// G_SetCustomExitVars(int) [nextmap override only]
// G_SetCustomExitVars(nil, int) [skipstats only]
// G_SetCustomExitVars(int, int) [both of the above]
// G_SetCustomExitVars(); [reset to defaults]
// 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;

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

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

@ -282,7 +282,6 @@ static int patch_get(lua_State *L)
patch_t *patch = *((patch_t **)luaL_checkudata(L, 1, META_PATCH));
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);
@ -436,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;
}
@ -1256,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;
}
@ -1268,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;
}
@ -1496,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);
}
}

View file

@ -177,9 +177,18 @@ static const char *CopyString(huddrawlist_h list, const char* str)
lenstr = strlen(str);
if (list->strbuf_capacity <= list->strbuf_len + lenstr + 1)
{
const char *old_offset = list->strbuf;
size_t i;
if (list->strbuf_capacity == 0) list->strbuf_capacity = 256;
else list->strbuf_capacity *= 2;
list->strbuf = (char*) Z_Realloc(list->strbuf, sizeof(char) * list->strbuf_capacity, PU_STATIC, NULL);
// align the string pointers to make sure old pointers don't point towards invalid addresses
// this is necessary since Z_ReallocAlign might actually move the string buffer in memory
for (i = 0; i < list->items_len; i++)
{
list->items[i].str += list->strbuf - old_offset;
}
}
const char *result = (const char *) &list->strbuf[list->strbuf_len];
strncpy(&list->strbuf[list->strbuf_len], str, lenstr + 1);

View file

@ -508,8 +508,6 @@ static int pivotlist_get(lua_State *L)
const char *field = luaL_checkstring(L, 2);
UINT8 frame;
I_Assert(framepivot != NULL);
frame = R_Char2Frame(field[0]);
if (frame == 255)
luaL_error(L, "invalid frame %s", field);
@ -539,8 +537,6 @@ static int pivotlist_set(lua_State *L)
if (hook_cmd_running)
return luaL_error(L, "Do not alter spriteframepivot_t in CMD building code!");
I_Assert(pivotlist != NULL);
frame = R_Char2Frame(field[0]);
if (frame == 255)
luaL_error(L, "invalid frame %s", field);
@ -1750,7 +1746,7 @@ static int lib_setSkinColor(lua_State *L)
else if (i == 6 || (str && fastcmp(str,"accessible"))) {
boolean v = lua_toboolean(L, 3);
if (cnum < FIRSTSUPERCOLOR && v != skincolors[cnum].accessible)
return luaL_error(L, "skincolors[] index %d is a standard color; accessibility changes are prohibited.", cnum);
CONS_Alert(CONS_WARNING, "skincolors[] index %d is a standard color; accessibility changes are prohibited.", cnum);
else
info->accessible = v;
}
@ -1845,7 +1841,7 @@ static int skincolor_set(lua_State *L)
else if (fastcmp(field,"accessible")) {
boolean v = lua_toboolean(L, 3);
if (cnum < FIRSTSUPERCOLOR && v != skincolors[cnum].accessible)
return luaL_error(L, "skincolors[] index %d is a standard color; accessibility changes are prohibited.", cnum);
CONS_Alert(CONS_WARNING, "skincolors[] index %d is a standard color; accessibility changes are prohibited.", cnum);
else
info->accessible = v;
} else

View file

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

View file

@ -44,6 +44,8 @@ enum mobj_e {
mobj_spritexoffset,
mobj_spriteyoffset,
mobj_floorspriteslope,
mobj_drawonlyforplayer,
mobj_dontdrawforviewmobj,
mobj_touching_sectorlist,
mobj_subsector,
mobj_floorz,
@ -122,6 +124,8 @@ static const char *const mobj_opt[] = {
"spritexoffset",
"spriteyoffset",
"floorspriteslope",
"drawonlyforplayer",
"dontdrawforviewmobj",
"touching_sectorlist",
"subsector",
"floorz",
@ -262,6 +266,17 @@ static int mobj_get(lua_State *L)
case mobj_floorspriteslope:
LUA_PushUserdata(L, mo->floorspriteslope, META_SLOPE);
break;
case mobj_drawonlyforplayer:
LUA_PushUserdata(L, mo->drawonlyforplayer, META_PLAYER);
break;
case mobj_dontdrawforviewmobj:
if (mo->dontdrawforviewmobj && P_MobjWasRemoved(mo->dontdrawforviewmobj))
{ // don't put invalid mobj back into Lua.
P_SetTarget(&mo->dontdrawforviewmobj, NULL);
return 0;
}
LUA_PushUserdata(L, mo->dontdrawforviewmobj, META_MOBJ);
break;
case mobj_touching_sectorlist:
return UNIMPLEMENTED;
case mobj_subsector:
@ -551,6 +566,24 @@ static int mobj_set(lua_State *L)
break;
case mobj_floorspriteslope:
return NOSET;
case mobj_drawonlyforplayer:
if (lua_isnil(L, 3))
mo->drawonlyforplayer = NULL;
else
{
player_t *drawonlyforplayer = *((player_t **)luaL_checkudata(L, 3, META_PLAYER));
mo->drawonlyforplayer = drawonlyforplayer;
}
break;
case mobj_dontdrawforviewmobj:
if (lua_isnil(L, 3))
P_SetTarget(&mo->dontdrawforviewmobj, NULL);
else
{
mobj_t *dontdrawforviewmobj = *((mobj_t **)luaL_checkudata(L, 3, META_MOBJ));
P_SetTarget(&mo->dontdrawforviewmobj, dontdrawforviewmobj);
}
break;
case mobj_touching_sectorlist:
return UNIMPLEMENTED;
case mobj_subsector:
@ -892,6 +925,8 @@ enum mapthing_e {
mapthing_type,
mapthing_options,
mapthing_scale,
mapthing_spritexscale,
mapthing_spriteyscale,
mapthing_z,
mapthing_extrainfo,
mapthing_tag,
@ -911,6 +946,8 @@ const char *const mapthing_opt[] = {
"type",
"options",
"scale",
"spritexscale",
"spriteyscale",
"z",
"extrainfo",
"tag",
@ -966,7 +1003,13 @@ static int mapthing_get(lua_State *L)
lua_pushinteger(L, mt->options);
break;
case mapthing_scale:
lua_pushinteger(L, mt->scale);
lua_pushfixed(L, mt->scale);
break;
case mapthing_spritexscale:
lua_pushfixed(L, mt->spritexscale);
break;
case mapthing_spriteyscale:
lua_pushfixed(L, mt->spriteyscale);
break;
case mapthing_z:
lua_pushinteger(L, mt->z);
@ -1039,6 +1082,12 @@ static int mapthing_set(lua_State *L)
case mapthing_scale:
mt->scale = luaL_checkfixed(L, 3);
break;
case mapthing_spritexscale:
mt->spritexscale = luaL_checkfixed(L, 3);
break;
case mapthing_spriteyscale:
mt->spriteyscale = luaL_checkfixed(L, 3);
break;
case mapthing_z:
mt->z = (INT16)luaL_checkinteger(L, 3);
break;

View file

@ -28,7 +28,7 @@
#include "p_slopes.h" // for P_SlopeById and slopelist
#include "p_polyobj.h" // polyobj_t, PolyObjects
#ifdef LUA_ALLOW_BYTECODE
#include "d_netfil.h" // for LUA_DumpFile
#include "netcode/d_netfil.h" // for LUA_DumpFile
#endif
#include "lua_script.h"
@ -225,6 +225,18 @@ int LUA_PushGlobals(lua_State *L, const char *word)
} else if (fastcmp(word,"pointlimit")) {
lua_pushinteger(L, cv_pointlimit.value);
return 1;
} else if (fastcmp(word, "redflag")) {
LUA_PushUserdata(L, redflag, META_MOBJ);
return 1;
} else if (fastcmp(word, "blueflag")) {
LUA_PushUserdata(L, blueflag, META_MOBJ);
return 1;
} else if (fastcmp(word, "rflagpoint")) {
LUA_PushUserdata(L, rflagpoint, META_MAPTHING);
return 1;
} else if (fastcmp(word, "bflagpoint")) {
LUA_PushUserdata(L, bflagpoint, META_MAPTHING);
return 1;
// begin map vars
} else if (fastcmp(word,"spstage_start")) {
lua_pushinteger(L, spstage_start);
@ -977,6 +989,7 @@ enum
ARCH_MAPHEADER,
ARCH_SKINCOLOR,
ARCH_MOUSE,
ARCH_SKIN,
ARCH_TEND=0xFF,
};
@ -1005,6 +1018,7 @@ static const struct {
{META_MAPHEADER, ARCH_MAPHEADER},
{META_SKINCOLOR, ARCH_SKINCOLOR},
{META_MOUSE, ARCH_MOUSE},
{META_SKIN, ARCH_SKIN},
{NULL, ARCH_NULL}
};
@ -1326,6 +1340,13 @@ static UINT8 ArchiveValue(int TABLESINDEX, int myindex)
WRITEUINT8(save_p, m == &mouse ? 1 : 2);
break;
}
case ARCH_SKIN:
{
skin_t *skin = *((skin_t **)lua_touserdata(gL, myindex));
WRITEUINT8(save_p, ARCH_SKIN);
WRITEUINT8(save_p, skin - skins); // UINT8 because MAXSKINS is only 32
break;
}
default:
WRITEUINT8(save_p, ARCH_NULL);
return 2;
@ -1572,6 +1593,9 @@ static UINT8 UnArchiveValue(int TABLESINDEX)
case ARCH_MOUSE:
LUA_PushUserdata(gL, READUINT16(save_p) == 1 ? &mouse : &mouse2, META_MOUSE);
break;
case ARCH_SKIN:
LUA_PushUserdata(gL, &skins[READUINT8(save_p)], META_SKIN);
break;
case ARCH_TEND:
return 1;
}

View file

@ -25,6 +25,7 @@ enum skin {
skin_flags,
skin_realname,
skin_hudname,
skin_supername,
skin_ability,
skin_ability2,
skin_thokitem,
@ -63,6 +64,7 @@ static const char *const skin_opt[] = {
"flags",
"realname",
"hudname",
"supername",
"ability",
"ability2",
"thokitem",
@ -126,6 +128,9 @@ static int skin_get(lua_State *L)
case skin_hudname:
lua_pushstring(L, skin->hudname);
break;
case skin_supername:
lua_pushstring(L, skin->supername);
break;
case skin_ability:
lua_pushinteger(L, skin->ability);
break;
@ -334,13 +339,13 @@ static const char *const sprites_opt[] = {
// skin.sprites[i] -> sprites[i]
static int lib_getSkinSprite(lua_State *L)
{
spritedef_t *sprites = *(spritedef_t **)luaL_checkudata(L, 1, META_SKINSPRITES);
spritedef_t *sksprites = *(spritedef_t **)luaL_checkudata(L, 1, META_SKINSPRITES);
playersprite_t i = luaL_checkinteger(L, 2);
if (i < 0 || i >= NUMPLAYERSPRITES*2)
return luaL_error(L, LUA_QL("skin_t") " field 'sprites' index %d out of range (0 - %d)", i, (NUMPLAYERSPRITES*2)-1);
LUA_PushUserdata(L, &sprites[i], META_SKINSPRITESLIST);
LUA_PushUserdata(L, &sksprites[i], META_SKINSPRITESLIST);
return 1;
}

View file

@ -19,7 +19,7 @@
#include "r_local.h"
#include "p_local.h"
#include "p_setup.h"
#include "d_net.h"
#include "netcode/d_net.h"
#include "m_cheat.h"
#include "m_menu.h"
@ -1102,6 +1102,8 @@ static mapthing_t *OP_CreateNewMapThing(player_t *player, UINT16 type, boolean c
mt->options = (mt->z << ZSHIFT) | (UINT16)cv_opflags.value;
mt->scale = player->mo->scale;
mt->spritexscale = player->mo->spritexscale;
mt->spriteyscale = player->mo->spriteyscale;
memset(mt->args, 0, NUMMAPTHINGARGS*sizeof(*mt->args));
memset(mt->stringargs, 0x00, NUMMAPTHINGSTRINGARGS*sizeof(*mt->stringargs));
mt->pitch = mt->roll = 0;

View file

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

View file

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

View file

@ -21,50 +21,6 @@
#include "doomdef.h"
#include "m_fixed.h"
#ifdef __USE_C_FIXEDMUL__
/** \brief The FixedMul function
\param a fixed_t number
\param b fixed_t number
\return a*b>>FRACBITS
*/
fixed_t FixedMul(fixed_t a, fixed_t b)
{
// Need to cast to unsigned before shifting to avoid undefined behaviour
// for negative integers
return (fixed_t)(((UINT64)((INT64)a * b)) >> FRACBITS);
}
#endif //__USE_C_FIXEDMUL__
#ifdef __USE_C_FIXEDDIV__
/** \brief The FixedDiv2 function
\param a fixed_t number
\param b fixed_t number
\return a/b * FRACUNIT
*/
fixed_t FixedDiv2(fixed_t a, fixed_t b)
{
INT64 ret;
if (b == 0)
I_Error("FixedDiv: divide by zero");
ret = (((INT64)a * FRACUNIT)) / b;
if ((ret > INT32_MAX) || (ret < INT32_MIN))
I_Error("FixedDiv: divide by zero");
return (fixed_t)ret;
}
#endif // __USE_C_FIXEDDIV__
fixed_t FixedSqrt(fixed_t x)
{
#ifdef HAVE_SQRT

View file

@ -53,127 +53,35 @@ FUNCMATH FUNCINLINE static ATTRINLINE fixed_t FloatToFixed(float f)
#define FIXED_TO_FLOAT(x) FixedToFloat(x) // (((float)(x)) / ((float)FRACUNIT))
#define FLOAT_TO_FIXED(f) FloatToFixed(f) // (fixed_t)((f) * ((float)FRACUNIT))
/** \brief The FixedMul function
#if defined (__WATCOMC__) && FRACBITS == 16
#pragma aux FixedMul = \
"imul ebx", \
"shrd eax,edx,16" \
parm [eax] [ebx] \
value [eax] \
modify exact [eax edx]
\param a fixed_t number
\param b fixed_t number
#pragma aux FixedDiv2 = \
"cdq", \
"shld edx,eax,16", \
"sal eax,16", \
"idiv ebx" \
parm [eax] [ebx] \
value [eax] \
modify exact [eax edx]
#elif defined (__GNUC__) && defined (__i386__) && !defined (NOASM)
// i386 linux, cygwin or mingw
FUNCMATH FUNCINLINE static inline fixed_t FixedMul(fixed_t a, fixed_t b) // asm
{
fixed_t ret;
asm
(
"imull %2;" // a*b
"shrdl %3,%%edx,%0;" // shift logical right FRACBITS bits
:"=a" (ret) // eax is always the result and the first operand (%0,%1)
:"0" (a), "r" (b) // and %2 is what we use imull on with what in %1
, "I" (FRACBITS) // %3 holds FRACBITS (normally 16)
:"cc", "%edx" // edx and condition codes clobbered
);
return ret;
}
\return a*b>>FRACBITS
FUNCMATH FUNCINLINE static inline fixed_t FixedDiv2(fixed_t a, fixed_t b)
{
fixed_t ret;
asm
(
"movl %1,%%edx;" // these two instructions allow the next two to pair, on the Pentium processor.
"sarl $31,%%edx;" // shift arithmetic right 31 on EDX
"shldl %3,%1,%%edx;" // DP shift logical left FRACBITS on EDX
"sall %3,%0;" // shift arithmetic left FRACBITS on EAX
"idivl %2;" // EDX/b = EAX
: "=a" (ret)
: "0" (a), "r" (b)
, "I" (FRACBITS)
: "%edx"
);
return ret;
}
#elif defined (__GNUC__) && defined (__arm__) && !defined(__thumb__) && !defined(NOASM) //ARMv4 ASM
FUNCMATH FUNCINLINE static inline fixed_t FixedMul(fixed_t a, fixed_t b) // let abuse smull
{
fixed_t ret;
asm
(
"smull %[lo], r1, %[a], %[b];"
"mov %[lo], %[lo], lsr %3;"
"orr %[lo], %[lo], r1, lsl %3;"
: [lo] "=&r" (ret) // rhi, rlo and rm must be distinct registers
: [a] "r" (a), [b] "r" (b)
, "i" (FRACBITS)
: "r1"
);
return ret;
}
*/
FUNCMATH FUNCINLINE static ATTRINLINE fixed_t FixedMul(fixed_t a, fixed_t b)
{
// Need to cast to unsigned before shifting to avoid undefined behaviour
// for negative integers
return (fixed_t)(((UINT64)((INT64)a * b)) >> FRACBITS);
}
#define __USE_C_FIXEDDIV__ // no double or asm div in ARM land
#elif defined (__GNUC__) && defined (__ppc__) && !defined(NOASM) && 0 // WII: PPC CPU
FUNCMATH FUNCINLINE static inline fixed_t FixedMul(fixed_t a, fixed_t b) // asm
{
fixed_t ret, hi, lo;
asm
(
"mullw %0, %2, %3;"
"mulhw %1, %2, %3"
: "=r" (hi), "=r" (lo)
: "r" (a), "r" (b)
, "I" (FRACBITS)
);
ret = (INT64)((hi>>FRACBITS)+lo)<<FRACBITS;
return ret;
}
/** \brief The FixedDiv2 function
#define __USE_C_FIXEDDIV__// Alam: I am lazy
#elif defined (__GNUC__) && defined (__mips__) && !defined(NOASM) && 0 // PSP: MIPS CPU
FUNCMATH FUNCINLINE static inline fixed_t FixedMul(fixed_t a, fixed_t b) // asm
{
fixed_t ret;
asm
(
"mult %3, %4;" // a*b=h<32+l
: "=r" (ret), "=l" (a), "=h" (b) //todo: abuse shr opcode
: "0" (a), "r" (b)
, "I" (FRACBITS)
//: "+l", "+h"
);
ret = (INT64)((a>>FRACBITS)+b)<<FRACBITS;
return ret;
}
\param a fixed_t number
\param b fixed_t number
#define __USE_C_FIXEDDIV__ // no 64b asm div in MIPS land
#elif defined (__GNUC__) && defined (__sh__) && 0 // DC: SH4 CPU
#elif defined (__GNUC__) && defined (__m68k__) && 0 // DEAD: Motorola 6800 CPU
#elif defined (_MSC_VER) && defined(USEASM) && FRACBITS == 16
// Microsoft Visual C++ (no asm inline)
fixed_t __cdecl FixedMul(fixed_t a, fixed_t b);
fixed_t __cdecl FixedDiv2(fixed_t a, fixed_t b);
#else
#define __USE_C_FIXEDMUL__
#define __USE_C_FIXEDDIV__
#endif
\return a/b * FRACUNIT
#ifdef __USE_C_FIXEDMUL__
FUNCMATH fixed_t FixedMul(fixed_t a, fixed_t b);
#endif
#ifdef __USE_C_FIXEDDIV__
FUNCMATH fixed_t FixedDiv2(fixed_t a, fixed_t b);
#endif
*/
FUNCMATH FUNCINLINE static ATTRINLINE fixed_t FixedDiv2(fixed_t a, fixed_t b)
{
// This does not check for division overflow or division by 0!
// That is the caller's responsibility.
return (fixed_t)(((INT64)a * FRACUNIT) / b);
}
/** \brief The FixedInt function

View file

@ -20,7 +20,7 @@
#include "doomdef.h"
#include "d_main.h"
#include "d_netcmd.h"
#include "netcode/d_netcmd.h"
#include "console.h"
#include "r_fps.h"
#include "r_local.h"
@ -53,8 +53,10 @@
#include "hardware/hw_main.h"
#endif
#include "d_net.h"
#include "mserv.h"
#include "netcode/d_net.h"
#include "netcode/mserv.h"
#include "netcode/server_connection.h"
#include "netcode/client_connection.h"
#include "m_misc.h"
#include "m_anigif.h"
#include "byteptr.h"
@ -149,9 +151,7 @@ levellist_mode_t levellistmode = LLM_CREATESERVER;
UINT8 maplistoption = 0;
static char joystickInfo[MAX_JOYSTICKS+1][29];
#ifndef NONET
static UINT32 serverlistpage;
#endif
static UINT8 numsaves = 0;
static saveinfo_t* savegameinfo = NULL; // Extra info about the save games.
@ -190,10 +190,8 @@ static void M_GoBack(INT32 choice);
static void M_StopMessage(INT32 choice);
static boolean stopstopmessage = false;
#ifndef NONET
static void M_HandleServerPage(INT32 choice);
static void M_RoomMenu(INT32 choice);
#endif
// Prototyping is fun, innit?
// ==========================================================================
@ -296,7 +294,6 @@ static void M_SetupMultiPlayer2(INT32 choice);
static void M_StartSplitServerMenu(INT32 choice);
static void M_StartServer(INT32 choice);
static void M_ServerOptions(INT32 choice);
#ifndef NONET
static void M_StartServerMenu(INT32 choice);
static void M_ConnectMenu(INT32 choice);
static void M_ConnectMenuModChecks(INT32 choice);
@ -304,7 +301,6 @@ static void M_Refresh(INT32 choice);
static void M_Connect(INT32 choice);
static void M_ChooseRoom(INT32 choice);
menu_t MP_MainDef;
#endif
// Options
// Split into multiple parts due to size
@ -382,11 +378,9 @@ static void M_DrawVideoMode(void);
static void M_DrawColorMenu(void);
static void M_DrawScreenshotMenu(void);
static void M_DrawMonitorToggles(void);
#ifndef NONET
static void M_DrawConnectMenu(void);
static void M_DrawMPMainMenu(void);
static void M_DrawRoomMenu(void);
#endif
static void M_DrawJoystick(void);
static void M_DrawSetupMultiPlayerMenu(void);
static void M_DrawColorRamp(INT32 x, INT32 y, INT32 w, INT32 h, skincolor_t color);
@ -401,10 +395,8 @@ static void M_HandleImageDef(INT32 choice);
static void M_HandleLoadSave(INT32 choice);
static void M_HandleLevelStats(INT32 choice);
static void M_HandlePlaystyleMenu(INT32 choice);
#ifndef NONET
static boolean M_CancelConnect(void);
static void M_HandleConnectIP(INT32 choice);
#endif
static void M_HandleSetupMultiPlayer(INT32 choice);
static void M_HandleVideoMode(INT32 choice);
@ -503,11 +495,7 @@ consvar_t cv_dummyloadless = CVAR_INIT ("dummyloadless", "In-game", CV_HIDEN, lo
static menuitem_t MainMenu[] =
{
{IT_STRING|IT_CALL, NULL, "1 Player", M_SinglePlayerMenu, 76},
#ifndef NONET
{IT_STRING|IT_SUBMENU, NULL, "Multiplayer", &MP_MainDef, 84},
#else
{IT_STRING|IT_CALL, NULL, "Multiplayer", M_StartSplitServerMenu, 84},
#endif
{IT_STRING|IT_CALL, NULL, "Extras", M_SecretsMenu, 92},
{IT_CALL |IT_STRING, NULL, "Addons", M_Addons, 100},
{IT_STRING|IT_CALL, NULL, "Options", M_Options, 108},
@ -930,16 +918,10 @@ static menuitem_t SP_PlayerMenu[] =
static menuitem_t MP_SplitServerMenu[] =
{
{IT_STRING|IT_CALL, NULL, "Select Gametype/Level...", M_MapChange, 100},
#ifdef NONET // In order to keep player setup accessible.
{IT_STRING|IT_CALL, NULL, "Player 1 setup...", M_SetupMultiPlayer, 110},
{IT_STRING|IT_CALL, NULL, "Player 2 setup...", M_SetupMultiPlayer2, 120},
#endif
{IT_STRING|IT_CALL, NULL, "More Options...", M_ServerOptions, 130},
{IT_WHITESTRING|IT_CALL, NULL, "Start", M_StartServer, 140},
};
#ifndef NONET
static menuitem_t MP_MainMenu[] =
{
{IT_HEADER, NULL, "Join a game", NULL, 0},
@ -1026,8 +1008,6 @@ menuitem_t MP_RoomMenu[] =
{IT_DISABLED, NULL, "", M_ChooseRoom, 162},
};
#endif
static menuitem_t MP_PlayerSetupMenu[] =
{
{IT_KEYHANDLER, NULL, "", M_HandleSetupMultiPlayer, 0}, // name
@ -1586,14 +1566,12 @@ enum
static menuitem_t OP_ServerOptionsMenu[] =
{
{IT_HEADER, NULL, "General", NULL, 0},
#ifndef NONET
{IT_STRING | IT_CVAR | IT_CV_STRING,
NULL, "Server name", &cv_servername, 7},
{IT_STRING | IT_CVAR, NULL, "Max Players", &cv_maxplayers, 21},
{IT_STRING | IT_CVAR, NULL, "Allow Add-on Downloading", &cv_downloading, 26},
{IT_STRING | IT_CVAR, NULL, "Allow players to join", &cv_allownewplayer, 31},
{IT_STRING | IT_CVAR, NULL, "Minutes for reconnecting", &cv_rejointimeout, 36},
#endif
{IT_STRING | IT_CVAR, NULL, "Map progression", &cv_advancemap, 41},
{IT_STRING | IT_CVAR, NULL, "Intermission Timer", &cv_inttime, 46},
@ -1632,7 +1610,6 @@ static menuitem_t OP_ServerOptionsMenu[] =
{IT_STRING | IT_CVAR, NULL, "Autobalance sizes", &cv_autobalance, 216},
{IT_STRING | IT_CVAR, NULL, "Scramble on Map Change", &cv_scrambleonchange, 221},
#ifndef NONET
{IT_HEADER, NULL, "Advanced", NULL, 230},
{IT_STRING | IT_CVAR | IT_CV_STRING, NULL, "Master server", &cv_masterserver, 236},
@ -1640,7 +1617,6 @@ static menuitem_t OP_ServerOptionsMenu[] =
{IT_STRING | IT_CVAR, NULL, "Attempts to resynchronise", &cv_resynchattempts, 256},
{IT_STRING | IT_CVAR, NULL, "Show IP Address of Joiners", &cv_showjoinaddress, 261},
#endif
};
static menuitem_t OP_MonitorToggleMenu[] =
@ -1954,11 +1930,7 @@ menu_t MP_SplitServerDef =
MTREE2(MN_MP_MAIN, MN_MP_SPLITSCREEN),
"M_MULTI",
sizeof (MP_SplitServerMenu)/sizeof (menuitem_t),
#ifndef NONET
&MP_MainDef,
#else
&MainDef,
#endif
MP_SplitServerMenu,
M_DrawServerMenu,
27, 30 - 50,
@ -1966,8 +1938,6 @@ menu_t MP_SplitServerDef =
NULL
};
#ifndef NONET
menu_t MP_MainDef =
{
MN_MP_MAIN,
@ -2019,15 +1989,10 @@ menu_t MP_RoomDef =
0,
NULL
};
#endif
menu_t MP_PlayerSetupDef =
{
#ifdef NONET
MTREE2(MN_MP_MAIN, MN_MP_PLAYERSETUP),
#else
MTREE3(MN_MP_MAIN, MN_MP_SPLITSCREEN, MN_MP_PLAYERSETUP),
#endif
"M_SPLAYR",
sizeof (MP_PlayerSetupMenu)/sizeof (menuitem_t),
&MainDef, // doesn't matter
@ -2649,7 +2614,7 @@ static boolean MIT_SetCurBackground(UINT32 menutype, INT32 level, INT32 *retval,
{
strncpy(curbgname, defaultname, 9);
curbgxspeed = (gamestate == GS_TIMEATTACK) ? 0 : titlescrollxspeed;
curbgyspeed = (gamestate == GS_TIMEATTACK) ? 0 : titlescrollyspeed;
curbgyspeed = (gamestate == GS_TIMEATTACK) ? 18 : titlescrollyspeed;
}
}
return false;
@ -2787,6 +2752,7 @@ void M_SetMenuCurBackground(const char *defaultname)
{
char name[9];
strncpy(name, defaultname, 8);
name[8] = '\0';
M_IterateMenuTree(MIT_SetCurBackground, &name);
}
@ -2843,8 +2809,8 @@ static void M_HandleMenuPresState(menu_t *newMenu)
curfadevalue = 16;
curhidepics = hidetitlepics;
curbgcolor = -1;
curbgxspeed = titlescrollxspeed;
curbgyspeed = titlescrollyspeed;
curbgxspeed = (gamestate == GS_TIMEATTACK) ? 0 : titlescrollxspeed;
curbgyspeed = (gamestate == GS_TIMEATTACK) ? 18 : titlescrollyspeed;
curbghide = (gamestate != GS_TIMEATTACK); // show in time attack, hide in other menus
curttmode = ttmode;
@ -3196,7 +3162,7 @@ boolean M_Responder(event_t *ev)
|| gamestate == GS_CREDITS || gamestate == GS_EVALUATION || gamestate == GS_GAMEEND)
return false;
if (gamestate == GS_TITLESCREEN && finalecount < TICRATE)
if (gamestate == GS_TITLESCREEN && finalecount < (cv_tutorialprompt.value ? TICRATE : 0))
return false;
if (CON_Ready() && gamestate != GS_WAITINGPLAYERS)
@ -3500,10 +3466,10 @@ boolean M_Responder(event_t *ev)
#ifndef DEVELOP
// TODO: Replays are scary, so I left the remaining instances of this alone.
// It'd be nice to get rid of this once and for all though!
if (((currentMenu->menuitems[itemOn].status & IT_CALLTYPE) & IT_CALL_NOTMODIFIED) && (modifiedgame && !savemoddata) && !usedCheats)
if (((currentMenu->menuitems[itemOn].status & IT_CALLTYPE) & IT_CALL_NOTMODIFIED) && usedCheats)
{
S_StartSound(NULL, sfx_skid);
M_StartMessage(M_GetText("This cannot be done in a modified game.\n\n(Press a key)\n"), NULL, MM_NOTHING);
M_StartMessage(M_GetText("This cannot be done in a cheated game.\n\n(Press a key)\n"), NULL, MM_NOTHING);
return true;
}
#endif
@ -3956,9 +3922,7 @@ void M_Init(void)
OP_JoystickSetMenu[i].itemaction = M_AssignJoystick;
}
#ifndef NONET
CV_RegisterVar(&cv_serversort);
#endif
}
void M_InitCharacterTables(void)
@ -7100,9 +7064,6 @@ static void M_DestroyRobots(INT32 choice)
static void M_LevelSelectWarp(INT32 choice)
{
boolean fromloadgame = (currentMenu == &SP_LevelSelectDef);
boolean frompause = (currentMenu == &SP_PauseLevelSelectDef);
(void)choice;
if (W_CheckNumForName(G_BuildMapName(cv_nextmap.value)) == LUMPERROR)
@ -7114,13 +7075,11 @@ static void M_LevelSelectWarp(INT32 choice)
startmap = (INT16)(cv_nextmap.value);
fromlevelselect = true;
if (fromloadgame)
G_LoadGame((UINT32)cursaveslot, startmap);
else
if (currentMenu == &SP_LevelSelectDef || currentMenu == &SP_PauseLevelSelectDef)
{
cursaveslot = 0;
if (frompause)
if (cursaveslot > 0) // do we have a save slot to load?
G_LoadGame((UINT32)cursaveslot, startmap); // reload from SP save data: this is needed to keep score/lives/continues from reverting to defaults
else // no save slot, start new game but keep the current skin
{
M_ClearMenus(true);
@ -7131,8 +7090,11 @@ static void M_LevelSelectWarp(INT32 choice)
Z_Free(levelselect.rows);
levelselect.rows = NULL;
}
else
M_SetupChoosePlayer(0);
}
else // start new game
{
cursaveslot = 0;
M_SetupChoosePlayer(0);
}
}
@ -10449,13 +10411,23 @@ static void M_ChooseTimeAttack(INT32 choice)
G_DeferedInitNew(false, G_BuildMapName(cv_nextmap.value), (UINT8)(cv_chooseskin.value-1), false, false);
}
static char ra_demoname[1024];
static void M_StartTimeAttackReplay(INT32 choice)
{
if (choice == 'y' || choice == KEY_ENTER)
{
M_ClearMenus(true);
modeattacking = ATTACKING_RECORD; // set modeattacking before G_DoPlayDemo so the map loader knows
G_DoPlayDemo(ra_demoname);
}
}
// Player has selected the "REPLAY" from the time attack screen
static void M_ReplayTimeAttack(INT32 choice)
{
const char *which;
char *demoname;
M_ClearMenus(true);
modeattacking = ATTACKING_RECORD; // set modeattacking before G_DoPlayDemo so the map loader knows
UINT8 error = DFILE_ERROR_NONE;
if (currentMenu == &SP_ReplayDef)
{
@ -10475,11 +10447,15 @@ static void M_ReplayTimeAttack(INT32 choice)
break;
case 4: // guest
// srb2/replay/main/map01-guest.lmp
G_DoPlayDemo(va("%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s-guest.lmp", srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value)));
return;
snprintf(ra_demoname, 1024, "%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s-guest.lmp", srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value));
break;
}
if (choice != 4)
{
// srb2/replay/main/map01-sonic-time-best.lmp
snprintf(ra_demoname, 1024, "%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s-%s-%s.lmp", srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value), skins[cv_chooseskin.value-1].name, which);
}
// srb2/replay/main/map01-sonic-time-best.lmp
G_DoPlayDemo(va("%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s-%s-%s.lmp", srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value), skins[cv_chooseskin.value-1].name, which));
}
else if (currentMenu == &SP_NightsReplayDef)
{
@ -10495,19 +10471,78 @@ static void M_ReplayTimeAttack(INT32 choice)
which = "last";
break;
case 3: // guest
G_DoPlayDemo(va("%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s-guest.lmp", srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value)));
return;
snprintf(ra_demoname, 1024, "%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s-guest.lmp", srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value));
break;
}
demoname = va("%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s-%s-%s.lmp", srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value), skins[cv_chooseskin.value-1].name, which);
if (choice != 3)
{
snprintf(ra_demoname, 1024, "%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s-%s-%s.lmp", srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value), skins[cv_chooseskin.value-1].name, which);
#ifdef OLDNREPLAYNAME // Check for old style named NiGHTS replay if a new style replay doesn't exist.
if (!FIL_FileExists(demoname))
demoname = va("%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s-%s.lmp", srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value), which);
if (!FIL_FileExists(ra_demoname))
{
snprintf(ra_demoname, 1024, "%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s-%s.lmp", srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value), which);
}
#endif
G_DoPlayDemo(demoname);
}
}
demofileoverride = DFILE_OVERRIDE_NONE;
error = G_CheckDemoForError(ra_demoname);
if (error)
{
S_StartSound(NULL, sfx_skid);
switch (error)
{
case DFILE_ERROR_NOTDEMO:
M_StartMessage(M_GetText("An error occurred loading this replay.\n\n(Press a key)\n"), NULL, MM_NOTHING);
break;
case DFILE_ERROR_NOTLOADED:
demofileoverride = DFILE_OVERRIDE_LOAD;
M_StartMessage(M_GetText("Add-ons for this replay\nhave not been loaded.\n\nAttempt to load files?\n\n(Press 'Y' to confirm)\n"), M_StartTimeAttackReplay, MM_YESNO);
break;
case DFILE_ERROR_OUTOFORDER:
/*
demofileoverride = DFILE_OVERRIDE_SKIP;
M_StartMessage(M_GetText("Add-ons for this replay\nwere loaded out of order.\n\nAttempt to playback anyway?\n\n(Press 'Y' to confirm)\n"), M_StartTimeAttackReplay, MM_YESNO);
*/
M_StartMessage(M_GetText("Add-ons for this replay\nwere loaded out of order.\n\n(Press a key)\n"), NULL, MM_NOTHING);
break;
case DFILE_ERROR_INCOMPLETEOUTOFORDER:
/*
demofileoverride = DFILE_OVERRIDE_LOAD;
M_StartMessage(M_GetText("Add-ons for this replay\nhave not been loaded,\nand some are in the wrong order.\n\nAttempt to load files?\n\n(Press 'Y' to confirm)\n"), M_StartTimeAttackReplay, MM_YESNO);
*/
M_StartMessage(M_GetText("Add-ons for this replay\nhave not been loaded,\nand some are in the wrong order.\n\n(Press a key)\n"), NULL, MM_NOTHING);
break;
case DFILE_ERROR_CANNOTLOAD:
/*
demofileoverride = DFILE_OVERRIDE_SKIP;
M_StartMessage(M_GetText("Add-ons for this replay\ncould not be loaded.\n\nAttempt to playback anyway?\n\n(Press 'Y' to confirm)\n"), M_StartTimeAttackReplay, MM_YESNO);
*/
M_StartMessage(M_GetText("Add-ons for this replay\ncould not be loaded.\n\n(Press a key)\n"), NULL, MM_NOTHING);
break;
case DFILE_ERROR_EXTRAFILES:
/*
demofileoverride = DFILE_OVERRIDE_SKIP;
M_StartMessage(M_GetText("You have more files loaded\nthan the replay does.\n\nAttempt to playback anyway?\n\n(Press 'Y' to confirm)\n"), M_StartTimeAttackReplay, MM_YESNO);
*/
M_StartMessage(M_GetText("You have more files loaded\nthan the replay does.\n\n(Press a key)\n"), NULL, MM_NOTHING);
break;
}
return;
}
M_StartTimeAttackReplay(KEY_ENTER);
}
static void M_EraseGuest(INT32 choice)
@ -11037,7 +11072,6 @@ static void M_EndGame(INT32 choice)
#define S_LINEY(n) currentMenu->y + SERVERHEADERHEIGHT + (n * SERVERLINEHEIGHT)
#ifndef NONET
static UINT32 localservercount;
static void M_HandleServerPage(INT32 choice)
@ -11309,11 +11343,9 @@ static int ServerListEntryComparator_modified(const void *entry1, const void *en
// Default to strcmp.
return strcmp(sa->info.servername, sb->info.servername);
}
#endif
void M_SortServerList(void)
{
#ifndef NONET
switch(cv_serversort.value)
{
case 0: // Ping.
@ -11335,10 +11367,8 @@ void M_SortServerList(void)
qsort(serverlist, serverlistcount, sizeof(serverelem_t), ServerListEntryComparator_gametypename);
break;
}
#endif
}
#ifndef NONET
#ifdef UPDATE_ALERT
static boolean M_CheckMODVersion(int id)
{
@ -11537,7 +11567,6 @@ static void M_ChooseRoom(INT32 choice)
if (currentMenu == &MP_ConnectDef)
M_Refresh(0);
}
#endif //NONET
//===========================================================================
// Start Server Menu
@ -11585,7 +11614,6 @@ static void M_DrawServerMenu(void)
{
M_DrawGenericMenu();
#ifndef NONET
// Room name
if (currentMenu == &MP_ServerDef)
{
@ -11597,15 +11625,10 @@ static void M_DrawServerMenu(void)
V_DrawRightAlignedString(BASEVIDWIDTH - currentMenu->x, currentMenu->y + MP_ServerMenu[mp_server_room].alphaKey,
V_YELLOWMAP, room_list[menuRoomIndex].name);
}
#endif
if (cv_nextmap.value)
{
#ifndef NONET
#define imgheight MP_ServerMenu[mp_server_levelgt].alphaKey
#else
#define imgheight 100
#endif
patch_t *PictureOfLevel;
lumpnum_t lumpnum;
char headerstr[40];
@ -11657,7 +11680,6 @@ static void M_ServerOptions(INT32 choice)
{
(void)choice;
#ifndef NONET
if ((splitscreen && !netgame) || currentMenu == &MP_SplitServerDef)
{
OP_ServerOptionsMenu[ 1].status = IT_GRAYEDOUT; // Server name
@ -11678,7 +11700,6 @@ static void M_ServerOptions(INT32 choice)
OP_ServerOptionsMenu[37].status = IT_STRING | IT_CVAR;
OP_ServerOptionsMenu[38].status = IT_STRING | IT_CVAR;
}
#endif
/* Disable fading because of different menu head. */
if (currentMenu == &OP_MainDef)/* from Options menu */
@ -11690,7 +11711,6 @@ static void M_ServerOptions(INT32 choice)
M_SetupNextMenu(&OP_ServerOptionsDef);
}
#ifndef NONET
static void M_StartServerMenu(INT32 choice)
{
(void)choice;
@ -11957,7 +11977,6 @@ static void M_HandleConnectIP(INT32 choice)
M_ClearMenus(true);
}
}
#endif //!NONET
// ========================
// MULTIPLAYER PLAYER SETUP
@ -11983,6 +12002,136 @@ static INT32 setupm_fakeskin;
static menucolor_t *setupm_fakecolor;
static boolean colorgrid;
#define COLOR_GRID_ROW_SIZE (16)
static UINT16 M_GetColorGridIndex(UINT16 color)
{
menucolor_t *look;
UINT16 i = 0;
if (!skincolors[color].accessible)
{
return 0;
}
for (look = menucolorhead; ; i++, look = look->next)
{
while (!skincolors[look->color].accessible) // skip inaccessible colors
{
if (look == menucolortail)
{
return 0;
}
look = look->next;
}
if (look->color == color)
{
return i;
}
if (look == menucolortail)
{
return 0;
}
}
}
static INT32 M_GridIndexToX(UINT16 index)
{
return (index % COLOR_GRID_ROW_SIZE);
}
static INT32 M_GridIndexToY(UINT16 index)
{
return (index / COLOR_GRID_ROW_SIZE);
}
static UINT16 M_ColorGridLen(void)
{
menucolor_t *look;
UINT16 i = 0;
for (look = menucolorhead; ; i++)
{
do
{
if (look == menucolortail)
{
return i;
}
look = look->next;
}
while (!skincolors[look->color].accessible); // skip inaccessible colors
}
}
static UINT16 M_GridPosToGridIndex(INT32 x, INT32 y)
{
const UINT16 grid_len = M_ColorGridLen();
const UINT16 grid_height = ((grid_len - 1) / COLOR_GRID_ROW_SIZE) + 1;
const UINT16 last_row_len = COLOR_GRID_ROW_SIZE - ((grid_height * COLOR_GRID_ROW_SIZE) - grid_len);
UINT16 row_len = COLOR_GRID_ROW_SIZE;
UINT16 new_index = 0;
while (y < 0)
{
y += grid_height;
}
y = (y % grid_height);
if (y >= grid_height-1 && last_row_len > 0)
{
row_len = last_row_len;
}
while (x < 0)
{
x += row_len;
}
x = (x % row_len);
new_index = (y * COLOR_GRID_ROW_SIZE) + x;
if (new_index >= grid_len)
{
new_index = grid_len - 1;
}
return new_index;
}
static menucolor_t *M_GridIndexToMenuColor(UINT16 index)
{
menucolor_t *look = menucolorhead;
UINT16 i = 0;
for (look = menucolorhead; ; i++, look = look->next)
{
while (!skincolors[look->color].accessible) // skip inaccessible colors
{
if (look == menucolortail)
{
return menucolorhead;
}
look = look->next;
}
if (i == index)
{
return look;
}
if (look == menucolortail)
{
return menucolorhead;
}
}
}
static void M_DrawSetupMultiPlayerMenu(void)
{
INT32 x, y, cursory = 0, flags = 0;
@ -12101,32 +12250,54 @@ colordraw:
boolean stoprow = false;
menucolor_t *mc; // Last accessed color
const UINT16 grid_len = M_ColorGridLen();
const UINT16 grid_end_y = M_GridIndexToY(grid_len - 1);
INT32 grid_select = M_GetColorGridIndex(setupm_fakecolor->color);
INT32 grid_select_y = M_GridIndexToY(grid_select);
x = 132;
y = 66;
pos = min(max(0, 16*((M_GetColorIndex(setupm_fakecolor->color)-1)/16) - 64), 16*(M_GetColorIndex(menucolortail->color)/16-1) - 128);
mc = M_GetColorFromIndex(pos);
pos = M_GridPosToGridIndex(0, max(0, min(grid_select_y - 3, grid_end_y - 7)));
mc = M_GridIndexToMenuColor(pos);
// Draw grid
V_DrawFill(x-2, y-2, 132, 132, 159);
for (j = 0; j < 8; j++)
{
for (i = 0; i < 16; i++)
for (i = 0; i < COLOR_GRID_ROW_SIZE; i++)
{
if (skincolors[mc->color].accessible && !stoprow)
if (skincolors[mc->color].accessible)
{
M_DrawColorRamp(x + i*w, y + j*16, w, 1, skincolors[mc->color]);
if (mc->color == setupm_fakecolor->color) // store current color position
{
cx = x + i*w;
cy = y + j*16;
}
if (mc == setupm_fakecolor) // store current color position
{
cx = x + i*w;
cy = y + j*16;
}
}
mc = mc->next;
while (!skincolors[mc->color].accessible && !stoprow) // Find accessible color after this one
if (stoprow)
{
break;
}
// Find accessible color after this one
do
{
mc = mc->next;
if (mc == menucolortail) stoprow = true;
}
if (mc == menucolortail)
{
stoprow = true;
}
} while (!skincolors[mc->color].accessible && !stoprow);
}
if (stoprow)
{
break;
}
}
@ -12247,15 +12418,16 @@ static void M_HandleSetupMultiPlayer(INT32 choice)
case KEY_DOWNARROW:
case KEY_UPARROW:
{
UINT8 i;
if (itemOn == 2 && colorgrid)
{
for (i = 0; i < 16; i++)
{
setupm_fakecolor = (choice == KEY_UPARROW) ? setupm_fakecolor->prev : setupm_fakecolor->next;
while (!skincolors[setupm_fakecolor->color].accessible) // skip inaccessible colors
setupm_fakecolor = (choice == KEY_UPARROW) ? setupm_fakecolor->prev : setupm_fakecolor->next;
}
UINT16 index = M_GetColorGridIndex(setupm_fakecolor->color);
INT32 x = M_GridIndexToX(index);
INT32 y = M_GridIndexToY(index);
y += (choice == KEY_UPARROW) ? -1 : 1;
index = M_GridPosToGridIndex(x, y);
setupm_fakecolor = M_GridIndexToMenuColor(index);
}
else if (choice == KEY_UPARROW)
M_PrevOpt();
@ -12282,8 +12454,8 @@ static void M_HandleSetupMultiPlayer(INT32 choice)
}
else if (itemOn == 2) // player color
{
S_StartSound(NULL,sfx_menu1); // Tails
setupm_fakecolor = setupm_fakecolor->prev;
S_StartSound(NULL,sfx_menu1); // Tails
}
break;
@ -12322,8 +12494,8 @@ static void M_HandleSetupMultiPlayer(INT32 choice)
}
else if (itemOn == 2) // player color
{
S_StartSound(NULL,sfx_menu1); // Tails
setupm_fakecolor = setupm_fakecolor->next;
S_StartSound(NULL,sfx_menu1); // Tails
}
break;
@ -12333,13 +12505,28 @@ static void M_HandleSetupMultiPlayer(INT32 choice)
UINT8 i;
if (itemOn == 2) // player color
{
S_StartSound(NULL,sfx_menu1);
for (i = 0; i < (colorgrid ? 64 : 13); i++) // or (282-charw)/(2*indexwidth)
if (colorgrid)
{
setupm_fakecolor = (choice == KEY_PGUP) ? setupm_fakecolor->prev : setupm_fakecolor->next;
while (!skincolors[setupm_fakecolor->color].accessible) // skip inaccessible colors
setupm_fakecolor = (choice == KEY_PGUP) ? setupm_fakecolor->prev : setupm_fakecolor->next;
UINT16 index = M_GetColorGridIndex(setupm_fakecolor->color);
INT32 x = M_GridIndexToX(index);
INT32 y = M_GridIndexToY(index);
y += (choice == KEY_UPARROW) ? -4 : 4;
index = M_GridPosToGridIndex(x, y);
setupm_fakecolor = M_GridIndexToMenuColor(index);
}
else
{
for (i = 0; i < 13; i++) // or (282-charw)/(2*indexwidth)
{
setupm_fakecolor = (choice == KEY_PGUP) ? setupm_fakecolor->prev : setupm_fakecolor->next;
while (!skincolors[setupm_fakecolor->color].accessible) // skip inaccessible colors
setupm_fakecolor = (choice == KEY_PGUP) ? setupm_fakecolor->prev : setupm_fakecolor->next;
}
}
S_StartSound(NULL, sfx_menu1); // Tails
}
}
break;
@ -12369,7 +12556,6 @@ static void M_HandleSetupMultiPlayer(INT32 choice)
}
}
break;
break;
case KEY_DEL:
if (itemOn == 0 && (l = strlen(setupm_name))!=0)
@ -12452,11 +12638,7 @@ static void M_SetupMultiPlayer(INT32 choice)
else
MP_PlayerSetupMenu[1].status = (IT_KEYHANDLER|IT_STRING);
// ditto with colour
if (Playing() && G_GametypeHasTeams())
MP_PlayerSetupMenu[2].status = (IT_GRAYEDOUT);
else
MP_PlayerSetupMenu[2].status = (IT_KEYHANDLER|IT_STRING);
MP_PlayerSetupMenu[2].status = (IT_KEYHANDLER|IT_STRING);
multi_spr2 = P_GetSkinSprite2(&skins[setupm_fakeskin], SPR2_WALK, NULL);
@ -12471,7 +12653,7 @@ static void M_SetupMultiPlayer2(INT32 choice)
multi_frame = 0;
multi_tics = 4*FRACUNIT;
strcpy (setupm_name, cv_playername2.string);
// set for splitscreen secondary player
@ -12497,11 +12679,7 @@ static void M_SetupMultiPlayer2(INT32 choice)
else
MP_PlayerSetupMenu[1].status = (IT_KEYHANDLER | IT_STRING);
// ditto with colour
if (Playing() && G_GametypeHasTeams())
MP_PlayerSetupMenu[2].status = (IT_GRAYEDOUT);
else
MP_PlayerSetupMenu[2].status = (IT_KEYHANDLER|IT_STRING);
MP_PlayerSetupMenu[2].status = (IT_KEYHANDLER|IT_STRING);
multi_spr2 = P_GetSkinSprite2(&skins[setupm_fakeskin], SPR2_WALK, NULL);

View file

@ -20,7 +20,7 @@
#include "command.h"
#include "f_finale.h" // for ttmode_enum
#include "i_threads.h"
#include "mserv.h"
#include "netcode/mserv.h"
#include "r_things.h" // for SKINNAMESIZE
// Compatibility with old-style named NiGHTS replay files.
@ -74,7 +74,7 @@ typedef enum
MN_MP_SERVER,
MN_MP_CONNECT,
MN_MP_ROOM,
MN_MP_PLAYERSETUP, // MP_PlayerSetupDef shared with SPLITSCREEN if #defined NONET
MN_MP_PLAYERSETUP,
MN_MP_SERVER_OPTIONS,
// Options

View file

@ -12,7 +12,7 @@
#include "m_perfstats.h"
#include "v_video.h"
#include "i_video.h"
#include "d_netcmd.h"
#include "netcode/d_netcmd.h"
#include "r_main.h"
#include "i_system.h"
#include "z_zone.h"

View file

@ -3,6 +3,7 @@
// Copyright (C) 1993-1996 by id Software, Inc.
// Copyright (C) 1998-2000 by DooM Legacy Team.
// Copyright (C) 2012-2016 by Matthew "Kaito Sinclaire" Walsh.
// Copyright (C) 2022-2023 by tertu marybig.
// Copyright (C) 1999-2023 by Sonic Team Junior.
//
// This program is free software distributed under the
@ -14,11 +15,122 @@
#include "doomdef.h"
#include "doomtype.h"
#include "i_system.h" // I_GetRandomBytes
#include "m_random.h"
#include "m_fixed.h"
#include "m_cond.h" // totalplaytime
// SFC32 random number generator implementation
typedef struct rnstate_s {
UINT32 data[3];
UINT32 counter;
} rnstate_t;
/** Generate a raw uniform random number using a particular state.
*
* \param state The RNG state to use.
* \return A random UINT32.
*/
static inline UINT32 RandomState_Get32(rnstate_t *state) {
UINT32 result, b, c;
b = state->data[1];
c = state->data[2];
result = state->data[0] + b + state->counter++;
state->data[0] = b ^ (b >> 9);
state->data[1] = c * 9;
state->data[2] = ((c << 21) | (c >> 11)) + result;
return result;
}
/** Seed an SFC32 RNG state with up to 96 bits of seed data.
*
* \param state The RNG state to seed.
* \param seeds A pointer to up to 3 UINT32s to use as seed data.
* \param seed_count The number of seed words.
*/
static inline void RandomState_Seed(rnstate_t *state, UINT32 *seeds, size_t seed_count)
{
size_t i;
state->counter = 1;
for(i = 0; i < 3; i++)
{
UINT32 seed_word;
if(i < seed_count)
seed_word = seeds[i];
else
seed_word = 0;
// For SFC32, seed data should be stored in the state in reverse order.
state->data[2-i] = seed_word;
}
for(i = 0; i < 16; i++)
RandomState_Get32(state);
}
/** Gets a uniform number in the range [0, limit).
* Technique is based on a combination of scaling and rejection sampling
* and is adapted from Daniel Lemire.
*
* \note Any UINT32 is a valid argument for limit.
*
* \param state The RNG state to use.
* \param limit The upper limit of the range.
* \return A UINT32 in the range [0, limit).
*/
static inline UINT32 RandomState_GetKey32(rnstate_t *state, const UINT32 limit)
{
UINT32 raw_random, scaled_lower_word;
UINT64 scaled_random;
// This algorithm won't work correctly if passed a 0.
if (limit == 0) return 0;
raw_random = RandomState_Get32(state);
scaled_random = (UINT64)raw_random * (UINT64)limit;
/*The high bits of scaled_random now contain the number we want, but it is
possible, depending on the number we generated and the value of limit,
that there is bias in the result. The rest of this code is for ensuring
that does not happen.
*/
scaled_lower_word = (UINT32)scaled_random;
// If we're lucky, we can bail out now and avoid the division
if (scaled_lower_word < limit)
{
// Scale the limit to improve the chance of success.
// After this, the first result might turn out to be good enough.
UINT32 scaled_limit;
// An explanation for this trick: scaled_limit should be
// (UINT32_MAX+1)%range, but if that was computed directly the result
// would need to be computed as a UINT64. This trick allows it to be
// computed using 32-bit arithmetic.
scaled_limit = (-limit) % limit;
while (scaled_lower_word < scaled_limit)
{
raw_random = RandomState_Get32(state);
scaled_random = (UINT64)raw_random * (UINT64)limit;
scaled_lower_word = (UINT32)scaled_random;
}
}
return scaled_random >> 32;
}
// The default seed is the hexadecimal digits of pi, though it will be overwritten.
static rnstate_t m_randomstate = {
.data = {0x4A3B6035U, 0x99555606U, 0x6F603421U},
.counter = 16
};
// ---------------------------
// RNG functions (not synched)
@ -31,13 +143,7 @@
*/
fixed_t M_RandomFixed(void)
{
#if RAND_MAX < 65535
// Compensate for insufficient randomness.
fixed_t rndv = (rand()&1)<<15;
return rand()^rndv;
#else
return (rand() & 0xFFFF);
#endif
return RandomState_Get32(&m_randomstate) >> (32-FRACBITS);
}
/** Provides a random byte. Distribution is uniform.
@ -47,7 +153,7 @@ fixed_t M_RandomFixed(void)
*/
UINT8 M_RandomByte(void)
{
return (rand() & 0xFF);
return RandomState_Get32(&m_randomstate) >> 24;
}
/** Provides a random integer for picking random elements from an array.
@ -59,7 +165,22 @@ UINT8 M_RandomByte(void)
*/
INT32 M_RandomKey(INT32 a)
{
return (INT32)((rand()/((float)RAND_MAX+1.0f))*a);
boolean range_is_negative;
INT64 range;
INT32 random_result;
range = a;
range_is_negative = range < 0;
if(range_is_negative)
range = -range;
random_result = RandomState_GetKey32(&m_randomstate, (UINT32)range);
if(range_is_negative)
random_result = -random_result;
return random_result;
}
/** Provides a random integer in a given range.
@ -72,7 +193,46 @@ INT32 M_RandomKey(INT32 a)
*/
INT32 M_RandomRange(INT32 a, INT32 b)
{
return (INT32)((rand()/((float)RAND_MAX+1.0f))*(b-a+1))+a;
if (b < a)
{
INT32 temp;
temp = a;
a = b;
b = temp;
}
const UINT32 spread = b-a+1;
return (INT32)((INT64)RandomState_GetKey32(&m_randomstate, spread) + a);
}
/** Attempts to seed the unsynched RNG from a good random number source
* provided by the operating system.
* \return true on success, false on failure.
*/
boolean M_RandomSeedFromOS(void)
{
UINT32 complete_word_count;
union {
UINT32 words[3];
char bytes[sizeof(UINT32[3])];
} seed_data;
complete_word_count = I_GetRandomBytes((char *)&seed_data.bytes, sizeof(seed_data)) / sizeof(UINT32);
// If we get even 1 word of seed, it's fine, but any less probably is not fine.
if (complete_word_count == 0)
return false;
RandomState_Seed(&m_randomstate, (UINT32 *)&seed_data.words, complete_word_count);
return true;
}
void M_RandomSeed(UINT32 seed)
{
RandomState_Seed(&m_randomstate, &seed, 1);
}
@ -246,10 +406,18 @@ void P_SetRandSeedD(const char *rfile, INT32 rline, UINT32 seed)
}
/** Gets a randomized seed for setting the random seed.
* This function will never return 0, as the current P_Random implementation
* cannot handle a zero seed. Any other seed is equally likely.
*
* \sa P_GetRandSeed
*/
UINT32 M_RandomizedSeed(void)
{
return ((serverGamedata->totalplaytime & 0xFFFF) << 16) | M_RandomFixed();
UINT32 seed;
do {
seed = RandomState_Get32(&m_randomstate);
} while(seed == 0);
return seed;
}

View file

@ -3,6 +3,7 @@
// Copyright (C) 1993-1996 by id Software, Inc.
// Copyright (C) 1998-2000 by DooM Legacy Team.
// Copyright (C) 2012-2016 by Matthew "Kaito Sinclaire" Walsh.
// Copyright (C) 2022-2023 by tertu marybig.
// Copyright (C) 1999-2023 by Sonic Team Junior.
//
// This program is free software distributed under the
@ -29,6 +30,8 @@ fixed_t M_RandomFixed(void);
UINT8 M_RandomByte(void);
INT32 M_RandomKey(INT32 a);
INT32 M_RandomRange(INT32 a, INT32 b);
boolean M_RandomSeedFromOS(void);
void M_RandomSeed(UINT32 a);
// PRNG functions
#ifdef DEBUGRANDOM

View file

@ -0,0 +1,15 @@
target_sources(SRB2SDL2 PRIVATE
d_clisrv.c
server_connection.c
client_connection.c
tic_command.c
net_command.c
gamestate.c
commands.c
d_net.c
d_netcmd.c
d_netfil.c
http-mserv.c
i_tcp.c
mserv.c
)

13
src/netcode/Sourcefile Normal file
View file

@ -0,0 +1,13 @@
d_clisrv.c
server_connection.c
client_connection.c
tic_command.c
net_command.c
gamestate.c
commands.c
d_net.c
d_netcmd.c
d_netfil.c
http-mserv.c
i_tcp.c
mserv.c

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,61 @@
// 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 client_connection.h
/// \brief Client connection handling
#ifndef __D_CLIENT_CONNECTION__
#define __D_CLIENT_CONNECTION__
#include "../doomtype.h"
#include "d_clisrv.h"
#define MAXSERVERLIST (MAXNETNODES-1)
typedef struct
{
SINT8 node;
serverinfo_pak info;
} serverelem_t;
typedef enum
{
CL_SEARCHING,
CL_CHECKFILES,
CL_DOWNLOADFILES,
CL_ASKJOIN,
CL_LOADFILES,
CL_WAITJOINRESPONSE,
CL_DOWNLOADSAVEGAME,
CL_CONNECTED,
CL_ABORTED,
CL_ASKFULLFILELIST,
CL_CONFIRMCONNECT
} cl_mode_t;
extern serverelem_t serverlist[MAXSERVERLIST];
extern UINT32 serverlistcount;
extern cl_mode_t cl_mode;
extern boolean serverisfull; //lets us be aware if the server was full after we check files, but before downloading, so we can ask if the user still wants to download or not
extern tic_t firstconnectattempttime;
extern UINT8 mynode; // my address pointofview server
void CL_QueryServerList(msg_server_t *list);
void CL_UpdateServerList(boolean internetsearch, INT32 room);
void CL_ConnectToServer(void);
boolean CL_SendJoin(void);
void PT_ServerInfo(SINT8 node);
void PT_MoreFilesNeeded(SINT8 node);
void PT_ServerRefuse(SINT8 node);
void PT_ServerCFG(SINT8 node);
#endif

484
src/netcode/commands.c Normal file
View file

@ -0,0 +1,484 @@
// 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 commands.c
/// \brief Various netgame commands, such as kick and ban
#include "commands.h"
#include "d_clisrv.h"
#include "client_connection.h"
#include "net_command.h"
#include "d_netcmd.h"
#include "d_net.h"
#include "i_net.h"
#include "protocol.h"
#include "../byteptr.h"
#include "../d_main.h"
#include "../g_game.h"
#include "../w_wad.h"
#include "../z_zone.h"
#include "../doomstat.h"
#include "../doomdef.h"
#include "../r_local.h"
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include <string.h>
typedef struct banreason_s
{
char *reason;
struct banreason_s *prev; //-1
struct banreason_s *next; //+1
} banreason_t;
static banreason_t *reasontail = NULL; //last entry, use prev
static banreason_t *reasonhead = NULL; //1st entry, use next
void Ban_Add(const char *reason)
{
banreason_t *reasonlist = malloc(sizeof(*reasonlist));
if (!reasonlist)
return;
if (!reason)
reason = "NA";
reasonlist->next = NULL;
reasonlist->reason = Z_StrDup(reason);
if ((reasonlist->prev = reasontail) == NULL)
reasonhead = reasonlist;
else
reasontail->next = reasonlist;
reasontail = reasonlist;
}
static void Ban_Clear(void)
{
banreason_t *temp;
I_ClearBans();
reasontail = NULL;
while (reasonhead)
{
temp = reasonhead->next;
Z_Free(reasonhead->reason);
free(reasonhead);
reasonhead = temp;
}
}
void Ban_Load_File(boolean warning)
{
FILE *f;
const char *address, *mask;
char buffer[MAX_WADPATH];
if (!I_ClearBans)
return;
f = fopen(va("%s"PATHSEP"%s", srb2home, "ban.txt"), "r");
if (!f)
{
if (warning)
CONS_Alert(CONS_WARNING, M_GetText("Could not open ban.txt for ban list\n"));
return;
}
Ban_Clear();
for (; fgets(buffer, (int)sizeof(buffer), f);)
{
address = strtok(buffer, " \t\r\n");
mask = strtok(NULL, " \t\r\n");
I_SetBanAddress(address, mask);
Ban_Add(strtok(NULL, "\r\n"));
}
fclose(f);
}
void D_SaveBan(void)
{
FILE *f;
banreason_t *reasonlist = reasonhead;
const char *address, *mask;
const char *path = va("%s"PATHSEP"%s", srb2home, "ban.txt");
if (!reasonhead)
{
remove(path);
return;
}
f = fopen(path, "w");
if (!f)
{
CONS_Alert(CONS_WARNING, M_GetText("Could not save ban list into ban.txt\n"));
return;
}
for (size_t i = 0;(address = I_GetBanAddress(i)) != NULL;i++)
{
if (!I_GetBanMask || (mask = I_GetBanMask(i)) == NULL)
fprintf(f, "%s 0", address);
else
fprintf(f, "%s %s", address, mask);
if (reasonlist && reasonlist->reason)
fprintf(f, " %s\n", reasonlist->reason);
else
fprintf(f, " %s\n", "NA");
if (reasonlist) reasonlist = reasonlist->next;
}
fclose(f);
}
void Command_ShowBan(void) //Print out ban list
{
size_t i;
const char *address, *mask;
banreason_t *reasonlist = reasonhead;
if (I_GetBanAddress)
CONS_Printf(M_GetText("Ban List:\n"));
else
return;
for (i = 0;(address = I_GetBanAddress(i)) != NULL;i++)
{
if (!I_GetBanMask || (mask = I_GetBanMask(i)) == NULL)
CONS_Printf("%s: %s ", sizeu1(i+1), address);
else
CONS_Printf("%s: %s/%s ", sizeu1(i+1), address, mask);
if (reasonlist && reasonlist->reason)
CONS_Printf("(%s)\n", reasonlist->reason);
else
CONS_Printf("\n");
if (reasonlist) reasonlist = reasonlist->next;
}
if (i == 0 && !address)
CONS_Printf(M_GetText("(empty)\n"));
}
void Command_ClearBans(void)
{
if (!I_ClearBans)
return;
Ban_Clear();
D_SaveBan();
}
void Command_Ban(void)
{
if (COM_Argc() < 2)
{
CONS_Printf(M_GetText("Ban <playername/playernum> <reason>: ban and kick a player\n"));
return;
}
if (!netgame) // Don't kick Tails in splitscreen!
{
CONS_Printf(M_GetText("This only works in a netgame.\n"));
return;
}
if (server || IsPlayerAdmin(consoleplayer))
{
UINT8 buf[3 + MAX_REASONLENGTH];
UINT8 *p = buf;
const SINT8 pn = nametonum(COM_Argv(1));
const INT32 node = playernode[(INT32)pn];
if (pn == -1 || pn == 0)
return;
WRITEUINT8(p, pn);
if (server && I_Ban && !I_Ban(node)) // only the server is allowed to do this right now
{
CONS_Alert(CONS_WARNING, M_GetText("Too many bans! Geez, that's a lot of people you're excluding...\n"));
WRITEUINT8(p, KICK_MSG_GO_AWAY);
SendNetXCmd(XD_KICK, &buf, 2);
}
else
{
if (server) // only the server is allowed to do this right now
{
Ban_Add(COM_Argv(2));
D_SaveBan(); // save the ban list
}
if (COM_Argc() == 2)
{
WRITEUINT8(p, KICK_MSG_BANNED);
SendNetXCmd(XD_KICK, &buf, 2);
}
else
{
size_t j = COM_Argc();
char message[MAX_REASONLENGTH];
//Steal from the motd code so you don't have to put the reason in quotes.
strlcpy(message, COM_Argv(2), sizeof message);
for (size_t i = 3; i < j; i++)
{
strlcat(message, " ", sizeof message);
strlcat(message, COM_Argv(i), sizeof message);
}
WRITEUINT8(p, KICK_MSG_CUSTOM_BAN);
WRITESTRINGN(p, message, MAX_REASONLENGTH);
SendNetXCmd(XD_KICK, &buf, p - buf);
}
}
}
else
CONS_Printf(M_GetText("Only the server or a remote admin can use this.\n"));
}
void Command_BanIP(void)
{
if (COM_Argc() < 2)
{
CONS_Printf(M_GetText("banip <ip> <reason>: ban an ip address\n"));
return;
}
if (server) // Only the server can use this, otherwise does nothing.
{
const char *address = (COM_Argv(1));
const char *reason;
if (COM_Argc() == 2)
reason = NULL;
else
reason = COM_Argv(2);
if (I_SetBanAddress && I_SetBanAddress(address, NULL))
{
if (reason)
CONS_Printf("Banned IP address %s for: %s\n", address, reason);
else
CONS_Printf("Banned IP address %s\n", address);
Ban_Add(reason);
D_SaveBan();
}
else
{
return;
}
}
}
void Command_ReloadBan(void) //recheck ban.txt
{
Ban_Load_File(true);
}
void Command_Kick(void)
{
if (COM_Argc() < 2)
{
CONS_Printf(M_GetText("kick <playername/playernum> <reason>: kick a player\n"));
return;
}
if (!netgame) // Don't kick Tails in splitscreen!
{
CONS_Printf(M_GetText("This only works in a netgame.\n"));
return;
}
if (server || IsPlayerAdmin(consoleplayer))
{
UINT8 buf[3 + MAX_REASONLENGTH];
UINT8 *p = buf;
const SINT8 pn = nametonum(COM_Argv(1));
if (pn == -1 || pn == 0)
return;
// Special case if we are trying to kick a player who is downloading the game state:
// trigger a timeout instead of kicking them, because a kick would only
// take effect after they have finished downloading
if (server && playernode[pn] != UINT8_MAX && netnodes[playernode[pn]].sendingsavegame)
{
Net_ConnectionTimeout(playernode[pn]);
return;
}
WRITESINT8(p, pn);
if (COM_Argc() == 2)
{
WRITEUINT8(p, KICK_MSG_GO_AWAY);
SendNetXCmd(XD_KICK, &buf, 2);
}
else
{
size_t j = COM_Argc();
char message[MAX_REASONLENGTH];
//Steal from the motd code so you don't have to put the reason in quotes.
strlcpy(message, COM_Argv(2), sizeof message);
for (size_t i = 3; i < j; i++)
{
strlcat(message, " ", sizeof message);
strlcat(message, COM_Argv(i), sizeof message);
}
WRITEUINT8(p, KICK_MSG_CUSTOM_KICK);
WRITESTRINGN(p, message, MAX_REASONLENGTH);
SendNetXCmd(XD_KICK, &buf, p - buf);
}
}
else
CONS_Printf(M_GetText("Only the server or a remote admin can use this.\n"));
}
void Command_connect(void)
{
if (COM_Argc() < 2 || *COM_Argv(1) == 0)
{
CONS_Printf(M_GetText(
"Connect <serveraddress> (port): connect to a server\n"
"Connect ANY: connect to the first lan server found\n"
//"Connect SELF: connect to your own server.\n"
));
return;
}
if (Playing() || titledemo)
{
CONS_Printf(M_GetText("You cannot connect while in a game. End this game first.\n"));
return;
}
server = false;
/*
if (!stricmp(COM_Argv(1), "self"))
{
servernode = 0;
server = true;
/// \bug should be but...
//SV_SpawnServer();
}
else
*/
{
// used in menu to connect to a server in the list
if (netgame && !stricmp(COM_Argv(1), "node"))
{
servernode = (SINT8)atoi(COM_Argv(2));
}
else if (netgame)
{
CONS_Printf(M_GetText("You cannot connect while in a game. End this game first.\n"));
return;
}
else if (I_NetOpenSocket)
{
I_NetOpenSocket();
netgame = true;
multiplayer = true;
if (!stricmp(COM_Argv(1), "any"))
servernode = BROADCASTADDR;
else if (I_NetMakeNodewPort)
{
if (COM_Argc() >= 3) // address AND port
servernode = I_NetMakeNodewPort(COM_Argv(1), COM_Argv(2));
else // address only, or address:port
servernode = I_NetMakeNode(COM_Argv(1));
}
else
{
CONS_Alert(CONS_ERROR, M_GetText("There is no server identification with this network driver\n"));
D_CloseConnection();
return;
}
}
else
CONS_Alert(CONS_ERROR, M_GetText("There is no network driver\n"));
}
splitscreen = false;
SplitScreen_OnChange();
botingame = false;
botskin = 0;
CL_ConnectToServer();
}
void Command_GetPlayerNum(void)
{
for (INT32 i = 0; i < MAXPLAYERS; i++)
if (playeringame[i])
{
if (serverplayer == i)
CONS_Printf(M_GetText("num:%2d node:%2d %s\n"), i, playernode[i], player_names[i]);
else
CONS_Printf(M_GetText("\x82num:%2d node:%2d %s\n"), i, playernode[i], player_names[i]);
}
}
/** Lists all players and their player numbers.
*
* \sa Command_GetPlayerNum
*/
void Command_Nodes(void)
{
size_t maxlen = 0;
const char *address;
for (INT32 i = 0; i < MAXPLAYERS; i++)
{
const size_t plen = strlen(player_names[i]);
if (playeringame[i] && plen > maxlen)
maxlen = plen;
}
for (INT32 i = 0; i < MAXPLAYERS; i++)
{
if (playeringame[i])
{
CONS_Printf("%.2u: %*s", i, (int)maxlen, player_names[i]);
if (playernode[i] != UINT8_MAX)
{
CONS_Printf(" - node %.2d", playernode[i]);
if (I_GetNodeAddress && (address = I_GetNodeAddress(playernode[i])) != NULL)
CONS_Printf(" - %s", address);
}
if (IsPlayerAdmin(i))
CONS_Printf(M_GetText(" (verified admin)"));
if (players[i].spectator)
CONS_Printf(M_GetText(" (spectator)"));
CONS_Printf("\n");
}
}
}

33
src/netcode/commands.h Normal file
View file

@ -0,0 +1,33 @@
// 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 commands.h
/// \brief Various netgame commands, such as kick and ban
#ifndef __COMMANDS__
#define __COMMANDS__
#include "../doomdef.h"
#define MAX_REASONLENGTH 30
void Ban_Add(const char *reason);
void D_SaveBan(void);
void Ban_Load_File(boolean warning);
void Command_ShowBan(void);
void Command_ClearBans(void);
void Command_Ban(void);
void Command_BanIP(void);
void Command_ReloadBan(void);
void Command_Kick(void);
void Command_connect(void);
void Command_GetPlayerNum(void);
void Command_Nodes(void);
#endif

1736
src/netcode/d_clisrv.c Normal file

File diff suppressed because it is too large Load diff

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