diff --git a/.circleci/config.yml b/.circleci/config.yml index 711be39d76fdfb80c4680bbae19c8dd135af0afb..3faca372cd6fb0f92d05fdea87de12a297705395 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -50,7 +50,7 @@ jobs: - 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 + command: apt-get -o Dir::Cache="/root/.cache/apt" -qq -y --no-install-recommends install git build-essential libpng-dev:i386 libsdl2-mixer-dev:i386 libgme-dev:i386 libcurl4-openssl-dev:i386 libopenmpt-dev:i386 gettext ccache wget gcc-multilib upx openssh-client - run: name: make md5sum command: find /root/.cache/apt/archives -type f -print0 | sort -z | xargs -r0 md5sum > /root/.cache/apt_archives.md5 diff --git a/.gitignore b/.gitignore index cd828dc116957ceda70d6c5b8a2b929b158f1f80..268e3632906a9b840747e6c015b32848ba45b50f 100644 --- a/.gitignore +++ b/.gitignore @@ -22,4 +22,5 @@ Win32_LIB_ASM_Release /make /bin /build -/build.* +/build/* +/CMakeUserPresets.json \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index 915912af5e8689b782e62b30c8eafbee66804b97..80a3bdcd6798a48d10ea928d60ca3c4fb77bf353 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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}) diff --git a/CMakePresets.json b/CMakePresets.json new file mode 100644 index 0000000000000000000000000000000000000000..7713bb38516877d5e8e50cc46914a7f58c9c6d73 --- /dev/null +++ b/CMakePresets.json @@ -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" + } + ] +} diff --git a/README.md b/README.md index 49a3cc36d167169467a2d65bec7527610691694d..56ff2d02d24e39fe6f8038a0770e7b1b265c7ae7 100644 --- a/README.md +++ b/README.md @@ -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) diff --git a/SRB2.cbp b/SRB2.cbp index 2a1eb87b8565b3d2d9c13216c23d39dceecd6f92..9e887bf859c05ab821b3936f29cb3089daef2b2d 100644 --- a/SRB2.cbp +++ b/SRB2.cbp @@ -1992,24 +1992,6 @@ HW3SOUND for 3D hardware sound support <Option compilerVar="CC" /> </Unit> <Unit filename="src/v_video.h" /> - <Unit filename="src/vid_copy.s"> - <Option compilerVar="CC" /> - <Option compiler="avrgcc" use="1" buildCommand="$compiler $options -x assembler-with-cpp -c $file -o $object" /> - <Option compiler="gnu_gcc_compiler_for_mingw32" use="1" buildCommand="$compiler $options -x assembler-with-cpp -c $file -o $object" /> - <Option compiler="gnu_gcc_compiler_for_mingw64" use="1" buildCommand="$compiler $options -x assembler-with-cpp -c $file -o $object" /> - <Option compiler="armelfgcc" use="1" buildCommand="$compiler $options -x assembler-with-cpp -c $file -o $object" /> - <Option compiler="tricoregcc" use="1" buildCommand="$compiler $options -x assembler-with-cpp -c $file -o $object" /> - <Option compiler="ppcgcc" use="1" buildCommand="$compiler $options -x assembler-with-cpp -c $file -o $object" /> - <Option compiler="gcc" use="1" buildCommand="$compiler $options -x assembler-with-cpp -c $file -o $object" /> - <Option target="Debug Native/SDL" /> - <Option target="Release Native/SDL" /> - <Option target="Debug Linux/SDL" /> - <Option target="Release Linux/SDL" /> - <Option target="Debug Mingw/SDL" /> - <Option target="Release Mingw/SDL" /> - <Option target="Debug Mingw/DirectX" /> - <Option target="Release Mingw/DirectX" /> - </Unit> <Unit filename="src/w_wad.c"> <Option compilerVar="CC" /> </Unit> diff --git a/SRB2_common.props b/SRB2_common.props index 0f80ceb174874e682f0205de06733cb25e2b247a..6a0d53484f10106bc254851b1e1056dc7b24a86a 100644 --- a/SRB2_common.props +++ b/SRB2_common.props @@ -25,9 +25,6 @@ </Link> </ItemDefinitionGroup> <ItemDefinitionGroup Condition="'$(PlatformTarget)'=='x86'"> - <ClCompile> - <PreprocessorDefinitions>USEASM;%(PreprocessorDefinitions)</PreprocessorDefinitions> - </ClCompile> <Link> <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers> </Link> diff --git a/Srb2.dev b/Srb2.dev index 21683e7c3c5e055393d91778fba3405bfae240de..8bd36cf490cc84dae69d25399113d346392e4fc8 100644 --- a/Srb2.dev +++ b/Srb2.dev @@ -5,7 +5,7 @@ Ver=3 IsCpp=0 Type=0 UnitCount=279 -Folders=A_Asm,B_Bot,BLUA,D_Doom,F_Frame,G_Game,H_Hud,Hw_Hardware,Hw_Hardware/r_opengl,I_Interface,I_Interface/Dummy,I_Interface/SDL,I_Interface/Win32,LUA,M_Misc,P_Play,R_Rend,S_Sounds,W_Wad +Folders=B_Bot,BLUA,D_Doom,F_Frame,G_Game,H_Hud,Hw_Hardware,Hw_Hardware/r_opengl,I_Interface,I_Interface/Dummy,I_Interface/SDL,I_Interface/Win32,LUA,M_Misc,P_Play,R_Rend,S_Sounds,W_Wad CommandLine= CompilerSettings=00000000000100000111e1 PchHead=-1 @@ -1473,36 +1473,6 @@ Priority=1000 OverrideBuildCmd=0 BuildCmd= -[Unit149] -FileName=src\tmap.nas -Folder=A_Asm -Compile=0 -CompileCpp=0 -Link=0 -Priority=1000 -OverrideBuildCmd=1 -BuildCmd=nasm.exe -g -o $@ -f win32 src/tmap.nas - -[Unit150] -FileName=src\asm_defs.inc -Folder=A_Asm -Compile=0 -CompileCpp=0 -Link=0 -Priority=1000 -OverrideBuildCmd=0 -BuildCmd= - -[Unit151] -FileName=src\vid_copy.s -Folder=A_Asm -Compile=1 -CompileCpp=0 -Link=1 -Priority=1000 -OverrideBuildCmd=1 -BuildCmd=$(CC) $(CFLAGS) -x assembler-with-cpp -c src/vid_copy.s -o $@ - [Unit152] FileName=src\y_inter.h Folder=H_Hud @@ -1543,26 +1513,6 @@ Priority=1000 OverrideBuildCmd=0 BuildCmd= -[Unit156] -FileName=src\p5prof.h -Folder=A_Asm -Compile=1 -CompileCpp=0 -Link=1 -Priority=1000 -OverrideBuildCmd=0 -BuildCmd= - -[Unit157] -FileName=src\tmap_mmx.nas -Folder=A_Asm -Compile=0 -CompileCpp=0 -Link=0 -Priority=1000 -OverrideBuildCmd=1 -BuildCmd=nasm.exe -g -o $@ -f win32 src/tmap_mmx.nas - [Unit159] FileName=src\lzf.h Folder=W_Wad diff --git a/alias-bootstrap.sh b/alias-bootstrap.sh new file mode 100755 index 0000000000000000000000000000000000000000..f1a6ac4ed918db4391a39c9a3076dfcc38d2861b --- /dev/null +++ b/alias-bootstrap.sh @@ -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' diff --git a/appveyor.yml b/appveyor.yml index e3348d35cb2b001fba3162792867548b278d63f5..63d801b734719bf4ba47dfb42b1b7849c3a23189 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -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 diff --git a/cmake/Comptime.cmake b/cmake/Comptime.cmake new file mode 100644 index 0000000000000000000000000000000000000000..8388aed9ece077229a35d601ffd0679cb2ecd035 --- /dev/null +++ b/cmake/Comptime.cmake @@ -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") diff --git a/cmake/Modules/CMakeASM_YASMInformation.cmake b/cmake/Modules/CMakeASM_YASMInformation.cmake deleted file mode 100644 index 1765180853bb2d23217a1eb785f97737411e68b1..0000000000000000000000000000000000000000 --- a/cmake/Modules/CMakeASM_YASMInformation.cmake +++ /dev/null @@ -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) diff --git a/cmake/Modules/CMakeDetermineASM_YASMCompiler.cmake b/cmake/Modules/CMakeDetermineASM_YASMCompiler.cmake deleted file mode 100644 index a5e7c9e5801121f04411e5f1b1c6efa98736bcc1..0000000000000000000000000000000000000000 --- a/cmake/Modules/CMakeDetermineASM_YASMCompiler.cmake +++ /dev/null @@ -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) diff --git a/cmake/Modules/CMakeTestASM_YASMCompiler.cmake b/cmake/Modules/CMakeTestASM_YASMCompiler.cmake deleted file mode 100644 index 745f7125c4a2f7a003c488b89d977b75a8eb3ebc..0000000000000000000000000000000000000000 --- a/cmake/Modules/CMakeTestASM_YASMCompiler.cmake +++ /dev/null @@ -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) diff --git a/cmake/Modules/GitUtilities.cmake b/cmake/Modules/GitUtilities.cmake index d29e6b509dd27015f429c9e8f4de12e20fcc5b12..586c7b433ff31476fe2a4cf0d5634d36d2c997be 100644 --- a/cmake/Modules/GitUtilities.cmake +++ b/cmake/Modules/GitUtilities.cmake @@ -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) -endfunction() +endmacro() -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 - ) +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_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_latest_commit variable) + _git_easy_command(rev-parse --short HEAD) +endfunction() - set(${variable} "${output}" PARENT_SCOPE) -endfunction() \ No newline at end of file +function(git_working_tree_dirty variable) + _git_command(status --porcelain -uno) + + 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() diff --git a/cmake/Modules/clang-tidy-default.cmake b/cmake/Modules/clang-tidy-default.cmake new file mode 100644 index 0000000000000000000000000000000000000000..2be3af10d961229bac835c7083a0d81f677f7144 --- /dev/null +++ b/cmake/Modules/clang-tidy-default.cmake @@ -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() diff --git a/extras/conf/SRB2-22.cfg b/extras/conf/SRB2-22.cfg index dd5cdb46b2c2338fd1b2728f877ab903389054ad..41ad998891154f56fe850cdfe457a48189dd648f 100644 --- a/extras/conf/SRB2-22.cfg +++ b/extras/conf/SRB2-22.cfg @@ -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"; } diff --git a/extras/conf/udb/Includes/SRB222_things.cfg b/extras/conf/udb/Includes/SRB222_things.cfg index df08e3ac50fb47c80b412da2966e10cc2cec5f79..9eb227974dfd0b33de593a7ced83b42fab7d6738 100644 --- a/extras/conf/udb/Includes/SRB222_things.cfg +++ b/extras/conf/udb/Includes/SRB222_things.cfg @@ -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?"; diff --git a/src/Android.mk b/src/Android.mk index a461da2242c7ab813831c95c1d442353756b0907..035d48887727c2a6d6b63a6acb38fc7ec65a9342 100644 --- a/src/Android.mk +++ b/src/Android.mk @@ -76,7 +76,7 @@ LOCAL_SRC_FILES := am_map.c \ android/i_system.c \ android/i_video.c -LOCAL_CFLAGS += -DPLATFORM_ANDROID -DNONX86 -DLINUX -DDEBUGMODE -DNOASM -DNOPIX -DUNIXCOMMON -DNOTERMIOS +LOCAL_CFLAGS += -DPLATFORM_ANDROID -DNONX86 -DLINUX -DDEBUGMODE -DNOPIX -DUNIXCOMMON -DNOTERMIOS LOCAL_MODULE := libsrb2 diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 2f4467a322026aa73b4281b97daeae8800855deb..b926b3b7a3372d206df781fd65bbf7a947ddaef3 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,23 +1,150 @@ -add_executable(SRB2SDL2 MACOSX_BUNDLE WIN32) +include(clang-tidy-default) + +add_executable(SRB2SDL2 MACOSX_BUNDLE WIN32 + comptime.c + md5.c + config.h.in + string.c + d_main.c + d_clisrv.c + d_net.c + d_netfil.c + d_netcmd.c + dehacked.c + deh_soc.c + deh_lua.c + deh_tables.c + z_zone.c + f_finale.c + f_wipe.c + g_demo.c + g_game.c + g_input.c + am_map.c + command.c + console.c + hu_stuff.c + i_time.c + y_inter.c + st_stuff.c + m_aatree.c + m_anigif.c + m_argv.c + m_bbox.c + m_cheat.c + m_cond.c + m_easing.c + m_fixed.c + m_menu.c + m_misc.c + m_perfstats.c + m_random.c + m_queue.c + info.c + p_ceilng.c + p_enemy.c + p_floor.c + p_inter.c + p_lights.c + p_map.c + p_maputl.c + p_mobj.c + p_polyobj.c + p_saveg.c + p_setup.c + p_sight.c + p_spec.c + p_telept.c + p_tick.c + p_user.c + p_slopes.c + tables.c + r_bsp.c + r_data.c + r_draw.c + r_fps.c + r_main.c + r_plane.c + r_segs.c + r_skins.c + r_sky.c + r_splats.c + r_things.c + r_bbox.c + r_textures.c + r_patch.c + r_patchrotation.c + r_picformats.c + r_portal.c + screen.c + taglist.c + v_video.c + s_sound.c + sounds.c + w_wad.c + filesrch.c + mserv.c + http-mserv.c + i_tcp.c + lzf.c + b_bot.c + u_list.c + lua_script.c + lua_baselib.c + lua_mathlib.c + lua_hooklib.c + lua_consolelib.c + lua_infolib.c + lua_mobjlib.c + lua_playerlib.c + lua_skinlib.c + lua_thinkerlib.c + lua_maplib.c + lua_taglib.c + lua_polyobjlib.c + lua_blockmaplib.c + lua_hudlib.c + lua_hudlib_drawlist.c + lua_inputlib.c +) -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") -endif() +# 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 +) -# Core sources -target_sourcefile(c) -target_sources(SRB2SDL2 PRIVATE comptime.c md5.c config.h.in) +# 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) -set(SRB2_ASM_SOURCES vid_copy.s) +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() -set(SRB2_NASM_SOURCES tmap_mmx.nas tmap.nas) +target_compile_features(SRB2SDL2 PRIVATE c_std_11 cxx_std_17) ### Configuration -set(SRB2_CONFIG_USEASM OFF CACHE BOOL - "Enable NASM tmap implementation for software mode speedup.") -set(SRB2_CONFIG_YASM OFF CACHE BOOL - "Use YASM in place of NASM.") set(SRB2_CONFIG_DEV_BUILD OFF CACHE BOOL "Compile a development build of SRB2.") @@ -74,33 +201,6 @@ if("${SRB2_CONFIG_HWRENDER}") endif() endif() -if(${SRB2_CONFIG_USEASM}) - #SRB2_ASM_FLAGS can be used to pass flags to either nasm or yasm. - if("${CMAKE_SYSTEM_NAME}" MATCHES "Linux") - set(SRB2_ASM_FLAGS "-DLINUX ${SRB2_ASM_FLAGS}") - endif() - - if(${SRB2_CONFIG_YASM}) - set(CMAKE_ASM_YASM_SOURCE_FILE_EXTENSIONS ${CMAKE_ASM_YASM_SOURCE_FILE_EXTENSIONS} nas) - set(CMAKE_ASM_YASM_FLAGS "${SRB2_ASM_FLAGS}" CACHE STRING "Flags used by the assembler during all build types.") - enable_language(ASM_YASM) - else() - set(CMAKE_ASM_NASM_SOURCE_FILE_EXTENSIONS ${CMAKE_ASM_NASM_SOURCE_FILE_EXTENSIONS} nas) - set(CMAKE_ASM_NASM_FLAGS "${SRB2_ASM_FLAGS}" CACHE STRING "Flags used by the assembler during all build types.") - enable_language(ASM_NASM) - endif() - - set(SRB2_USEASM ON) - target_compile_definitions(SRB2SDL2 PRIVATE -DUSEASM) - target_compile_options(SRB2SDL2 PRIVATE -msse3 -mfpmath=sse) - - target_sources(SRB2SDL2 PRIVATE ${SRB2_ASM_SOURCES} - ${SRB2_NASM_SOURCES}) -else() - set(SRB2_USEASM OFF) - target_compile_definitions(SRB2SDL2 PRIVATE -DNONX86 -DNORUSEASM) -endif() - # Targets # If using CCACHE, then force it. @@ -289,6 +389,9 @@ if(SRB2_CONFIG_PROFILEMODE AND "${CMAKE_C_COMPILER_ID}" STREQUAL "GNU") endif() add_subdirectory(sdl) +if(SRB2_CONFIG_ENABLE_TESTS) + add_subdirectory(tests) +endif() # strip debug symbols into separate file when using gcc. # to be consistent with Makefile, don't generate for OS X. @@ -329,3 +432,11 @@ if("${CMAKE_SYSTEM_NAME}" STREQUAL Windows AND NOT "${SRB2_CONFIG_INTERNAL_LIBRA COMMENT "Copying runtime DLLs" ) endif() + +# Setup clang-tidy +if(SRB2_CONFIG_ENABLE_CLANG_TIDY_C) + target_set_default_clang_tidy(SRB2SDL2 C "-*,clang-analyzer-*,-clang-analyzer-cplusplus-*") +endif() +if(SRB2_CONFIG_ENABLE_CLANG_TIDY_CXX) + target_set_default_clang_tidy(SRB2SDL2 CXX "-*,clang-analyzer-*,modernize-*") +endif() diff --git a/src/Makefile b/src/Makefile index 36b1a7efabea7416f42c624fc03ab93d2a15c05f..41cef2a179383670247847bcd572a651c1b8aad6 100644 --- a/src/Makefile +++ b/src/Makefile @@ -47,8 +47,6 @@ # HAVE_MINIUPNPC=1 - Enable automated port forwarding. # Already enabled by default for 32-bit # Windows. -# NOASM=1 - Disable hand optimized assembly code for the -# Software renderer. # NOPNG=1 - Disable PNG graphics support. (TODO: double # check netplay compatible.) # NOCURL=1 - Disable libcurl--HTTP capability. @@ -88,7 +86,6 @@ # executable. # WINDOWSHELL=1 - Use Windows commands. # PREFIX= - Prefix to many commands, for cross compiling. -# YASM=1 - Use Yasm instead of NASM assembler. # STABS=1 - ? # ECHO=1 - Print out each command in the build process. # NOECHOFILENAMES=1 - Don't print out each that is being @@ -148,22 +145,6 @@ 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 - GZIP?=gzip GZIP_OPTS?=-9 -f -n ifdef WINDOWSHELL @@ -187,8 +168,6 @@ makedir:=../make opts:=-DCOMPVERSION -g libs:= -nasm_format:= - # This is a list of variables names, of which if defined, # also defines the name as a macro to the compiler. passthru_opts:= @@ -316,7 +295,6 @@ endif LD:=$(CC) cc:=$(cc) $(opts) -nasm=$(NASM) $(NASMOPTS) -f $(nasm_format) ifdef UPX upx=$(UPX) $(UPX_OPTS) endif @@ -393,7 +371,6 @@ $(objdir)/%.$(1) : %.$(2) | $$$$(@D)/ endef $(eval $(call _recipe,o,c,$(cc) -c -o $$@ $$<)) -$(eval $(call _recipe,o,nas,$(nasm) -o $$@ $$<)) $(eval $(call _recipe,o,s,$(cc) $(asflags) -c -o $$@ $$<)) $(eval $(call _recipe,res,rc,$(windres) -i $$< -o $$@)) @@ -414,3 +391,5 @@ ifdef WINDOWSHELL else @: endif + +#$(warning The handwritten GNU Makefile for SRB2 is deprecated, and may be removed in the future. Please consider switching to CMake.) diff --git a/src/Makefile.d/features.mk b/src/Makefile.d/features.mk index 8ba33383bb2f0c8169e92f91c6c8fea25c6c852f..1787f94cb8988e6b27d5bb334c5a978ef2b31947 100644 --- a/src/Makefile.d/features.mk +++ b/src/Makefile.d/features.mk @@ -18,13 +18,6 @@ opts+=-DHWRENDER sources+=$(call List,hardware/Sourcefile) endif -ifndef NOASM -ifndef NONX86 -sources+=tmap.nas tmap_mmx.nas -opts+=-DUSEASM -endif -endif - ifndef NOMD5 sources+=md5.c endif diff --git a/src/Makefile.d/nix.mk b/src/Makefile.d/nix.mk index 767b64c12be4bf42fede8e07e80cba68151ef92a..9adf3f0f14fdc2b052e48053cabedee48a1a7edd 100644 --- a/src/Makefile.d/nix.mk +++ b/src/Makefile.d/nix.mk @@ -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 diff --git a/src/Makefile.d/platform.mk b/src/Makefile.d/platform.mk index c5ac71a20adc24766a961cb544af54cf3a1b59b1..d19143e4cf6040dc161b201553db3942b123ee39 100644 --- a/src/Makefile.d/platform.mk +++ b/src/Makefile.d/platform.mk @@ -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 diff --git a/src/Makefile.d/sdl.mk b/src/Makefile.d/sdl.mk index 99ca624e69f2f18c10625c93585f14681636f36e..a1bfa33038bbacebada85790a7565fceb9440985 100644 --- a/src/Makefile.d/sdl.mk +++ b/src/Makefile.d/sdl.mk @@ -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 diff --git a/src/Makefile.d/win32.mk b/src/Makefile.d/win32.mk index 0e48ed68359523e70b4ba0a6d8eade4b81d1d9ca..73a3d9e453ecaa0a01e32e15f71326bd7be57920 100644 --- a/src/Makefile.d/win32.mk +++ b/src/Makefile.d/win32.mk @@ -17,8 +17,6 @@ sources+=win32/Srb2win.rc opts+=-DSTDC_HEADERS libs+=-ladvapi32 -lkernel32 -lmsvcrt -luser32 -nasm_format:=win32 - SDL?=1 ifndef NOHW diff --git a/src/Sourcefile b/src/Sourcefile index 7c530500052e7379fa503ef888445dde79d0d350..f2b408c665d28306ce9c778646f6139b6874099a 100644 --- a/src/Sourcefile +++ b/src/Sourcefile @@ -81,7 +81,6 @@ mserv.c http-mserv.c i_tcp.c lzf.c -vid_copy.s b_bot.c u_list.c lua_script.c diff --git a/src/android/i_system.c b/src/android/i_system.c index ff8b88de539353bfd93ae612a3739770b267c416..9d798d452fb1b36460553fd35870894be2a3e406 100644 --- a/src/android/i_system.c +++ b/src/android/i_system.c @@ -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" diff --git a/src/asm_defs.inc b/src/asm_defs.inc deleted file mode 100644 index 48f8da0d8f582f28ad09674eec97b4af840f40b9..0000000000000000000000000000000000000000 --- a/src/asm_defs.inc +++ /dev/null @@ -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 diff --git a/src/blua/CMakeLists.txt b/src/blua/CMakeLists.txt index 4e9c67d2f348a8bfed899e4002d25136284b031f..892bf534addc810434bdd00960ebe7a92ef7bde4 100644 --- a/src/blua/CMakeLists.txt +++ b/src/blua/CMakeLists.txt @@ -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 +) diff --git a/src/comptime.c b/src/comptime.c index 398eda0743706cecb4a22d1996f8949564f1fe07..386b53f46904df87fc5f64749cc11db6e6821e3f 100644 --- a/src/comptime.c +++ b/src/comptime.c @@ -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__; diff --git a/src/config.h.in b/src/config.h.in index 3d6d98375693b220329ebd7b8fe1619def9fe792..6d49a698934bf8b498f6bfb402bbaa7f8ff93191 100644 --- a/src/config.h.in +++ b/src/config.h.in @@ -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 diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 13dab45390dfa4b5f8c125465b1a61f8eadf67be..83482b527c3354f5c2b6f81cc2e47f66b108c2b1 100755 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -1295,6 +1295,7 @@ static boolean CL_AskFileList(INT32 firstfile) static boolean CL_SendJoin(void) { UINT8 localplayers = 1; + char const *player2name; if (netgame) CONS_Printf(M_GetText("Sending join request...\n")); netbuffer->packettype = PT_CLIENTJOIN; @@ -1311,9 +1312,14 @@ static boolean CL_SendJoin(void) CleanupPlayerName(consoleplayer, cv_playername.zstring); if (splitscreen) CleanupPlayerName(1, cv_playername2.zstring);/* 1 is a HACK? oh no */ + // Avoid empty string on bots to avoid softlocking in singleplayer + if (botingame) + player2name = strcmp(cv_playername.zstring, "Tails") == 0 ? "Tail" : "Tails"; + else + player2name = cv_playername2.zstring; strncpy(netbuffer->u.clientcfg.names[0], cv_playername.zstring, MAXPLAYERNAME); - strncpy(netbuffer->u.clientcfg.names[1], cv_playername2.zstring, MAXPLAYERNAME); + strncpy(netbuffer->u.clientcfg.names[1], player2name, MAXPLAYERNAME); return HSendPacket(servernode, true, 0, sizeof (clientconfig_pak)); } @@ -4578,7 +4584,7 @@ static void HandlePacketFromPlayer(SINT8 node) // If we've alredy received a ticcmd for this tic, just submit it for the next one. tic_t faketic = maketic; if ((!!(netcmds[maketic % BACKUPTICS][netconsole].angleturn & TICCMD_RECEIVED)) - && (maketic - firstticstosend < BACKUPTICS)) + && (maketic - firstticstosend < BACKUPTICS - 1)) faketic++; // Copy ticcmd diff --git a/src/d_main.c b/src/d_main.c index 2db4002580151c622395e2ed78756793221457b6..24c70843a3bd03d383651d7423914a7fd4d3f0e5 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -70,6 +70,8 @@ #include "filesrch.h" // refreshdirmenu #include "g_input.h" // tutorial mode control scheming #include "m_perfstats.h" +#include "m_random.h" +#include "command.h" #ifdef CMAKECONFIG #include "config.h" @@ -1215,6 +1217,15 @@ D_ConvertVersionNumbers (void) #endif } +static void Command_assert(void) +{ +#if !defined(NDEBUG) || defined(PARANOIA) + CONS_Printf("Yes, assertions are enabled.\n"); +#else + CONS_Printf("No, assertions are NOT enabled.\n"); +#endif +} + // // D_SRB2Main // @@ -1228,6 +1239,11 @@ void D_SRB2Main(void) /* break the version string into version numbers, for netplay */ D_ConvertVersionNumbers(); + if (!strcmp(compbranch, "")) + { + compbranch = "detached HEAD"; + } + // Print GPL notice for our console users (Linux) CONS_Printf( "\n\nSonic Robo Blast 2\n" @@ -1341,11 +1357,12 @@ void D_SRB2Main(void) snprintf(addonsdir, sizeof addonsdir, "%s%s%s", srb2home, PATHSEP, "addons"); I_mkdir(addonsdir, 0755); - // rand() needs seeded regardless of password - srand((unsigned int)time(NULL)); - rand(); - rand(); - rand(); + // seed M_Random because it is necessary; seed P_Random for scripts that + // might want to use random numbers immediately at start + if (!M_RandomSeedFromOS()) + M_RandomSeed((UINT32)time(NULL)); // less good but serviceable + + P_SetRandSeed(M_RandomizedSeed()); if (M_CheckParm("-password") && M_IsNextParm()) D_SetPassword(M_GetNextParm()); @@ -1363,6 +1380,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"))) @@ -1718,14 +1737,15 @@ void D_SRB2Main(void) // Prevent warping to nonexistent levels if (W_CheckNumForName(G_BuildMapName(pstartmap)) == LUMPERROR) I_Error("Could not warp to %s (map not found)\n", G_BuildMapName(pstartmap)); - // Prevent warping to locked levels - // ... unless you're in a dedicated server. Yes, technically this means you can view any level by - // running a dedicated server and joining it yourself, but that's better than making dedicated server's - // lives hell. - else if (!dedicated && M_MapLocked(pstartmap, 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); } } diff --git a/src/d_netcmd.c b/src/d_netcmd.c index f81a6abde0a7e30dff0b0c69c2a05484fde2b223..be0d03af2243f2aebb8f1d7cf700cb7af31a5f4c 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -776,6 +776,8 @@ void D_RegisterClientCommands(void) CV_RegisterVar(&cv_showfocuslost); CV_RegisterVar(&cv_pauseifunfocused); + CV_RegisterVar(&cv_instantretry); + // g_input.c CV_RegisterVar(&cv_sideaxis); CV_RegisterVar(&cv_sideaxis2); @@ -1643,9 +1645,14 @@ static void Command_Playdemo_f(void) { char name[256]; - if (COM_Argc() != 2) + if (COM_Argc() < 2) { - CONS_Printf(M_GetText("playdemo <demoname>: playback a demo\n")); + CONS_Printf("playdemo <demoname> [-addfiles / -force]:\n"); + CONS_Printf(M_GetText( + "Play back a demo file. The full path from your SRB2 directory must be given.\n\n" + + "* With \"-addfiles\", any required files are added from a list contained within the demo file.\n" + "* With \"-force\", the demo is played even if the necessary files have not been added.\n")); return; } @@ -1667,6 +1674,16 @@ static void Command_Playdemo_f(void) CONS_Printf(M_GetText("Playing back demo '%s'.\n"), name); + demofileoverride = DFILE_OVERRIDE_NONE; + if (strcmp(COM_Argv(2), "-addfiles") == 0) + { + demofileoverride = DFILE_OVERRIDE_LOAD; + } + else if (strcmp(COM_Argv(2), "-force") == 0) + { + demofileoverride = DFILE_OVERRIDE_SKIP; + } + // Internal if no extension, external if one exists // If external, convert the file name to a path in SRB2's home directory if (FIL_CheckExtension(name)) @@ -1887,8 +1904,8 @@ static void Command_Map_f(void) size_t option_gametype; const char *gametypename; boolean newresetplayers; - - boolean wouldSetCheats; + boolean prevent_cheat; + boolean set_cheated; INT32 newmapnum; @@ -1909,22 +1926,34 @@ static void Command_Map_f(void) option_gametype = COM_CheckPartialParm("-g"); newresetplayers = ! COM_CheckParm("-noresetplayers"); - wouldSetCheats = - !( netgame || multiplayer ) && - !( usedCheats ); + prevent_cheat = !( usedCheats ) && !( option_force || cv_debug ); + set_cheated = false; - if (wouldSetCheats && !option_force - && !M_SecretUnlocked(SECRET_LEVELSELECT, serverGamedata)) + if (!( netgame || multiplayer )) { - /* May want to be more descriptive? */ - CONS_Printf(M_GetText("Sorry, level change disabled in single player.\n")); - return; + if (prevent_cheat) + { + /* May want to be more descriptive? */ + CONS_Printf(M_GetText("Cheats must be enabled to level change in single player.\n")); + return; + } + else + { + set_cheated = true; + } } - if (!newresetplayers && !cv_debug) + if (!newresetplayers) { - CONS_Printf(M_GetText("DEVMODE must be enabled.\n")); - return; + if (prevent_cheat) + { + CONS_Printf(M_GetText("Cheats must be enabled to use -noresetplayers.\n")); + return; + } + else + { + set_cheated = true; + } } if (option_gametype) @@ -1932,7 +1961,7 @@ static void Command_Map_f(void) if (!multiplayer) { CONS_Printf(M_GetText( - "You can't switch gametypes in single player!\n")); + "You can't switch gametypes in single player!\n")); return; } else if (COM_Argc() < option_gametype + 2)/* no argument after? */ @@ -1945,7 +1974,9 @@ static void Command_Map_f(void) } if (!( first_option = COM_FirstOption() )) + { first_option = COM_Argc(); + } if (first_option < 2) { @@ -1968,11 +1999,6 @@ static void Command_Map_f(void) return; } - if (wouldSetCheats) - { - G_SetUsedCheats(false); - } - // new gametype value // use current one by default if (option_gametype) @@ -2014,15 +2040,13 @@ static void Command_Map_f(void) } // don't use a gametype the map doesn't support - if (cv_debug || option_force || cv_skipmapcheck.value) - fromlevelselect = false; // The player wants us to trek on anyway. Do so. // G_TOLFlag handles both multiplayer gametype and ignores it for !multiplayer - else + if (!( + mapheaderinfo[newmapnum-1] && + mapheaderinfo[newmapnum-1]->typeoflevel & G_TOLFlag(newgametype) + )) { - if (!( - mapheaderinfo[newmapnum-1] && - mapheaderinfo[newmapnum-1]->typeoflevel & G_TOLFlag(newgametype) - )) + if (prevent_cheat && !cv_skipmapcheck.value) { CONS_Alert(CONS_WARNING, M_GetText("%s (%s) doesn't support %s mode!\n(Use -force to override)\n"), realmapname, G_BuildMapName(newmapnum), (multiplayer ? gametype_cons_t[newgametype].strvalue : "Single Player")); @@ -2032,23 +2056,33 @@ static void Command_Map_f(void) } else { - fromlevelselect = - ( netgame || multiplayer ) && - newgametype == gametype && - gametypedefaultrules[newgametype] & GTR_CAMPAIGN; + // The player wants us to trek on anyway. Do so. + fromlevelselect = false; + set_cheated = ((gametypedefaultrules[newgametype] & GTR_CAMPAIGN) == GTR_CAMPAIGN); } } + else + { + fromlevelselect = + ( netgame || multiplayer ) && + newgametype == gametype && + (gametypedefaultrules[newgametype] & GTR_CAMPAIGN); + } // Prevent warping to locked levels - // ... unless you're in a dedicated server. Yes, technically this means you can view any level by - // running a dedicated server and joining it yourself, but that's better than making dedicated server's - // lives hell. - if (!dedicated && M_MapLocked(newmapnum, serverGamedata)) + if (M_CampaignWarpIsCheat(newgametype, newmapnum, serverGamedata)) { - CONS_Alert(CONS_NOTICE, M_GetText("You need to unlock this level before you can warp to it!\n")); - Z_Free(realmapname); - Z_Free(mapname); - return; + if (prevent_cheat) + { + CONS_Alert(CONS_NOTICE, M_GetText("Cheats must be enabled to warp to a locked level!\n")); + Z_Free(realmapname); + Z_Free(mapname); + return; + } + else + { + set_cheated = true; + } } // Ultimate Mode only in SP via menu @@ -2065,6 +2099,11 @@ static void Command_Map_f(void) } tutorialmode = false; // warping takes us out of tutorial mode + if (set_cheated && !usedCheats) + { + G_SetUsedCheats(false); + } + D_MapChange(newmapnum, newgametype, false, newresetplayers, 0, false, fromlevelselect); Z_Free(realmapname); @@ -2106,11 +2145,13 @@ static void Got_Mapcmd(UINT8 **cp, INT32 playernum) lastgametype = gametype; gametype = READUINT8(*cp); - G_SetGametype(gametype); // I fear putting that macro as an argument if (gametype < 0 || gametype >= gametypecount) gametype = lastgametype; - else if (gametype != lastgametype) + else + G_SetGametype(gametype); + + if (gametype != lastgametype) D_GameTypeChanged(lastgametype); // emulate consvar_t behavior for gametype skipprecutscene = ((flags & (1<<2)) != 0); @@ -2132,12 +2173,6 @@ static void Got_Mapcmd(UINT8 **cp, INT32 playernum) if (demoplayback && !timingdemo) precache = false; - if (resetplayer && !FLS) - { - emeralds = 0; - memset(&luabanks, 0, sizeof(luabanks)); - } - if (modeattacking) { SetPlayerSkinByNum(0, cv_chooseskin.value-1); @@ -3845,7 +3880,7 @@ static void Command_ListWADS_f(void) static void Command_Version_f(void) { #ifdef DEVELOP - CONS_Printf("Sonic Robo Blast 2 %s-%s (%s %s) ", compbranch, comprevision, compdate, comptime); + CONS_Printf("Sonic Robo Blast 2 %s %s %s (%s %s) ", compbranch, comprevision, compnote, compdate, comptime); #else CONS_Printf("Sonic Robo Blast 2 %s (%s %s %s %s) ", VERSIONSTRING, compdate, comptime, comprevision, compbranch); #endif @@ -3879,11 +3914,6 @@ static void Command_Version_f(void) else // 16-bit? 128-bit? CONS_Printf("Bits Unknown "); - // No ASM? -#ifdef NOASM - CONS_Printf("\x85" "NOASM " "\x80"); -#endif - // Debug build #ifdef _DEBUG CONS_Printf("\x85" "DEBUG " "\x80"); @@ -4249,9 +4279,6 @@ void D_GameTypeChanged(INT32 lastgametype) else if (!multiplayer && !netgame) { G_SetGametype(GT_COOP); - // These shouldn't matter anymore - //CV_Set(&cv_itemrespawntime, cv_itemrespawntime.defaultvalue); - //CV_SetValue(&cv_itemrespawn, 0); } // reset timelimit and pointlimit in race/coop, prevent stupid cheats @@ -4552,25 +4579,37 @@ static void Command_Mapmd5_f(void) CONS_Printf(M_GetText("You must be in a level to use this.\n")); } +void D_SendExitLevel(boolean cheat) +{ + UINT8 buf[8]; + UINT8 *buf_p = buf; + + WRITEUINT8(buf_p, cheat); + + SendNetXCmd(XD_EXITLEVEL, &buf, buf_p - buf); +} + static void Command_ExitLevel_f(void) { - if (!(netgame || (multiplayer && gametype != GT_COOP)) && !cv_debug) - CONS_Printf(M_GetText("This only works in a netgame.\n")); - else if (!(server || (IsPlayerAdmin(consoleplayer)))) + if (!(server || (IsPlayerAdmin(consoleplayer)))) CONS_Printf(M_GetText("Only the server or a remote admin can use this.\n")); else if (( gamestate != GS_LEVEL && gamestate != GS_CREDITS ) || demoplayback) CONS_Printf(M_GetText("You must be in a level to use this.\n")); else - SendNetXCmd(XD_EXITLEVEL, NULL, 0); + D_SendExitLevel(true); } static void Got_ExitLevelcmd(UINT8 **cp, INT32 playernum) { - (void)cp; + boolean cheat = false; + + cheat = (boolean)READUINT8(*cp); // Ignore duplicate XD_EXITLEVEL commands. if (gameaction == ga_completed) + { return; + } if (playernum != serverplayer && !IsPlayerAdmin(playernum)) { @@ -4580,6 +4619,11 @@ static void Got_ExitLevelcmd(UINT8 **cp, INT32 playernum) return; } + if (G_CoopGametype() && cheat) + { + G_SetUsedCheats(false); + } + G_ExitLevel(); } diff --git a/src/d_netcmd.h b/src/d_netcmd.h index 26bf4d5c6bfbcfe9e481b35b84f38c44360ec3fa..8bbc801d0ef700868482fd982346dff5296c5e14 100644 --- a/src/d_netcmd.h +++ b/src/d_netcmd.h @@ -201,6 +201,7 @@ void D_SendPlayerConfig(void); void Command_ExitGame_f(void); void Command_Retry_f(void); void D_GameTypeChanged(INT32 lastgametype); // not a real _OnChange function anymore +void D_SendExitLevel(boolean cheat); void D_MapChange(INT32 pmapnum, INT32 pgametype, boolean pultmode, boolean presetplayers, INT32 pdelay, boolean pskipprecutscene, boolean pfromlevelselect); boolean IsPlayerAdmin(INT32 playernum); void SetAdminPlayer(INT32 playernum); diff --git a/src/d_think.h b/src/d_think.h index bdb5db3f54135545d27b0018943f0c995fffdcd4..efc1589bf62e277a67ab309f05d33d66af741865 100644 --- a/src/d_think.h +++ b/src/d_think.h @@ -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 diff --git a/src/deh_lua.c b/src/deh_lua.c index 1b177eb25724e38eb42f81f08ff9919177372c29..0b789547b266aeb238701ca6b34c4f8702c334fb 100644 --- a/src/deh_lua.c +++ b/src/deh_lua.c @@ -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; } diff --git a/src/deh_tables.c b/src/deh_tables.c index 6a815b6ea54adb20a4bec570b86046b369b41597..0801cf935a184d5a30d0edd215fe90e2b68db737 100644 --- a/src/deh_tables.c +++ b/src/deh_tables.c @@ -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, diff --git a/src/deh_tables.h b/src/deh_tables.h index 6731f171d867b2e2c796d55a38879b6a428c3129..42716f9b4bd271c98aca83737f419670d862d7e5 100644 --- a/src/deh_tables.h +++ b/src/deh_tables.h @@ -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 diff --git a/src/doomdata.h b/src/doomdata.h index 4c5bdefaf968f073462ab37b295cf85b5185954e..276e03297b6f0d453ad0d0c65fc8bd9196d9680c 100644 --- a/src/doomdata.h +++ b/src/doomdata.h @@ -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; diff --git a/src/doomdef.h b/src/doomdef.h index 84404d6edb62d82633b3f2643b9133a14d6b7ed3..45d6645faa0bc0ff884e11cb5722e4967f679560 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -108,6 +108,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 +269,7 @@ typedef enum // Desaturated SKINCOLOR_AETHER, SKINCOLOR_SLATE, - SKINCOLOR_METEORITE, - SKINCOLOR_MERCURY, + SKINCOLOR_MOONSTONE, SKINCOLOR_BLUEBELL, SKINCOLOR_PINK, SKINCOLOR_ROSEWOOD, @@ -299,10 +306,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 +319,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 +359,7 @@ typedef enum SKINCOLOR_NOBLE, SKINCOLOR_FUCHSIA, SKINCOLOR_BUBBLEGUM, - SKINCOLOR_CRYSTAL, + SKINCOLOR_SIBERITE, SKINCOLOR_MAGENTA, SKINCOLOR_NEON, SKINCOLOR_VIOLET, @@ -637,7 +645,16 @@ UINT32 quickncasehash (const char *p, size_t n) #define PUNCTUATION "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~" // Compile date and time and revision. -extern const char *compdate, *comptime, *comprevision, *compbranch; +extern const char + *compdate, + *comptime, + *comprevision, + *compbranch, + *compnote, + *comptype; +extern int + compuncommitted, + compoptimized; // Disabled code and code under testing // None of these that are disabled in the normal build are guaranteed to work perfectly diff --git a/src/doomstat.h b/src/doomstat.h index a812cc304f6e0b19cab8f2fecf37868264ed9b16..fdd0d0b834ff58601cce67881e399709f9277d8b 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -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 diff --git a/src/doomtype.h b/src/doomtype.h index f6c236e20bf3979ec9f1ef2353ed80b647e45b73..4070e346a1b13dd516a91504f056cebc4defb20d 100644 --- a/src/doomtype.h +++ b/src/doomtype.h @@ -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,32 +100,26 @@ 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 +#if defined (_WIN32) || defined (__HAIKU__) +#define HAVE_DOSSTR_FUNCS #endif - #define boolean INT32 - - #ifndef O_BINARY - #define O_BINARY 0 +#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 //macintosh - -#if defined (_WIN32) || defined (__HAIKU__) -#define HAVE_DOSSTR_FUNCS #endif #ifndef HAVE_DOSSTR_FUNCS @@ -129,7 +129,7 @@ int strlwr(char *n); // from dosstr.c #include <stddef.h> // for size_t -#ifndef __APPLE__ +#ifndef SRB2_HAVE_STRLCPY size_t strlcat(char *dst, const char *src, size_t siz); size_t strlcpy(char *dst, const char *src, size_t siz); #endif @@ -144,22 +144,24 @@ size_t strlcpy(char *dst, const char *src, size_t siz); /* Boolean type definition */ -// \note __BYTEBOOL__ used to be set above if "macintosh" was defined, -// if macintosh's version of boolean type isn't needed anymore, then isn't this macro pointless now? -#ifndef __BYTEBOOL__ - #define __BYTEBOOL__ - - //faB: clean that up !! - #if defined( _MSC_VER) && (_MSC_VER >= 1800) // MSVC 2013 and forward - #include "stdbool.h" - #elif defined (_WIN32) - #define false FALSE // use windows types - #define true TRUE - #define boolean BOOL - #else - typedef enum {false, true} boolean; - #endif -#endif // __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 + +#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__ diff --git a/src/dummy/i_system.c b/src/dummy/i_system.c index 8556c0248651d04469b4c1114a780bba47824421..125d2e8aec897f288995649aec2476989b4136d6 100644 --- a/src/dummy/i_system.c +++ b/src/dummy/i_system.c @@ -180,6 +180,11 @@ const char *I_ClipboardPaste(void) return NULL; } +size_t I_GetRandomBytes(char *destination, size_t amount) +{ + return 0; +} + void I_RegisterSysCommands(void) {} void I_GetCursorPosition(INT32 *x, INT32 *y) diff --git a/src/f_finale.c b/src/f_finale.c index e59b43472087eb2f03a6240eadff652cbbe99609..91c06b31652ab2902668fdb82009519ee6811108 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -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); } } diff --git a/src/g_demo.c b/src/g_demo.c index 0403da16da95c5d4e41a614fa2640797ece217f2..4b9ff56e80f5711faabd18b53a9474f2c0a60c5e 100644 --- a/src/g_demo.c +++ b/src/g_demo.c @@ -39,6 +39,7 @@ #include "v_video.h" #include "lua_hook.h" #include "md5.h" // demo checksums +#include "d_netfil.h" // G_CheckDemoExtraFiles boolean timingdemo; // if true, exit with report on completion boolean nodrawers; // for comparative timing purposes @@ -49,6 +50,7 @@ static char demoname[64]; boolean demorecording; boolean demoplayback; boolean titledemo; // Title Screen demo can be cancelled by any key +demo_file_override_e demofileoverride; static UINT8 *demobuffer = NULL; static UINT8 *demo_p, *demotime_p; static UINT8 *demoend; @@ -56,6 +58,7 @@ static UINT8 demoflags; static UINT16 demoversion; boolean singledemo; // quit after playing a demo from cmdline boolean demo_start; // don't start playing demo right away +boolean demo_forwardmove_rng; // old demo backwards compatibility boolean demosynced = true; // console warning message boolean metalrecording; // recording as metal sonic @@ -95,7 +98,7 @@ demoghost *ghosts = NULL; // DEMO RECORDING // -#define DEMOVERSION 0x000f +#define DEMOVERSION 0x0010 #define DEMOHEADER "\xF0" "SRB2Replay" "\x0F" #define DF_GHOST 0x01 // This demo contains ghost data too! @@ -1413,6 +1416,10 @@ void G_BeginRecording(void) char name[MAXCOLORNAME+1]; player_t *player = &players[consoleplayer]; + char *filename; + UINT16 totalfiles; + UINT8 *m; + if (demo_p) return; memset(name,0,sizeof(name)); @@ -1435,23 +1442,43 @@ void G_BeginRecording(void) M_Memcpy(demo_p, mapmd5, 16); demo_p += 16; WRITEUINT8(demo_p,demoflags); + + // file list + m = demo_p;/* file count */ + demo_p += 2; + + totalfiles = 0; + for (i = mainwads; ++i < numwadfiles; ) + { + if (wadfiles[i]->important) + { + nameonly(( filename = va("%s", wadfiles[i]->filename) )); + WRITESTRINGL(demo_p, filename, MAX_WADPATH); + WRITEMEM(demo_p, wadfiles[i]->md5sum, 16); + + totalfiles++; + } + } + + WRITEUINT16(m, totalfiles); + switch ((demoflags & DF_ATTACKMASK)>>DF_ATTACKSHIFT) { - case ATTACKING_NONE: // 0 - break; - case ATTACKING_RECORD: // 1 - demotime_p = demo_p; - WRITEUINT32(demo_p,UINT32_MAX); // time - WRITEUINT32(demo_p,0); // score - WRITEUINT16(demo_p,0); // rings - break; - case ATTACKING_NIGHTS: // 2 - demotime_p = demo_p; - WRITEUINT32(demo_p,UINT32_MAX); // time - WRITEUINT32(demo_p,0); // score - break; - default: // 3 - break; + case ATTACKING_NONE: // 0 + break; + case ATTACKING_RECORD: // 1 + demotime_p = demo_p; + WRITEUINT32(demo_p,UINT32_MAX); // time + WRITEUINT32(demo_p,0); // score + WRITEUINT16(demo_p,0); // rings + break; + case ATTACKING_NIGHTS: // 2 + demotime_p = demo_p; + WRITEUINT32(demo_p,UINT32_MAX); // time + WRITEUINT32(demo_p,0); // score + break; + default: // 3 + break; } WRITEUINT32(demo_p,P_GetInitSeed()); @@ -1483,18 +1510,18 @@ void G_BeginRecording(void) // Stats WRITEUINT8(demo_p,player->charability); WRITEUINT8(demo_p,player->charability2); - WRITEUINT8(demo_p,player->actionspd>>FRACBITS); - WRITEUINT8(demo_p,player->mindash>>FRACBITS); - WRITEUINT8(demo_p,player->maxdash>>FRACBITS); - WRITEUINT8(demo_p,player->normalspeed>>FRACBITS); - WRITEUINT8(demo_p,player->runspeed>>FRACBITS); + WRITEFIXED(demo_p,player->actionspd); + WRITEFIXED(demo_p,player->mindash); + WRITEFIXED(demo_p,player->maxdash); + WRITEFIXED(demo_p,player->normalspeed); + WRITEFIXED(demo_p,player->runspeed); WRITEUINT8(demo_p,player->thrustfactor); WRITEUINT8(demo_p,player->accelstart); WRITEUINT8(demo_p,player->acceleration); WRITEFIXED(demo_p,player->height); WRITEFIXED(demo_p,player->spinheight); - WRITEUINT8(demo_p,player->camerascale>>FRACBITS); - WRITEUINT8(demo_p,player->shieldscale>>FRACBITS); + WRITEFIXED(demo_p,player->camerascale); + WRITEFIXED(demo_p,player->shieldscale); // Trying to convert it back to % causes demo desync due to precision loss. // Don't do it. @@ -1590,6 +1617,183 @@ void G_BeginMetal(void) oldmetal.angle = mo->angle>>24; } +static void G_LoadDemoExtraFiles(UINT8 **pp, UINT16 this_demo_version) +{ + UINT16 totalfiles; + char filename[MAX_WADPATH]; + UINT8 md5sum[16]; + filestatus_t ncs; + boolean toomany = false; + boolean alreadyloaded; + UINT16 i, j; + + if (this_demo_version < 0x0010) + { + // demo has no file list + return; + } + + totalfiles = READUINT16((*pp)); + for (i = 0; i < totalfiles; ++i) + { + if (toomany) + SKIPSTRING((*pp)); + else + { + strlcpy(filename, (char *)(*pp), sizeof filename); + SKIPSTRING((*pp)); + } + READMEM((*pp), md5sum, 16); + + if (!toomany) + { + alreadyloaded = false; + + for (j = 0; j < numwadfiles; ++j) + { + if (memcmp(md5sum, wadfiles[j]->md5sum, 16) == 0) + { + alreadyloaded = true; + break; + } + } + + if (alreadyloaded) + continue; + + if (numwadfiles >= MAX_WADFILES) + toomany = true; + else + ncs = findfile(filename, md5sum, false); + + if (toomany) + { + CONS_Alert(CONS_WARNING, M_GetText("Too many files loaded to add anymore for demo playback\n")); + if (!CON_Ready()) + M_StartMessage(M_GetText("There are too many files loaded to add this demo's addons.\n\nDemo playback may desync.\n\nPress ESC\n"), NULL, MM_NOTHING); + } + else if (ncs != FS_FOUND) + { + if (ncs == FS_NOTFOUND) + CONS_Alert(CONS_NOTICE, M_GetText("You do not have a copy of %s\n"), filename); + else if (ncs == FS_MD5SUMBAD) + CONS_Alert(CONS_NOTICE, M_GetText("Checksum mismatch on %s\n"), filename); + else + CONS_Alert(CONS_NOTICE, M_GetText("Unknown error finding file %s\n"), filename); + + if (!CON_Ready()) + M_StartMessage(M_GetText("There were errors trying to add this demo's addons. Check the console for more information.\n\nDemo playback may desync.\n\nPress ESC\n"), NULL, MM_NOTHING); + } + else + { + P_AddWadFile(filename); + } + } + } +} + +static void G_SkipDemoExtraFiles(UINT8 **pp, UINT16 this_demo_version) +{ + UINT16 totalfiles; + UINT16 i; + + if (this_demo_version < 0x0010) + { + // demo has no file list + return; + } + + totalfiles = READUINT16((*pp)); + for (i = 0; i < totalfiles; ++i) + { + SKIPSTRING((*pp));// file name + (*pp) += 16;// md5 + } +} + +// G_CheckDemoExtraFiles: checks if our loaded WAD list matches the demo's. +// Enabling quick prevents filesystem checks to see if needed files are available to load. +static UINT8 G_CheckDemoExtraFiles(UINT8 **pp, boolean quick, UINT16 this_demo_version) +{ + UINT16 totalfiles, filesloaded, nmusfilecount; + char filename[MAX_WADPATH]; + UINT8 md5sum[16]; + boolean toomany = false; + boolean alreadyloaded; + UINT16 i, j; + UINT8 error = DFILE_ERROR_NONE; + + if (this_demo_version < 0x0010) + { + // demo has no file list + return DFILE_ERROR_NONE; + } + + totalfiles = READUINT16((*pp)); + filesloaded = 0; + for (i = 0; i < totalfiles; ++i) + { + if (toomany) + SKIPSTRING((*pp)); + else + { + strlcpy(filename, (char *)(*pp), sizeof filename); + SKIPSTRING((*pp)); + } + READMEM((*pp), md5sum, 16); + + if (!toomany) + { + alreadyloaded = false; + nmusfilecount = 0; + + for (j = 0; j < numwadfiles; ++j) + { + if (wadfiles[j]->important && j > mainwads) + nmusfilecount++; + else + continue; + + if (memcmp(md5sum, wadfiles[j]->md5sum, 16) == 0) + { + alreadyloaded = true; + + if (i != nmusfilecount-1 && error < DFILE_ERROR_OUTOFORDER) + error |= DFILE_ERROR_OUTOFORDER; + + break; + } + } + + if (alreadyloaded) + { + filesloaded++; + continue; + } + + if (numwadfiles >= MAX_WADFILES) + error = DFILE_ERROR_CANNOTLOAD; + else if (!quick && findfile(filename, md5sum, false) != FS_FOUND) + error = DFILE_ERROR_CANNOTLOAD; + else if (error < DFILE_ERROR_INCOMPLETEOUTOFORDER) + error |= DFILE_ERROR_NOTLOADED; + } else + error = DFILE_ERROR_CANNOTLOAD; + } + + // Get final file count + nmusfilecount = 0; + + for (j = 0; j < numwadfiles; ++j) + if (wadfiles[j]->important && j > mainwads) + nmusfilecount++; + + if (!error && filesloaded < nmusfilecount) + error = DFILE_ERROR_EXTRAFILES; + + return error; +} + void G_SetDemoTime(UINT32 ptime, UINT32 pscore, UINT16 prings) { if (!demorecording || !demotime_p) @@ -1618,10 +1822,9 @@ UINT8 G_CmpDemoTime(char *oldname, char *newname) UINT8 *buffer,*p; UINT8 flags; UINT32 oldtime, newtime, oldscore, newscore; - UINT16 oldrings, newrings, oldversion; + UINT16 oldrings, newrings, oldversion, newversion; size_t bufsize ATTRUNUSED; UINT8 c; - UINT16 s ATTRUNUSED; UINT8 aflags = 0; // load the new file @@ -1637,15 +1840,15 @@ UINT8 G_CmpDemoTime(char *oldname, char *newname) I_Assert(c == VERSION); c = READUINT8(p); // SUBVERSION I_Assert(c == SUBVERSION); - s = READUINT16(p); - I_Assert(s >= 0x000c); + newversion = READUINT16(p); + I_Assert(newversion == DEMOVERSION); p += 16; // demo checksum I_Assert(!memcmp(p, "PLAY", 4)); p += 4; // PLAY p += 2; // gamemap p += 16; // map md5 flags = READUINT8(p); // demoflags - + G_SkipDemoExtraFiles(&p, newversion); aflags = flags & (DF_RECORDATTACK|DF_NIGHTSATTACK); I_Assert(aflags); if (flags & DF_RECORDATTACK) @@ -1687,7 +1890,8 @@ UINT8 G_CmpDemoTime(char *oldname, char *newname) switch(oldversion) // demoversion { case DEMOVERSION: // latest always supported - case 0x000e: // The previous demoversions also supported + case 0x000f: // The previous demoversions also supported + case 0x000e: case 0x000d: // all that changed between then and now was longer color name case 0x000c: break; @@ -1710,6 +1914,7 @@ UINT8 G_CmpDemoTime(char *oldname, char *newname) p += 2; // gamemap p += 16; // mapmd5 flags = READUINT8(p); + G_SkipDemoExtraFiles(&p, oldversion); if (!(flags & aflags)) { CONS_Alert(CONS_NOTICE, M_GetText("File '%s' not from same game mode. It will be overwritten.\n"), oldname); @@ -1829,8 +2034,10 @@ void G_DoPlayDemo(char *defdemoname) version = READUINT8(demo_p); subversion = READUINT8(demo_p); demoversion = READUINT16(demo_p); + demo_forwardmove_rng = (demoversion < 0x0010); switch(demoversion) { + case 0x000f: case 0x000d: case 0x000e: case DEMOVERSION: // latest always supported @@ -1871,6 +2078,69 @@ void G_DoPlayDemo(char *defdemoname) demo_p += 16; // mapmd5 demoflags = READUINT8(demo_p); + + if (titledemo) + { + // Titledemos should always play and ought to always be compatible with whatever wadlist is running. + G_SkipDemoExtraFiles(&demo_p, demoversion); + } + else if (demofileoverride == DFILE_OVERRIDE_LOAD) + { + G_LoadDemoExtraFiles(&demo_p, demoversion); + } + else if (demofileoverride == DFILE_OVERRIDE_SKIP) + { + G_SkipDemoExtraFiles(&demo_p, demoversion); + } + else + { + UINT8 error = G_CheckDemoExtraFiles(&demo_p, false, demoversion); + + if (error) + { + switch (error) + { + case DFILE_ERROR_NOTLOADED: + snprintf(msg, 1024, + M_GetText("Required files for this demo are not loaded.\n\nUse\n\"playdemo %s -addfiles\"\nto load them and play the demo.\n"), + pdemoname); + break; + + case DFILE_ERROR_OUTOFORDER: + snprintf(msg, 1024, + M_GetText("Required files for this demo are loaded out of order.\n\nUse\n\"playdemo %s -force\"\nto play the demo anyway.\n"), + pdemoname); + break; + + case DFILE_ERROR_INCOMPLETEOUTOFORDER: + snprintf(msg, 1024, + M_GetText("Required files for this demo are not loaded, and some are out of order.\n\nUse\n\"playdemo %s -addfiles\"\nto load needed files and play the demo.\n"), + pdemoname); + break; + + case DFILE_ERROR_CANNOTLOAD: + snprintf(msg, 1024, + M_GetText("Required files for this demo cannot be loaded.\n\nUse\n\"playdemo %s -force\"\nto play the demo anyway.\n"), + pdemoname); + break; + + case DFILE_ERROR_EXTRAFILES: + snprintf(msg, 1024, + M_GetText("You have additional files loaded beyond the demo's file list.\n\nUse\n\"playdemo %s -force\"\nto play the demo anyway.\n"), + pdemoname); + break; + } + + CONS_Alert(CONS_ERROR, "%s", msg); + M_StartMessage(msg, NULL, MM_NOTHING); + Z_Free(pdemoname); + Z_Free(demobuffer); + demoplayback = false; + titledemo = false; + return; + } + } + modeattacking = (demoflags & DF_ATTACKMASK)>>DF_ATTACKSHIFT; CON_ToggleOff(); @@ -1913,18 +2183,18 @@ void G_DoPlayDemo(char *defdemoname) charability = READUINT8(demo_p); charability2 = READUINT8(demo_p); - actionspd = (fixed_t)READUINT8(demo_p)<<FRACBITS; - mindash = (fixed_t)READUINT8(demo_p)<<FRACBITS; - maxdash = (fixed_t)READUINT8(demo_p)<<FRACBITS; - normalspeed = (fixed_t)READUINT8(demo_p)<<FRACBITS; - runspeed = (fixed_t)READUINT8(demo_p)<<FRACBITS; + actionspd = (demoversion < 0x0010) ? (fixed_t)READUINT8(demo_p)<<FRACBITS : READFIXED(demo_p); + mindash = (demoversion < 0x0010) ? (fixed_t)READUINT8(demo_p)<<FRACBITS : READFIXED(demo_p); + maxdash = (demoversion < 0x0010) ? (fixed_t)READUINT8(demo_p)<<FRACBITS : READFIXED(demo_p); + normalspeed = (demoversion < 0x0010) ? (fixed_t)READUINT8(demo_p)<<FRACBITS : READFIXED(demo_p); + runspeed = (demoversion < 0x0010) ? (fixed_t)READUINT8(demo_p)<<FRACBITS : READFIXED(demo_p); thrustfactor = READUINT8(demo_p); accelstart = READUINT8(demo_p); acceleration = READUINT8(demo_p); height = (demoversion < 0x000e) ? (fixed_t)READUINT8(demo_p)<<FRACBITS : READFIXED(demo_p); spinheight = (demoversion < 0x000e) ? (fixed_t)READUINT8(demo_p)<<FRACBITS : READFIXED(demo_p); - camerascale = (fixed_t)READUINT8(demo_p)<<FRACBITS; - shieldscale = (fixed_t)READUINT8(demo_p)<<FRACBITS; + camerascale = (demoversion < 0x0010) ? (fixed_t)READUINT8(demo_p)<<FRACBITS : READFIXED(demo_p); + shieldscale = (demoversion < 0x0010) ? (fixed_t)READUINT8(demo_p)<<FRACBITS : READFIXED(demo_p); jumpfactor = READFIXED(demo_p); followitem = READUINT32(demo_p); @@ -2026,6 +2296,88 @@ void G_DoPlayDemo(char *defdemoname) demo_start = true; } +// +// Check if a replay can be loaded from the menu +// +UINT8 G_CheckDemoForError(char *defdemoname) +{ + lumpnum_t l; + char *n,*pdemoname; + UINT16 our_demo_version; + + if (titledemo) + { + // Don't do anything with files for these. + return DFILE_ERROR_NONE; + } + + n = defdemoname+strlen(defdemoname); + while (*n != '/' && *n != '\\' && n != defdemoname) + n--; + if (n != defdemoname) + n++; + pdemoname = ZZ_Alloc(strlen(n)+1); + strcpy(pdemoname,n); + + // Internal if no extension, external if one exists + if (FIL_CheckExtension(defdemoname)) + { + //FIL_DefaultExtension(defdemoname, ".lmp"); + if (!FIL_ReadFile(defdemoname, &demobuffer)) + { + return DFILE_ERROR_NOTDEMO; + } + demo_p = demobuffer; + } + // load demo resource from WAD + else if ((l = W_CheckNumForName(defdemoname)) == LUMPERROR) + { + return DFILE_ERROR_NOTDEMO; + } + else // it's an internal demo + { + demobuffer = demo_p = W_CacheLumpNum(l, PU_STATIC); + } + + // read demo header + if (memcmp(demo_p, DEMOHEADER, 12)) + { + return DFILE_ERROR_NOTDEMO; + } + demo_p += 12; // DEMOHEADER + + demo_p++; // version + demo_p++; // subversion + our_demo_version = READUINT16(demo_p); + switch(our_demo_version) + { + case 0x000d: + case 0x000e: + case 0x000f: + case DEMOVERSION: // latest always supported + break; +#ifdef OLD22DEMOCOMPAT + case 0x000c: + break; +#endif + // too old, cannot support. + default: + return DFILE_ERROR_NOTDEMO; + } + demo_p += 16; // demo checksum + if (memcmp(demo_p, "PLAY", 4)) + { + return DFILE_ERROR_NOTDEMO; + } + demo_p += 4; // "PLAY" + demo_p += 2; // gamemap + demo_p += 16; // mapmd5 + + demo_p++; // demoflags + + return G_CheckDemoExtraFiles(&demo_p, true, our_demo_version); +} + void G_AddGhost(char *defdemoname) { INT32 i; @@ -2085,6 +2437,7 @@ void G_AddGhost(char *defdemoname) ghostversion = READUINT16(p); switch(ghostversion) { + case 0x000f: case 0x000d: case 0x000e: case DEMOVERSION: // latest always supported @@ -2130,6 +2483,9 @@ void G_AddGhost(char *defdemoname) Z_Free(buffer); return; } + + G_SkipDemoExtraFiles(&p, ghostversion); // Don't wanna modify the file list for ghosts. + switch ((flags & DF_ATTACKMASK)>>DF_ATTACKSHIFT) { case ATTACKING_NONE: // 0 @@ -2161,17 +2517,12 @@ void G_AddGhost(char *defdemoname) // Ghosts do not have a player structure to put this in. p++; // charability p++; // charability2 - p++; // actionspd - p++; // mindash - p++; // maxdash - p++; // normalspeed - p++; // runspeed + p += (ghostversion < 0x0010) ? 5 : 5 * sizeof(fixed_t); // actionspd, mindash, maxdash, normalspeed, and runspeed p++; // thrustfactor p++; // accelstart p++; // acceleration p += (ghostversion < 0x000e) ? 2 : 2 * sizeof(fixed_t); // height and spinheight - p++; // camerascale - p++; // shieldscale + p += (ghostversion < 0x0010) ? 2 : 2 * sizeof(fixed_t); // camerascale and shieldscale p += 4; // jumpfactor p += 4; // followitem @@ -2347,6 +2698,7 @@ void G_DoPlayMetal(void) switch(metalversion) { case DEMOVERSION: // latest always supported + case 0x000f: case 0x000e: // There are checks wheter the momentum is from older demo versions or not case 0x000d: // all that changed between then and now was longer color name case 0x000c: diff --git a/src/g_demo.h b/src/g_demo.h index f25315a58c9b6040f38baca3d7f50abc9050a69e..379c57428a6db9daeef1b5d6ab6368436224c828 100644 --- a/src/g_demo.h +++ b/src/g_demo.h @@ -26,9 +26,19 @@ extern boolean demoplayback, titledemo, demorecording, timingdemo; extern tic_t demostarttime; +typedef enum +{ + DFILE_OVERRIDE_NONE = 0, // Show errors normally + DFILE_OVERRIDE_LOAD, // Forcefully load demo, add files beforehand + DFILE_OVERRIDE_SKIP, // Forcefully load demo, skip file list +} demo_file_override_e; + +extern demo_file_override_e demofileoverride; + // Quit after playing a demo from cmdline. extern boolean singledemo; extern boolean demo_start; +extern boolean demo_forwardmove_rng; extern boolean demosynced; extern mobj_t *metalplayback; @@ -53,6 +63,18 @@ typedef enum GHC_RETURNSKIN // ditto } ghostcolor_t; +// G_CheckDemoExtraFiles: checks if our loaded WAD list matches the demo's. +typedef enum +{ + DFILE_ERROR_NONE = 0, // No file error + DFILE_ERROR_NOTLOADED, // Files are not loaded, but can be without a restart. + DFILE_ERROR_OUTOFORDER, // Files are loaded, but out of order. + DFILE_ERROR_INCOMPLETEOUTOFORDER, // Some files are loaded out of order, but others are not. + DFILE_ERROR_CANNOTLOAD, // Files are missing and cannot be loaded. + DFILE_ERROR_EXTRAFILES, // Extra files outside of the replay's file list are loaded. + DFILE_ERROR_NOTDEMO = UINT8_MAX, // This replay isn't even a replay... +} demo_file_error_e; + // Record/playback tics void G_ReadDemoTiccmd(ticcmd_t *cmd, INT32 playernum); void G_WriteDemoTiccmd(ticcmd_t *cmd, INT32 playernum); @@ -83,5 +105,6 @@ ATTRNORETURN void FUNCNORETURN G_StopMetalRecording(boolean kill); void G_StopDemo(void); boolean G_CheckDemoStatus(void); INT32 G_ConvertOldFrameFlags(INT32 frame); +UINT8 G_CheckDemoForError(char *defdemoname); #endif // __G_DEMO__ diff --git a/src/g_game.c b/src/g_game.c index b8c43499850cd49ca39fd6498b37a4d91b95c8ed..619ed8c89d722280375a30fe3059c58785ae61b2 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -156,6 +156,7 @@ textprompt_t *textprompts[MAX_PROMPTS]; INT16 nextmapoverride; UINT8 skipstats; +INT16 nextgametype = -1; // Pointers to each CTF flag mobj_t *redflag; @@ -315,6 +316,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); @@ -2079,7 +2082,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; @@ -2137,7 +2140,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; } } @@ -2172,9 +2175,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; @@ -2523,7 +2526,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 @@ -3462,9 +3464,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 +3862,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 +4054,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 +4069,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 +4125,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 +4150,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 +4159,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 +4224,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 +4281,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--; @@ -5048,6 +5063,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 +5076,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)) @@ -5114,6 +5136,19 @@ void G_InitNew(UINT8 pultmode, const char *mapname, boolean resetplayer, boolean automapactive = false; imcontinuing = false; + // 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 diff --git a/src/g_game.h b/src/g_game.h index a8c285f79f442b04a266f7e4ccbdd34997029833..9873430b936fd4b79f89d0adbcf714a303fae2ce 100644 --- a/src/g_game.h +++ b/src/g_game.h @@ -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; diff --git a/src/hardware/CMakeLists.txt b/src/hardware/CMakeLists.txt index 4e9c67d2f348a8bfed899e4002d25136284b031f..e7819aba97e2065d36f6f920d4725d7b294505f3 100644 --- a/src/hardware/CMakeLists.txt +++ b/src/hardware/CMakeLists.txt @@ -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 +) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 36ff86abd7d0770351234913b03d837e2086b62d..f2022bcea337558ca983e9f7e83a688303fe8dfb 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -1699,7 +1699,7 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom if ((rover->fofflags & FOF_TRANSLUCENT && !(rover->fofflags & FOF_SPLAT)) || rover->blend) { 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) @@ -1822,7 +1822,7 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom if ((rover->fofflags & FOF_TRANSLUCENT && !(rover->fofflags & FOF_SPLAT)) || rover->blend) { 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) @@ -3095,7 +3095,7 @@ static void HWR_Subsector(size_t num) false, *rover->bottomheight, *gl_frontsector->lightlist[light].lightlevel, - rover->alpha-1 > 255 ? 255 : rover->alpha-1, rover->master->frontsector, + max(0, min(rover->alpha, 255)), rover->master->frontsector, HWR_RippleBlend(gl_frontsector, rover, false) | (rover->blend ? HWR_GetBlendModeFlag(rover->blend) : PF_Translucent), false, *gl_frontsector->lightlist[light].extra_colormap); } @@ -3141,7 +3141,7 @@ static void HWR_Subsector(size_t num) true, *rover->topheight, *gl_frontsector->lightlist[light].lightlevel, - rover->alpha-1 > 255 ? 255 : rover->alpha-1, rover->master->frontsector, + max(0, min(rover->alpha, 255)), rover->master->frontsector, HWR_RippleBlend(gl_frontsector, rover, false) | (rover->blend ? HWR_GetBlendModeFlag(rover->blend) : PF_Translucent), false, *gl_frontsector->lightlist[light].extra_colormap); } @@ -3595,7 +3595,7 @@ static void HWR_DrawDropShadow(mobj_t *thing, fixed_t scale) return; } - floordiff = abs((flip < 0 ? thing->height : 0) + interp.z - groundz); + floordiff = abs((flip < 0 ? interp.height : 0) + interp.z - groundz); alpha = floordiff / (4*FRACUNIT) + 75; if (alpha >= 255) return; @@ -3606,9 +3606,7 @@ static void HWR_DrawDropShadow(mobj_t *thing, fixed_t scale) HWR_GetPatch(gpatch); scalemul = FixedMul(FRACUNIT - floordiff/640, scale); - scalemul = FixedMul(scalemul, (thing->radius*2) / gpatch->height); - if ((thing->scale != thing->old_scale) && (thing->scale >= FRACUNIT/1024)) // Interpolate shadows when scaling mobjs - scalemul = FixedMul(scalemul, FixedDiv(interp.scale, thing->scale)); + scalemul = FixedMul(scalemul, (interp.radius*2) / gpatch->height); fscale = FIXED_TO_FLOAT(scalemul); fx = FIXED_TO_FLOAT(interp.x); @@ -3720,7 +3718,7 @@ static void HWR_RotateSpritePolyToAim(gl_vissprite_t *spr, FOutVector *wallVerts if (P_MobjFlip(spr->mobj) == -1) { - basey = FIXED_TO_FLOAT(interp.z + spr->mobj->height); + basey = FIXED_TO_FLOAT(interp.z + interp.height); } else { @@ -4055,32 +4053,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)); @@ -5326,7 +5324,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)); @@ -5378,7 +5376,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 @@ -5684,7 +5682,6 @@ static void HWR_ProjectBoundingBox(mobj_t *thing) gl_vissprite_t *vis; float tr_x, tr_y; float tz; - float rad; if (!thing) return; @@ -5719,15 +5716,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; diff --git a/src/hardware/hw_md2.c b/src/hardware/hw_md2.c index fca3af217ececcf3a5d95c7df8559da24240f01b..6123eb9a932b4858e423343d917eaa606f658b1c 100644 --- a/src/hardware/hw_md2.c +++ b/src/hardware/hw_md2.c @@ -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)); diff --git a/src/http-mserv.c b/src/http-mserv.c index b7032e89a3d65ecec15f195d1d46334435a411d9..df9a71a5c5d6cfcb8f73ecd3eeff371170e76c8e 100644 --- a/src/http-mserv.c +++ b/src/http-mserv.c @@ -159,7 +159,7 @@ HMS_connect (const char *format, ...) return NULL; } - if (cv_masterserver_token.string[0]) + if (cv_masterserver_token.string && cv_masterserver_token.string[0]) { quack_token = curl_easy_escape(curl, cv_masterserver_token.string, 0); token_length = ( sizeof "?token="-1 )+ strlen(quack_token); diff --git a/src/hu_stuff.c b/src/hu_stuff.c index 091e2b2fba50e46638aa6ee52bff2d7e6c81f9f0..e223d320814c6dff885886d6d57a434c0d120493 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -2025,7 +2025,7 @@ void HU_Drawer(void) V_DrawCenteredString(BASEVIDWIDTH/2, 180, V_YELLOWMAP | V_ALLOWLOWERCASE, resynch_text); } - if (modeattacking && pausedelay > 0 && !pausebreakkey) + if (modeattacking && pausedelay > 0 && !(pausebreakkey || cv_instantretry.value)) { INT32 strength = ((pausedelay - 1 - NEWTICRATE/2)*10)/(NEWTICRATE/3); INT32 y = hudinfo[HUD_LIVES].y - 13; diff --git a/src/i_system.h b/src/i_system.h index deea9f8a8de8b0a5128336a03c4ca4d6069b0867..834dd4091487b295fd1faed9d11018e498d79b12 100644 --- a/src/i_system.h +++ b/src/i_system.h @@ -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. */ diff --git a/src/info.c b/src/info.c index abcf4b49998e827c42d8abb6f80b494bec8eb68c..36389d849a38e21064e0f4e94b803cccfc9f7ef0 100644 --- a/src/info.c +++ b/src/info.c @@ -7194,7 +7194,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = sfx_cgot, // deathsound EMERALD1, // speed 16*FRACUNIT, // radius - 32*FRACUNIT, // height + 24*FRACUNIT, // height 0, // display offset 16, // mass 0, // damage @@ -7220,7 +7220,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = sfx_cgot, // deathsound EMERALD2, // speed 16*FRACUNIT, // radius - 32*FRACUNIT, // height + 24*FRACUNIT, // height 0, // display offset 16, // mass 0, // damage @@ -7246,7 +7246,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = sfx_cgot, // deathsound EMERALD3, // speed 16*FRACUNIT, // radius - 32*FRACUNIT, // height + 24*FRACUNIT, // height 0, // display offset 16, // mass 0, // damage @@ -7272,7 +7272,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = sfx_cgot, // deathsound EMERALD4, // speed 16*FRACUNIT, // radius - 32*FRACUNIT, // height + 24*FRACUNIT, // height 0, // display offset 16, // mass 0, // damage @@ -7298,7 +7298,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = sfx_cgot, // deathsound EMERALD5, // speed 16*FRACUNIT, // radius - 32*FRACUNIT, // height + 24*FRACUNIT, // height 0, // display offset 16, // mass 0, // damage @@ -7324,7 +7324,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = sfx_cgot, // deathsound EMERALD6, // speed 16*FRACUNIT, // radius - 32*FRACUNIT, // height + 24*FRACUNIT, // height 0, // display offset 16, // mass 0, // damage @@ -7350,7 +7350,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = sfx_cgot, // deathsound EMERALD7, // speed 16*FRACUNIT, // radius - 32*FRACUNIT, // height + 24*FRACUNIT, // height 0, // display offset 16, // mass 0, // damage @@ -18344,7 +18344,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_itemup, // deathsound 60*FRACUNIT, // speed - 24*FRACUNIT, // radius + 16*FRACUNIT, // radius 24*FRACUNIT, // height 0, // display offset pw_bouncering, // mass @@ -18371,7 +18371,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_itemup, // deathsound 60*FRACUNIT, // speed - 24*FRACUNIT, // radius + 16*FRACUNIT, // radius 24*FRACUNIT, // height 0, // display offset pw_railring, // mass @@ -18425,7 +18425,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_itemup, // deathsound 60*FRACUNIT, // speed - 24*FRACUNIT, // radius + 16*FRACUNIT, // radius 24*FRACUNIT, // height 0, // display offset pw_automaticring, // mass @@ -18452,7 +18452,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_itemup, // deathsound 60*FRACUNIT, // speed - 24*FRACUNIT, // radius + 16*FRACUNIT, // radius 24*FRACUNIT, // height 0, // display offset pw_explosionring, // mass @@ -18479,7 +18479,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_itemup, // deathsound 60*FRACUNIT, // speed - 24*FRACUNIT, // radius + 16*FRACUNIT, // radius 24*FRACUNIT, // height 0, // display offset pw_scatterring, // mass @@ -18506,7 +18506,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_itemup, // deathsound 60*FRACUNIT, // speed - 24*FRACUNIT, // radius + 16*FRACUNIT, // radius 24*FRACUNIT, // height 0, // display offset pw_grenadering, // mass @@ -18535,7 +18535,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = sfx_ncitem, // deathsound 60*FRACUNIT, // speed 24*FRACUNIT, // radius - 24*FRACUNIT, // height + 40*FRACUNIT, // height 0, // display offset pw_bouncering, // mass 2*TICRATE, // damage @@ -18562,7 +18562,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = sfx_ncitem, // deathsound 60*FRACUNIT, // speed 24*FRACUNIT, // radius - 24*FRACUNIT, // height + 40*FRACUNIT, // height 0, // display offset pw_railring, // mass 2*TICRATE, // damage @@ -18589,7 +18589,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = sfx_ncitem, // deathsound 60*FRACUNIT, // speed 24*FRACUNIT, // radius - 24*FRACUNIT, // height + 40*FRACUNIT, // height 0, // display offset pw_automaticring, // mass 2*TICRATE, // damage @@ -18616,7 +18616,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = sfx_ncitem, // deathsound 60*FRACUNIT, // speed 24*FRACUNIT, // radius - 24*FRACUNIT, // height + 40*FRACUNIT, // height 0, // display offset pw_explosionring, // mass 2*TICRATE, // damage @@ -18643,7 +18643,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = sfx_ncitem, // deathsound 60*FRACUNIT, // speed 24*FRACUNIT, // radius - 24*FRACUNIT, // height + 40*FRACUNIT, // height 0, // display offset pw_scatterring, // mass 2*TICRATE, // damage @@ -18670,7 +18670,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = sfx_ncitem, // deathsound 60*FRACUNIT, // speed 24*FRACUNIT, // radius - 24*FRACUNIT, // height + 40*FRACUNIT, // height 0, // display offset pw_grenadering, // mass 2*TICRATE, // damage @@ -21584,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 diff --git a/src/lua_baselib.c b/src/lua_baselib.c index 838e2f53ba6088e599bbedc4fbd7b20bfa1edfcb..4af5066aeb8df5a75b6091c205e932c72f6f2349 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -1079,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; } @@ -1107,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; } @@ -2454,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); @@ -3824,7 +3826,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 @@ -3833,18 +3835,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; diff --git a/src/lua_consolelib.c b/src/lua_consolelib.c index 9e5d1e2ee03dfe94144c1eec79757fb2d3a2f064..3783b8f7b6dac036a2e169c807e8e1079f130c76 100644 --- a/src/lua_consolelib.c +++ b/src/lua_consolelib.c @@ -615,7 +615,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; } diff --git a/src/lua_hudlib.c b/src/lua_hudlib.c index c7f67e93ac07d194a25a2ce365726219d52a3ee4..6eec91273352db4adc598a80b7e0138795589640 100644 --- a/src/lua_hudlib.c +++ b/src/lua_hudlib.c @@ -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); } } diff --git a/src/lua_hudlib_drawlist.c b/src/lua_hudlib_drawlist.c index 6f83094ac0ee1d256947c9e78090489de0387937..c518ba52540ff874480d7cda2c8314a31987e993 100644 --- a/src/lua_hudlib_drawlist.c +++ b/src/lua_hudlib_drawlist.c @@ -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); diff --git a/src/lua_infolib.c b/src/lua_infolib.c index 10baa3c6727f4840234c50c162727838e9286c40..3764acf6a40945489506ce8d94b1b976fa771752 100644 --- a/src/lua_infolib.c +++ b/src/lua_infolib.c @@ -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 diff --git a/src/lua_maplib.c b/src/lua_maplib.c index 3d95cdb751f8ae349ed026591ede5cd55438b189..e343979939056ec3c18b482a3bfd3423c446d70e 100644 --- a/src/lua_maplib.c +++ b/src/lua_maplib.c @@ -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); diff --git a/src/lua_mobjlib.c b/src/lua_mobjlib.c index fd8dcec92599b81c8e0cefbc0f5a095181a64d84..fddf958beb783e27671cb966c3afbc3e20b0c620 100644 --- a/src/lua_mobjlib.c +++ b/src/lua_mobjlib.c @@ -925,6 +925,8 @@ enum mapthing_e { mapthing_type, mapthing_options, mapthing_scale, + mapthing_spritexscale, + mapthing_spriteyscale, mapthing_z, mapthing_extrainfo, mapthing_tag, @@ -944,6 +946,8 @@ const char *const mapthing_opt[] = { "type", "options", "scale", + "spritexscale", + "spriteyscale", "z", "extrainfo", "tag", @@ -999,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); @@ -1072,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; diff --git a/src/lua_script.c b/src/lua_script.c index a8263ea5fe040272530bae660c1c3bee882164d9..6a5982006379d3e32e9694009e73fe67111a7f40 100644 --- a/src/lua_script.c +++ b/src/lua_script.c @@ -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; } diff --git a/src/lua_skinlib.c b/src/lua_skinlib.c index 13e0dd98715462fa9c63696aa87c307957162d4e..041c5d59851f3669b03d45c899c20b3440e193f0 100644 --- a/src/lua_skinlib.c +++ b/src/lua_skinlib.c @@ -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; diff --git a/src/m_cheat.c b/src/m_cheat.c index e370335f8332d65fd7f5824270f99a81d9ba7a4b..7ad86353ac86916b167d3e0768f9a8ad6f23444e 100644 --- a/src/m_cheat.c +++ b/src/m_cheat.c @@ -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; diff --git a/src/m_cond.c b/src/m_cond.c index 86bae4933137df3e633950038f19603d121db03b..18018f20751d209dbe839a649ae9936352c3a5a5 100644 --- a/src/m_cond.c +++ b/src/m_cond.c @@ -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,8 +467,19 @@ UINT8 M_SecretUnlocked(INT32 type, gamedata_t *data) UINT8 M_MapLocked(INT32 mapnum, gamedata_t *data) { - if (!mapheaderinfo[mapnum-1] || mapheaderinfo[mapnum-1]->unlockrequired < 0 - || cv_debug || devparm) + 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 (cv_debug || devparm) + return false; // Unlock every level when in devmode. + + if (!mapheaderinfo[mapnum-1] || mapheaderinfo[mapnum-1]->unlockrequired < 0) { return false; } @@ -481,6 +492,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]->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; diff --git a/src/m_cond.h b/src/m_cond.h index 2be8d564be46f0c6bba94a427555fc2a50c08d05..2491a384c02aa5f34ba47933eba689811ac599d0 100644 --- a/src/m_cond.h +++ b/src/m_cond.h @@ -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 diff --git a/src/m_fixed.c b/src/m_fixed.c index ad283119646b75abf514360bcf64d96972e86214..b674e3b2c8e230524d57ea540dada83b8bf75eb6 100644 --- a/src/m_fixed.c +++ b/src/m_fixed.c @@ -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 diff --git a/src/m_fixed.h b/src/m_fixed.h index 4a5b7ce2adf863571000b2134948d0c8e4e3e86f..94bd6a16bbf86e70c4f38c86a4758424da325db1 100644 --- a/src/m_fixed.h +++ b/src/m_fixed.h @@ -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] - - #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; - } + \param a fixed_t number + \param b fixed_t number - 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; - } + \return 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; - } +*/ +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__// 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; - } +/** \brief The FixedDiv2 function - #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 + \param a fixed_t number + \param b fixed_t number -#ifdef __USE_C_FIXEDMUL__ -FUNCMATH fixed_t FixedMul(fixed_t a, fixed_t b); -#endif + \return a/b * FRACUNIT -#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 diff --git a/src/m_menu.c b/src/m_menu.c index 7618a2c4afe3cb72efab63e51acac50a922d3f09..aa1d4b5bd2c421fa5b2ff819adb2d60570411ae2 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -2649,7 +2649,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; @@ -2843,8 +2843,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 +3196,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 +3500,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 @@ -7108,9 +7108,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) @@ -7122,13 +7119,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); @@ -7139,8 +7134,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); } } @@ -10460,13 +10458,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) { @@ -10486,11 +10494,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) { @@ -10506,19 +10518,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 + } + } + + 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; - G_DoPlayDemo(demoname); + 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) @@ -11994,6 +12065,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; @@ -12112,32 +12313,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) { - mc = mc->next; - if (mc == menucolortail) stoprow = true; + break; } + + // Find accessible color after this one + do + { + mc = mc->next; + if (mc == menucolortail) + { + stoprow = true; + } + } while (!skincolors[mc->color].accessible && !stoprow); + } + + if (stoprow) + { + break; } } @@ -12258,15 +12481,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(); @@ -12293,8 +12517,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; @@ -12333,8 +12557,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; @@ -12344,13 +12568,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 + 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; @@ -12380,7 +12619,6 @@ static void M_HandleSetupMultiPlayer(INT32 choice) } } break; - break; case KEY_DEL: if (itemOn == 0 && (l = strlen(setupm_name))!=0) diff --git a/src/m_random.c b/src/m_random.c index 8b5138b9c86f77e6fa4a0d0867e4e62198fb2dca..536fbfbbd1077abf6ae400bd4d8773a7574e4b08 100644 --- a/src/m_random.c +++ b/src/m_random.c @@ -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; } diff --git a/src/m_random.h b/src/m_random.h index 824287e27d486906c60d976e60817cb5ac9ffb73..a7c07a46b5e2c951548d67f409287e80345c20dd 100644 --- a/src/m_random.h +++ b/src/m_random.h @@ -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 diff --git a/src/p5prof.h b/src/p5prof.h deleted file mode 100644 index a9ed3965e9691f9931cd360da7cc41efc2ee5c55..0000000000000000000000000000000000000000 --- a/src/p5prof.h +++ /dev/null @@ -1,278 +0,0 @@ -/********************************************************* - * - * File: p5prof.h - * By: Kevin Baca - * - * MODIFIED BY Fab SO THAT RDMSR(...) WRITES EDX : EAX TO A LONG LONG - * (WHICH MEANS WRITE THE LOW DWORD FIRST) - * - * Now in yer code do: - * INT64 count,total; - * - * ... - * RDMSR(0x10,&count); //inner loop count - * total += count; - * ... - * - * printf("0x%x %x", (INT32)total, *((INT32 *)&total+1)); - * // HIGH LOW - * - *********************************************************/ -/**\file - \brief This file provides macros to profile your code. - - Here's how they work... - - As you may or may not know, the Pentium class of - processors provides extremely fine grained profiling - capabilities through the use of what are called - Machine Specific Registers (MSRs). These registers - can provide information about almost any aspect of - CPU performance down to a single cycle. - - The MSRs of interest for profiling are specified by - indices 0x10, 0x11, 0x12, and 0x13. Here is a brief - description of each of these registers: - - MSR 0x10 - This register is simple a cycle counter. - - MSR 0x11 - This register controls what type of profiling data - will be gathered. - - MSRs 0x12 and 0x13 - These registers gather the profiling data specified in - MSR 0x11. - - Each MSR is 64 bits wide. For the Pentium processor, - only the lower 32 bits of MSR 0x11 are valid. Bits 0-15 - specify what data will be gathered in MSR 0x12. Bits 16-31 - specify what data will be gathered in MSR 0x13. Both sets - of bits have the same format: - - Bits 0-5 specify which hardware event will be tracked. - Bit 6, if set, indicates events will be tracked in - rings 0-2. - Bit 7, if set, indicates events will be tracked in - ring 3. - Bit 8, if set, indicates cycles should be counted for - the specified event. If clear, it indicates the - number of events should be counted. - - Two instructions are provided for manupulating the MSRs. - RDMSR (Read Machine Specific Register) and WRMSR - (Write Machine Specific Register). These opcodes were - originally undocumented and therefore most assemblers don't - recognize them. Their byte codes are provided in the - macros below. - - RDMSR takes the MSR index in ecx and the profiling criteria - in edx : eax. - - WRMSR takes the MSR index in ecx and returns the profile data - in edx : eax. - - Two profiling registers limits profiling capability to - gathering only two types of information. The register - usage can, however, be combined in interesting ways. - For example, you can set one register to gather the - number of a specific type of event while the other gathers - the number of cycles for the same event. Or you can - gather the number of two separate events while using - MSR 0x10 to gather the number of cycles. - - The enumerated list provides somewhat readable labels for - the types of events that can be tracked. - - For more information, get ahold of appendix H from the - Intel Pentium programmer's manual (I don't remember the - order number) or go to - http://green.kaist.ac.kr/jwhahn/art3.htm. - That's an article by Terje Mathisen where I got most of - my information. - - You may use this code however you wish. I hope it's - useful and I hope I got everything right. - - -Kevin - - kbaca@skygames.com - -*/ - -#ifdef __GNUC__ - -#define RDTSC(_dst) \ -__asm__(" - .byte 0x0F,0x31 - movl %%edx,(%%edi) - movl %%eax,4(%%edi)"\ -: : "D" (_dst) : "eax", "edx", "edi") - -// the old code... swapped it -// movl %%edx,(%%edi) -// movl %%eax,4(%%edi)" -#define RDMSR(_msri, _msrd) \ -__asm__(" - .byte 0x0F,0x32 - movl %%eax,(%%edi) - movl %%edx,4(%%edi)"\ -: : "c" (_msri), "D" (_msrd) : "eax", "ecx", "edx", "edi") - -#define WRMSR(_msri, _msrd) \ -__asm__(" - xorl %%edx,%%edx - .byte 0x0F,0x30"\ -: : "c" (_msri), "a" (_msrd) : "eax", "ecx", "edx") - -#define RDMSR_0x12_0x13(_msr12, _msr13) \ -__asm__(" - movl $0x12,%%ecx - .byte 0x0F,0x32 - movl %%edx,(%%edi) - movl %%eax,4(%%edi) - movl $0x13,%%ecx - .byte 0x0F,0x32 - movl %%edx,(%%esi) - movl %%eax,4(%%esi)"\ -: : "D" (_msr12), "S" (_msr13) : "eax", "ecx", "edx", "edi") - -#define ZERO_MSR_0x12_0x13() \ -__asm__(" - xorl %%edx,%%edx - xorl %%eax,%%eax - movl $0x12,%%ecx - .byte 0x0F,0x30 - movl $0x13,%%ecx - .byte 0x0F,0x30"\ -: : : "eax", "ecx", "edx") - -#elif defined (__WATCOMC__) - -extern void RDTSC(UINT32 *dst); -#pragma aux RDTSC =\ - "db 0x0F,0x31"\ - "mov [edi],edx"\ - "mov [4+edi],eax"\ - parm [edi]\ - modify [eax edx edi]; - -extern void RDMSR(UINT32 msri, UINT32 *msrd); -#pragma aux RDMSR =\ - "db 0x0F,0x32"\ - "mov [edi],edx"\ - "mov [4+edi],eax"\ - parm [ecx] [edi]\ - modify [eax ecx edx edi]; - -extern void WRMSR(UINT32 msri, UINT32 msrd); -#pragma aux WRMSR =\ - "xor edx,edx"\ - "db 0x0F,0x30"\ - parm [ecx] [eax]\ - modify [eax ecx edx]; - -extern void RDMSR_0x12_0x13(UINT32 *msr12, UINT32 *msr13); -#pragma aux RDMSR_0x12_0x13 =\ - "mov ecx,0x12"\ - "db 0x0F,0x32"\ - "mov [edi],edx"\ - "mov [4+edi],eax"\ - "mov ecx,0x13"\ - "db 0x0F,0x32"\ - "mov [esi],edx"\ - "mov [4+esi],eax"\ - parm [edi] [esi]\ - modify [eax ecx edx edi esi]; - -extern void ZERO_MSR_0x12_0x13(void); -#pragma aux ZERO_MSR_0x12_0x13 =\ - "xor edx,edx"\ - "xor eax,eax"\ - "mov ecx,0x12"\ - "db 0x0F,0x30"\ - "mov ecx,0x13"\ - "db 0x0F,0x30"\ - modify [eax ecx edx]; - -#endif - -typedef enum -{ - DataRead, - DataWrite, - DataTLBMiss, - DataReadMiss, - DataWriteMiss, - WriteHitEM, - DataCacheLinesWritten, - DataCacheSnoops, - DataCacheSnoopHit, - MemAccessBothPipes, - BankConflict, - MisalignedDataRef, - CodeRead, - CodeTLBMiss, - CodeCacheMiss, - SegRegLoad, - RESERVED0, - RESERVED1, - Branch, - BTBHit, - TakenBranchOrBTBHit, - PipelineFlush, - InstructionsExeced, - InstructionsExecedVPipe, - BusUtilizationClocks, - PipelineStalledWriteBackup, - PipelineStalledDateMemRead, - PipeLineStalledWriteEM, - LockedBusCycle, - IOReadOrWriteCycle, - NonCacheableMemRef, - AGI, - RESERVED2, - RESERVED3, - FPOperation, - Breakpoint0Match, - Breakpoint1Match, - Breakpoint2Match, - Breakpoint3Match, - HWInterrupt, - DataReadOrWrite, - DataReadOrWriteMiss -}; - -#define PROF_CYCLES (0x100) -#define PROF_EVENTS (0x000) -#define RING_012 (0x40) -#define RING_3 (0x80) -#define RING_0123 (RING_012 | RING_3) - -/*void ProfSetProfiles(UINT32 msr12, UINT32 msr13);*/ -#define ProfSetProfiles(_msr12, _msr13)\ -{\ - UINT32 prof;\ -\ - prof = (_msr12) | ((_msr13) << 16);\ - WRMSR(0x11, prof);\ -} - -/*void ProfBeginProfiles(void);*/ -#define ProfBeginProfiles()\ - ZERO_MSR_0x12_0x13(); - -/*void ProfGetProfiles(UINT32 msr12[2], UINT32 msr13[2]);*/ -#define ProfGetProfiles(_msr12, _msr13)\ - RDMSR_0x12_0x13(_msr12, _msr13); - -/*void ProfZeroTimer(void);*/ -#define ProfZeroTimer()\ - WRMSR(0x10, 0); - -/*void ProfReadTimer(UINT32 timer[2]);*/ -#define ProfReadTimer(timer)\ - RDMSR(0x10, timer); - -/*EOF*/ diff --git a/src/p_enemy.c b/src/p_enemy.c index b468c230f4591ac2be6c9f6286000cf0ed3ac596..eebb65f3cb146f229183b014acdc89e0042f8da2 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -829,7 +829,7 @@ static boolean P_LookForShield(mobj_t *actor) continue; if ((player->powers[pw_shield] & SH_PROTECTELECTRIC) - && (P_AproxDistance(P_AproxDistance(actor->x-player->mo->x, actor->y-player->mo->y), actor->z-player->mo->z) < FixedMul(RING_DIST, player->mo->scale))) + && (R_PointToDist2(0, 0, R_PointToDist2(0, 0, actor->x-player->mo->x, actor->y-player->mo->y), actor->z-player->mo->z) < FixedMul(RING_DIST, player->mo->scale))) { P_SetTarget(&actor->tracer, player->mo); @@ -12636,8 +12636,7 @@ void A_MineRange(mobj_t *actor) void A_ConnectToGround(mobj_t *actor) { mobj_t *work; - fixed_t workz; - fixed_t workh; + fixed_t endz; angle_t ang; INT32 locvar1 = var1; INT32 locvar2 = var2; @@ -12648,38 +12647,42 @@ void A_ConnectToGround(mobj_t *actor) if (actor->subsector->sector->ffloors) P_AdjustMobjFloorZ_FFloors(actor, actor->subsector->sector, 2); + endz = actor->z; if (actor->flags2 & MF2_OBJECTFLIP) - workz = (actor->z + actor->height) - actor->ceilingz; + actor->z = actor->ceilingz - actor->height; // Ensures perfect ceiling connection else - workz = actor->floorz - actor->z; + actor->z = actor->floorz; // Ensures perfect floor connection if (locvar2) { - workh = FixedMul(mobjinfo[locvar2].height, actor->scale); - if (actor->flags2 & MF2_OBJECTFLIP) - workz += workh; - work = P_SpawnMobjFromMobj(actor, 0, 0, workz, locvar2); - workz += workh; - } + work = P_SpawnMobjFromMobj(actor, 0, 0, 0, locvar2); + if (work) + work->old_z = work->z; // Don't copy old_z from the actor - if (!locvar1) - return; + actor->z += P_MobjFlip(actor) * FixedMul(mobjinfo[locvar2].height, actor->scale); + } - if (!(workh = FixedMul(mobjinfo[locvar1].height, actor->scale))) + if (!locvar1 || !mobjinfo[locvar1].height) // Can't tile the middle object? + { + actor->z = endz; return; + } ang = actor->angle + ANGLE_45; - while (workz < 0) + while ((actor->flags2 & MF2_OBJECTFLIP) ? (actor->z > endz) : (actor->z < endz)) { - work = P_SpawnMobjFromMobj(actor, 0, 0, workz, locvar1); + work = P_SpawnMobjFromMobj(actor, 0, 0, 0, locvar1); if (work) - work->angle = ang; + { + work->angle = work->old_angle = ang; + work->old_z = work->z; // Don't copy old_z from the actor + } + ang += ANGLE_90; - workz += workh; + actor->z += P_MobjFlip(actor) * FixedMul(mobjinfo[locvar1].height, actor->scale); } - if (workz != 0) - actor->z += P_MobjFlip(actor)*workz; + actor->old_z = actor->z; // Reset Z interpolation - the spawned objects intentionally don't have any Z interpolation either, after all } // Function: A_SpawnParticleRelative diff --git a/src/p_inter.c b/src/p_inter.c index 4d22ba343893cc1245df77da80f9a973c201ab49..271b6ebc45a5bf42d048b39ace8db61d212741c8 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -1144,7 +1144,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) if (!(mo2->type == MT_RING || mo2->type == MT_COIN || mo2->type == MT_BLUESPHERE || mo2->type == MT_BOMBSPHERE || mo2->type == MT_NIGHTSCHIP || mo2->type == MT_NIGHTSSTAR - || ((mo2->type == MT_EMBLEM) && (mo2->reactiontime & GE_NIGHTSPULL)))) + || ((mo2->type == MT_EMBLEM) && (mo2->reactiontime & GE_NIGHTSPULL) && P_CanPickupEmblem(player, mo2->health - 1) && !P_EmblemWasCollected(mo2->health - 1)))) continue; // Yay! The thing's in reach! Pull it in! @@ -2235,7 +2235,7 @@ void P_CheckTimeLimit(void) } if (server) - SendNetXCmd(XD_EXITLEVEL, NULL, 0); + D_SendExitLevel(false); } //Optional tie-breaker for Match/CTF @@ -2298,11 +2298,11 @@ void P_CheckTimeLimit(void) } } if (server) - SendNetXCmd(XD_EXITLEVEL, NULL, 0); + D_SendExitLevel(false); } if (server) - SendNetXCmd(XD_EXITLEVEL, NULL, 0); + D_SendExitLevel(false); } /** Checks if a player's score is over the pointlimit and the round should end. @@ -2331,7 +2331,7 @@ void P_CheckPointLimit(void) if ((UINT32)cv_pointlimit.value <= redscore || (UINT32)cv_pointlimit.value <= bluescore) { if (server) - SendNetXCmd(XD_EXITLEVEL, NULL, 0); + D_SendExitLevel(false); } } else @@ -2344,7 +2344,7 @@ void P_CheckPointLimit(void) if ((UINT32)cv_pointlimit.value <= players[i].score) { if (server) - SendNetXCmd(XD_EXITLEVEL, NULL, 0); + D_SendExitLevel(false); return; } } @@ -2388,7 +2388,7 @@ void P_CheckSurvivors(void) { CONS_Printf(M_GetText("The IT player has left the game.\n")); if (server) - SendNetXCmd(XD_EXITLEVEL, NULL, 0); + D_SendExitLevel(false); return; } @@ -2408,7 +2408,7 @@ void P_CheckSurvivors(void) { CONS_Printf(M_GetText("All players have been tagged!\n")); if (server) - SendNetXCmd(XD_EXITLEVEL, NULL, 0); + D_SendExitLevel(false); } return; @@ -2420,7 +2420,7 @@ void P_CheckSurvivors(void) { CONS_Printf(M_GetText("There are no players able to become IT.\n")); if (server) - SendNetXCmd(XD_EXITLEVEL, NULL, 0); + D_SendExitLevel(false); } return; @@ -2432,7 +2432,7 @@ void P_CheckSurvivors(void) { CONS_Printf(M_GetText("All players have been tagged!\n")); if (server) - SendNetXCmd(XD_EXITLEVEL, NULL, 0); + D_SendExitLevel(false); } } diff --git a/src/p_map.c b/src/p_map.c index a8170269cb909d595855d10061a0790f5ed82723..80135db7471058b85f7aadda2fef0c37e4ddba57 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -2524,7 +2524,6 @@ boolean P_CheckCameraPosition(fixed_t x, fixed_t y, camera_t *thiscam) boolean P_TryCameraMove(fixed_t x, fixed_t y, camera_t *thiscam) { subsector_t *s = R_PointInSubsector(x, y); - boolean retval = true; boolean itsatwodlevel = false; floatok = false; @@ -2539,8 +2538,8 @@ boolean P_TryCameraMove(fixed_t x, fixed_t y, camera_t *thiscam) fixed_t tryx = thiscam->x; fixed_t tryy = thiscam->y; - if ((thiscam == &camera && (players[displayplayer].pflags & PF_NOCLIP)) - || (thiscam == &camera2 && (players[secondarydisplayplayer].pflags & PF_NOCLIP))) + if ((thiscam == &camera && (players[displayplayer].pflags & PF_NOCLIP || players[displayplayer].powers[pw_carry] == CR_NIGHTSMODE)) + || (thiscam == &camera2 && (players[secondarydisplayplayer].pflags & PF_NOCLIP || players[secondarydisplayplayer].powers[pw_carry] == CR_NIGHTSMODE))) { // Noclipping player camera noclips too!! floatok = true; thiscam->floorz = thiscam->z; @@ -2608,7 +2607,7 @@ boolean P_TryCameraMove(fixed_t x, fixed_t y, camera_t *thiscam) thiscam->y = y; thiscam->subsector = s; - return retval; + return true; } // @@ -4009,131 +4008,135 @@ void P_BounceMove(mobj_t *mo) slidemo = mo; hitcount = 0; -retry: - if (++hitcount == 3) - goto bounceback; // don't loop forever - - if (mo->player) - { - mmomx = mo->player->rmomx; - mmomy = mo->player->rmomy; - } - else + do { - mmomx = mo->momx; - mmomy = mo->momy; - } + if (++hitcount == 3) + goto bounceback; // don't loop forever - // trace along the three leading corners - if (mo->momx > 0) - { - leadx = mo->x + mo->radius; - trailx = mo->x - mo->radius; - } - else - { - leadx = mo->x - mo->radius; - trailx = mo->x + mo->radius; - } + if (mo->player) + { + mmomx = mo->player->rmomx; + mmomy = mo->player->rmomy; + } + else + { + mmomx = mo->momx; + mmomy = mo->momy; + } - if (mo->momy > 0) - { - leady = mo->y + mo->radius; - traily = mo->y - mo->radius; - } - else - { - leady = mo->y - mo->radius; - traily = mo->y + mo->radius; - } + // trace along the three leading corners + if (mo->momx > 0) + { + leadx = mo->x + mo->radius; + trailx = mo->x - mo->radius; + } + else + { + leadx = mo->x - mo->radius; + trailx = mo->x + mo->radius; + } + + if (mo->momy > 0) + { + leady = mo->y + mo->radius; + traily = mo->y - mo->radius; + } + else + { + leady = mo->y - mo->radius; + traily = mo->y + mo->radius; + } - bestslidefrac = FRACUNIT + 1; + bestslidefrac = FRACUNIT + 1; - P_PathTraverse(leadx, leady, leadx + mmomx, leady + mmomy, PT_ADDLINES, PTR_SlideTraverse); - P_PathTraverse(trailx, leady, trailx + mmomx, leady + mmomy, PT_ADDLINES, PTR_SlideTraverse); - P_PathTraverse(leadx, traily, leadx + mmomx, traily + mmomy, PT_ADDLINES, PTR_SlideTraverse); + P_PathTraverse(leadx, leady, leadx + mmomx, leady + mmomy, PT_ADDLINES, PTR_SlideTraverse); + P_PathTraverse(trailx, leady, trailx + mmomx, leady + mmomy, PT_ADDLINES, PTR_SlideTraverse); + P_PathTraverse(leadx, traily, leadx + mmomx, traily + mmomy, PT_ADDLINES, PTR_SlideTraverse); - // move up to the wall - if (bestslidefrac == FRACUNIT + 1) - { - // the move must have hit the middle, so bounce straight back -bounceback: - if (P_TryMove(mo, mo->x - mmomx, mo->y - mmomy, true)) + // move up to the wall + if (bestslidefrac == FRACUNIT + 1) { - mo->momx *= -1; - mo->momy *= -1; - mo->momx = FixedMul(mo->momx, (FRACUNIT - (FRACUNIT>>2) - (FRACUNIT>>3))); - mo->momy = FixedMul(mo->momy, (FRACUNIT - (FRACUNIT>>2) - (FRACUNIT>>3))); - - if (mo->player) + // the move must have hit the middle, so bounce straight back +bounceback: + if (P_TryMove(mo, mo->x - mmomx, mo->y - mmomy, true)) { - mo->player->cmomx *= -1; - mo->player->cmomy *= -1; - mo->player->cmomx = FixedMul(mo->player->cmomx, - (FRACUNIT - (FRACUNIT>>2) - (FRACUNIT>>3))); - mo->player->cmomy = FixedMul(mo->player->cmomy, - (FRACUNIT - (FRACUNIT>>2) - (FRACUNIT>>3))); + mo->momx *= -1; + mo->momy *= -1; + mo->momx = FixedMul(mo->momx, (FRACUNIT - (FRACUNIT>>2) - (FRACUNIT>>3))); + mo->momy = FixedMul(mo->momy, (FRACUNIT - (FRACUNIT>>2) - (FRACUNIT>>3))); + + if (mo->player) + { + mo->player->cmomx *= -1; + mo->player->cmomy *= -1; + mo->player->cmomx = FixedMul(mo->player->cmomx, + (FRACUNIT - (FRACUNIT>>2) - (FRACUNIT>>3))); + mo->player->cmomy = FixedMul(mo->player->cmomy, + (FRACUNIT - (FRACUNIT>>2) - (FRACUNIT>>3))); + } } + return; } - return; - } - // fudge a bit to make sure it doesn't hit - bestslidefrac -= 0x800; - if (bestslidefrac > 0) - { - newx = FixedMul(mmomx, bestslidefrac); - newy = FixedMul(mmomy, bestslidefrac); + // fudge a bit to make sure it doesn't hit + bestslidefrac -= 0x800; + if (bestslidefrac > 0) + { + newx = FixedMul(mmomx, bestslidefrac); + newy = FixedMul(mmomy, bestslidefrac); - if (!P_TryMove(mo, mo->x + newx, mo->y + newy, true)) - goto bounceback; - } + if (!P_TryMove(mo, mo->x + newx, mo->y + newy, true)) + { + if (P_MobjWasRemoved(mo)) + return; + goto bounceback; + } + } - // Now continue along the wall. - // First calculate remainder. - bestslidefrac = FRACUNIT - bestslidefrac; + // Now continue along the wall. + // First calculate remainder. + bestslidefrac = FRACUNIT - bestslidefrac; - if (bestslidefrac > FRACUNIT) - bestslidefrac = FRACUNIT; + if (bestslidefrac > FRACUNIT) + bestslidefrac = FRACUNIT; - if (bestslidefrac <= 0) - return; + if (bestslidefrac <= 0) + return; - if (mo->type == MT_SHELL) - { - tmxmove = mmomx; - tmymove = mmomy; - } - else if (mo->type == MT_THROWNBOUNCE) - { - tmxmove = FixedMul(mmomx, (FRACUNIT - (FRACUNIT>>6) - (FRACUNIT>>5))); - tmymove = FixedMul(mmomy, (FRACUNIT - (FRACUNIT>>6) - (FRACUNIT>>5))); - } - else if (mo->type == MT_THROWNGRENADE || mo->type == MT_CYBRAKDEMON_NAPALM_BOMB_LARGE) - { - // Quickly decay speed as it bounces - tmxmove = FixedDiv(mmomx, 2*FRACUNIT); - tmymove = FixedDiv(mmomy, 2*FRACUNIT); - } - else - { - tmxmove = FixedMul(mmomx, (FRACUNIT - (FRACUNIT>>2) - (FRACUNIT>>3))); - tmymove = FixedMul(mmomy, (FRACUNIT - (FRACUNIT>>2) - (FRACUNIT>>3))); - } + if (mo->type == MT_SHELL) + { + tmxmove = mmomx; + tmymove = mmomy; + } + else if (mo->type == MT_THROWNBOUNCE) + { + tmxmove = FixedMul(mmomx, (FRACUNIT - (FRACUNIT>>6) - (FRACUNIT>>5))); + tmymove = FixedMul(mmomy, (FRACUNIT - (FRACUNIT>>6) - (FRACUNIT>>5))); + } + else if (mo->type == MT_THROWNGRENADE || mo->type == MT_CYBRAKDEMON_NAPALM_BOMB_LARGE) + { + // Quickly decay speed as it bounces + tmxmove = FixedDiv(mmomx, 2*FRACUNIT); + tmymove = FixedDiv(mmomy, 2*FRACUNIT); + } + else + { + tmxmove = FixedMul(mmomx, (FRACUNIT - (FRACUNIT>>2) - (FRACUNIT>>3))); + tmymove = FixedMul(mmomy, (FRACUNIT - (FRACUNIT>>2) - (FRACUNIT>>3))); + } - P_HitBounceLine(bestslideline); // clip the moves + P_HitBounceLine(bestslideline); // clip the moves - mo->momx = tmxmove; - mo->momy = tmymove; + mo->momx = tmxmove; + mo->momy = tmymove; - if (mo->player) - { - mo->player->cmomx = tmxmove; - mo->player->cmomy = tmymove; + if (mo->player) + { + mo->player->cmomx = tmxmove; + mo->player->cmomy = tmymove; + } } - - if (!P_TryMove(mo, mo->x + tmxmove, mo->y + tmymove, true)) - goto retry; + while (!P_TryMove(mo, mo->x + tmxmove, mo->y + tmymove, true) && !P_MobjWasRemoved(mo)); } // diff --git a/src/p_mobj.c b/src/p_mobj.c index 4ca59285f7fc46bbfeb6e2373b50eb4eae33637d..686f08478e8d7006e3d01c7a69ea3f38b4e1534a 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -3688,7 +3688,7 @@ boolean P_CameraThinker(player_t *player, camera_t *thiscam, boolean resetcalled dummy.y = thiscam->y; dummy.z = thiscam->z; dummy.height = thiscam->height; - if (!resetcalled && !(player->pflags & PF_NOCLIP) && !P_CheckSight(&dummy, player->mo)) // TODO: "P_CheckCameraSight" instead. + if (!resetcalled && !(player->pflags & PF_NOCLIP || player->powers[pw_carry] == CR_NIGHTSMODE) && !P_CheckSight(&dummy, player->mo)) // TODO: "P_CheckCameraSight" instead. P_ResetCamera(player, thiscam); else { @@ -3719,7 +3719,7 @@ boolean P_CameraThinker(player_t *player, camera_t *thiscam, boolean resetcalled // adjust height thiscam->z += thiscam->momz + player->mo->pmomz; - if (!itsatwodlevel && !(player->pflags & PF_NOCLIP)) + if (!itsatwodlevel && !(player->pflags & PF_NOCLIP || player->powers[pw_carry] == CR_NIGHTSMODE)) { // clip movement if (thiscam->z <= thiscam->floorz) // hit the floor @@ -6882,7 +6882,6 @@ void P_RunOverlays(void) mo->eflags = (mo->eflags & ~MFE_VERTICALFLIP) | (mo->target->eflags & MFE_VERTICALFLIP); mo->scale = mo->destscale = mo->target->scale; mo->angle = (mo->target->player ? mo->target->player->drawangle : mo->target->angle) + mo->movedir; - P_SetTarget(&mo->dontdrawforviewmobj, mo->target->dontdrawforviewmobj); // Hide the overlay from the view that its target is hidden from - But don't copy drawonlyforplayer! if (!(mo->state->frame & FF_ANIMATE)) zoffs = FixedMul(((signed)mo->state->var2)*FRACUNIT, mo->scale); @@ -9228,7 +9227,7 @@ static void P_DragonbomberThink(mobj_t *mobj) else { fixed_t vspeed = FixedMul(mobj->info->speed >> 3, mobj->scale); - fixed_t z = mobj->target->z + (mobj->height >> 1) + (mobj->flags & MFE_VERTICALFLIP ? -128*mobj->scale : 128*mobj->scale + mobj->target->height); + fixed_t z = mobj->target->z + (mobj->height >> 1) + (mobj->eflags & MFE_VERTICALFLIP ? -128*mobj->scale : (128*mobj->scale + mobj->target->height)); angle_t diff = R_PointToAngle2(mobj->x, mobj->y, mobj->target->x, mobj->target->y) - mobj->angle; if (diff > ANGLE_180) mobj->angle -= DRAGONTURNSPEED; @@ -10564,6 +10563,29 @@ static fixed_t P_DefaultMobjShadowScale (mobj_t *thing) case MT_REDFLAG: case MT_BLUEFLAG: + case MT_BOUNCERING: + case MT_AUTOMATICRING: + case MT_INFINITYRING: + case MT_RAILRING: + case MT_EXPLOSIONRING: + case MT_SCATTERRING: + case MT_GRENADERING: + + case MT_BOUNCEPICKUP: + case MT_RAILPICKUP: + case MT_AUTOPICKUP: + case MT_EXPLODEPICKUP: + case MT_SCATTERPICKUP: + case MT_GRENADEPICKUP: + + case MT_REDRING: + case MT_THROWNBOUNCE: + case MT_THROWNINFINITY: + case MT_THROWNAUTOMATIC: + case MT_THROWNSCATTER: + case MT_THROWNEXPLOSION: + case MT_THROWNGRENADE: + case MT_EMBLEM: case MT_TOKEN: @@ -11181,12 +11203,6 @@ void P_RemoveMobj(mobj_t *mobj) P_SetTarget(&mobj->hnext, P_SetTarget(&mobj->hprev, NULL)); - // DBG: set everything in mobj_t to 0xFF instead of leaving it. debug memory error. -#ifdef SCRAMBLE_REMOVED - // Invalidate mobj_t data to cause crashes if accessed! - memset((UINT8 *)mobj + sizeof(thinker_t), 0xff, sizeof(mobj_t) - sizeof(thinker_t)); -#endif - R_RemoveMobjInterpolator(mobj); // free block @@ -11205,6 +11221,17 @@ void P_RemoveMobj(mobj_t *mobj) } P_RemoveThinker((thinker_t *)mobj); + +#ifdef PARANOIA + // Saved to avoid being scrambled like below... + mobj->thinker.debug_mobjtype = mobj->type; +#endif + + // DBG: set everything in mobj_t to 0xFF instead of leaving it. debug memory error. +#ifdef SCRAMBLE_REMOVED + // Invalidate mobj_t data to cause crashes if accessed! + memset((UINT8 *)mobj + sizeof(thinker_t), 0xff, sizeof(mobj_t) - sizeof(thinker_t)); +#endif } // This does not need to be added to Lua. @@ -11836,7 +11863,7 @@ void P_MovePlayerToStarpost(INT32 playernum) mapthing_t *huntemeralds[MAXHUNTEMERALDS]; INT32 numhuntemeralds; -fixed_t P_GetMobjSpawnHeight(const mobjtype_t mobjtype, const fixed_t x, const fixed_t y, const fixed_t dz, const fixed_t offset, const boolean flip, const fixed_t scale) +fixed_t P_GetMobjSpawnHeight(const mobjtype_t mobjtype, const fixed_t x, const fixed_t y, const fixed_t dz, const fixed_t offset, const boolean flip, const fixed_t scale, const boolean absolutez) { const subsector_t *ss = R_PointInSubsector(x, y); @@ -11846,9 +11873,9 @@ fixed_t P_GetMobjSpawnHeight(const mobjtype_t mobjtype, const fixed_t x, const f // Establish height. if (flip) - return P_GetSectorCeilingZAt(ss->sector, x, y) - dz - FixedMul(scale, offset + mobjinfo[mobjtype].height); + return (absolutez ? dz : P_GetSectorCeilingZAt(ss->sector, x, y) - dz) - FixedMul(scale, offset + mobjinfo[mobjtype].height); else - return P_GetSectorFloorZAt(ss->sector, x, y) + dz + FixedMul(scale, offset); + return (absolutez ? dz : P_GetSectorFloorZAt(ss->sector, x, y) + dz) + FixedMul(scale, offset); } fixed_t P_GetMapThingSpawnHeight(const mobjtype_t mobjtype, const mapthing_t* mthing, const fixed_t x, const fixed_t y) @@ -11856,6 +11883,7 @@ fixed_t P_GetMapThingSpawnHeight(const mobjtype_t mobjtype, const mapthing_t* mt fixed_t dz = mthing->z << FRACBITS; // Base offset from the floor. fixed_t offset = 0; // Specific scaling object offset. boolean flip = (!!(mobjinfo[mobjtype].flags & MF_SPAWNCEILING) ^ !!(mthing->options & MTF_OBJECTFLIP)); + boolean absolutez = !!(mthing->options & MTF_ABSOLUTEZ); switch (mobjtype) { @@ -11911,7 +11939,7 @@ fixed_t P_GetMapThingSpawnHeight(const mobjtype_t mobjtype, const mapthing_t* mt offset += mthing->args[0] ? 0 : 24*FRACUNIT; } - if (!(dz + offset)) // Snap to the surfaces when there's no offset set. + if (!(dz + offset) && !absolutez) // Snap to the surfaces when there's no offset set. { if (flip) return ONCEILINGZ; @@ -11919,7 +11947,7 @@ fixed_t P_GetMapThingSpawnHeight(const mobjtype_t mobjtype, const mapthing_t* mt return ONFLOORZ; } - return P_GetMobjSpawnHeight(mobjtype, x, y, dz, offset, flip, mthing->scale); + return P_GetMobjSpawnHeight(mobjtype, x, y, dz, offset, flip, mthing->scale, absolutez); } static boolean P_SpawnNonMobjMapThing(mapthing_t *mthing) @@ -12588,7 +12616,7 @@ static boolean P_SetupNiGHTSDrone(mapthing_t *mthing, mobj_t *mobj) dronemangoaldiff = max(mobjinfo[MT_NIGHTSDRONE_MAN].height - mobjinfo[MT_NIGHTSDRONE_GOAL].height, 0); if (flip && mobj->height != oldheight) - P_MoveOrigin(mobj, mobj->x, mobj->y, mobj->z - (mobj->height - oldheight)); + P_SetOrigin(mobj, mobj->x, mobj->y, mobj->z - (mobj->height - oldheight)); if (!flip) { @@ -13327,6 +13355,9 @@ static mobj_t *P_SpawnMobjFromMapThing(mapthing_t *mthing, fixed_t x, fixed_t y, P_SetScale(mobj, FixedMul(mobj->scale, mthing->scale)); mobj->destscale = FixedMul(mobj->destscale, mthing->scale); + mobj->spritexscale = mthing->spritexscale; + mobj->spriteyscale = mthing->spriteyscale; + if (!P_SetupSpawnedMapThing(mthing, mobj, &doangle)) return mobj; @@ -13413,7 +13444,7 @@ void P_SpawnHoop(mapthing_t *mthing) vector4_t v, res; fixed_t x = mthing->x << FRACBITS; fixed_t y = mthing->y << FRACBITS; - fixed_t z = P_GetMobjSpawnHeight(MT_HOOP, x, y, mthing->z << FRACBITS, 0, false, mthing->scale); + fixed_t z = P_GetMobjSpawnHeight(MT_HOOP, x, y, mthing->z << FRACBITS, 0, false, mthing->scale, mthing->options & MTF_ABSOLUTEZ); hoopcenter = P_SpawnMobj(x, y, z, MT_HOOPCENTER); hoopcenter->spawnpoint = mthing; @@ -13540,7 +13571,7 @@ static void P_SpawnItemRow(mapthing_t *mthing, mobjtype_t *itemtypes, UINT8 numi itemtypes[r] = P_GetMobjtypeSubstitute(&dummything, itemtypes[r]); } } - z = P_GetMobjSpawnHeight(itemtypes[0], x, y, z, 0, mthing->options & MTF_OBJECTFLIP, mthing->scale); + z = P_GetMobjSpawnHeight(itemtypes[0], x, y, z, 0, mthing->options & MTF_OBJECTFLIP, mthing->scale, mthing->options & MTF_ABSOLUTEZ); for (r = 0; r < numitems; r++) { @@ -13599,7 +13630,7 @@ static void P_SpawnItemCircle(mapthing_t *mthing, mobjtype_t *itemtypes, UINT8 n itemtypes[i] = P_GetMobjtypeSubstitute(&dummything, itemtypes[i]); } } - z = P_GetMobjSpawnHeight(itemtypes[0], x, y, z, 0, false, mthing->scale); + z = P_GetMobjSpawnHeight(itemtypes[0], x, y, z, 0, false, mthing->scale, mthing->options & MTF_ABSOLUTEZ); for (i = 0; i < numitems; i++) { diff --git a/src/p_mobj.h b/src/p_mobj.h index 9c598f59e3ce155e66a3155c4c95bd7712f839c7..a980691beb8b296b4fd16415141e4f9e5f484af8 100644 --- a/src/p_mobj.h +++ b/src/p_mobj.h @@ -491,7 +491,7 @@ void P_MovePlayerToSpawn(INT32 playernum, mapthing_t *mthing); void P_MovePlayerToStarpost(INT32 playernum); void P_AfterPlayerSpawn(INT32 playernum); -fixed_t P_GetMobjSpawnHeight(const mobjtype_t mobjtype, const fixed_t x, const fixed_t y, const fixed_t dz, const fixed_t offset, const boolean flip, const fixed_t scale); +fixed_t P_GetMobjSpawnHeight(const mobjtype_t mobjtype, const fixed_t x, const fixed_t y, const fixed_t dz, const fixed_t offset, const boolean flip, const fixed_t scale, const boolean absolutez); fixed_t P_GetMapThingSpawnHeight(const mobjtype_t mobjtype, const mapthing_t* mthing, const fixed_t x, const fixed_t y); mobj_t *P_SpawnMapThing(mapthing_t *mthing); diff --git a/src/p_saveg.c b/src/p_saveg.c index 8f11e63e58a25ba43ff6f78f3d9713332330e402..faecd13770b3d81b992017af51b4b663487aa50d 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -2716,8 +2716,8 @@ static void P_NetArchiveThinkers(void) continue; } #ifdef PARANOIA - else if (th->function.acp1 != (actionf_p1)P_RemoveThinkerDelayed) // wait garbage collection - I_Error("unknown thinker type %p", th->function.acp1); + else + I_Assert(th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed); // wait garbage collection #endif } diff --git a/src/p_setup.c b/src/p_setup.c index 175ab3328b627d7aceabeae3fd865ca71aba7b0b..e289b834699dd957aabc3ec554c25c720b6d5b2a 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -50,6 +50,7 @@ #include "m_random.h" #include "dehacked.h" // for map headers +#include "deh_tables.h" // FREE_SKINCOLORS #include "r_main.h" #include "m_cond.h" // for emblems @@ -1266,12 +1267,19 @@ static void P_WriteDuplicateText(const char *text, char **target) static void P_WriteSkincolor(INT32 constant, char **target) { + const char *color_name; + if (constant <= SKINCOLOR_NONE || constant >= (INT32)numskincolors) return; + if (constant >= SKINCOLOR_FIRSTFREESLOT) + color_name = FREE_SKINCOLORS[constant - SKINCOLOR_FIRSTFREESLOT]; + else + color_name = COLOR_ENUMS[constant]; + P_WriteDuplicateText( - va("SKINCOLOR_%s", skincolors[constant].name), + va("SKINCOLOR_%s", color_name), target ); } @@ -1510,6 +1518,7 @@ static void P_LoadThings(UINT8 *data) mt->extrainfo = (UINT8)(mt->type >> 12); Tag_FSet(&mt->tags, 0); mt->scale = FRACUNIT; + mt->spritexscale = mt->spriteyscale = FRACUNIT; memset(mt->args, 0, NUMMAPTHINGARGS*sizeof(*mt->args)); memset(mt->stringargs, 0x00, NUMMAPTHINGSTRINGARGS*sizeof(*mt->stringargs)); mt->pitch = mt->roll = 0; @@ -2013,11 +2022,19 @@ static void ParseTextmapThingParameter(UINT32 i, const char *param, const char * mapthings[i].roll = atol(val); else if (fastcmp(param, "type")) mapthings[i].type = atol(val); - else if (fastcmp(param, "scale") || fastcmp(param, "scalex") || fastcmp(param, "scaley")) + else if (fastcmp(param, "scale")) + mapthings[i].spritexscale = mapthings[i].spriteyscale = FLOAT_TO_FIXED(atof(val)); + else if (fastcmp(param, "scalex")) + mapthings[i].spritexscale = FLOAT_TO_FIXED(atof(val)); + else if (fastcmp(param, "scaley")) + mapthings[i].spriteyscale = FLOAT_TO_FIXED(atof(val)); + else if (fastcmp(param, "mobjscale")) mapthings[i].scale = FLOAT_TO_FIXED(atof(val)); // Flags else if (fastcmp(param, "flip") && fastcmp("true", val)) mapthings[i].options |= MTF_OBJECTFLIP; + else if (fastcmp(param, "absolutez") && fastcmp("true", val)) + mapthings[i].options |= MTF_ABSOLUTEZ; else if (fastncmp(param, "stringarg", 9) && strlen(param) > 9) { @@ -2431,8 +2448,12 @@ static void P_WriteTextmap(void) fprintf(f, "roll = %d;\n", wmapthings[i].roll); if (wmapthings[i].type != 0) fprintf(f, "type = %d;\n", wmapthings[i].type); + if (wmapthings[i].spritexscale != FRACUNIT) + fprintf(f, "scalex = %f;\n", FIXED_TO_FLOAT(wmapthings[i].spritexscale)); + if (wmapthings[i].spriteyscale != FRACUNIT) + fprintf(f, "scaley = %f;\n", FIXED_TO_FLOAT(wmapthings[i].spriteyscale)); if (wmapthings[i].scale != FRACUNIT) - fprintf(f, "scale = %f;\n", FIXED_TO_FLOAT(wmapthings[i].scale)); + fprintf(f, "mobjscale = %f;\n", FIXED_TO_FLOAT(wmapthings[i].scale)); if (wmapthings[i].options & MTF_OBJECTFLIP) fprintf(f, "flip = true;\n"); for (j = 0; j < NUMMAPTHINGARGS; j++) @@ -2978,6 +2999,7 @@ static void P_LoadTextmap(void) mt->extrainfo = 0; Tag_FSet(&mt->tags, 0); mt->scale = FRACUNIT; + mt->spritexscale = mt->spriteyscale = FRACUNIT; memset(mt->args, 0, NUMMAPTHINGARGS*sizeof(*mt->args)); memset(mt->stringargs, 0x00, NUMMAPTHINGSTRINGARGS*sizeof(*mt->stringargs)); mt->mobj = NULL; @@ -5455,7 +5477,7 @@ static void P_ConvertBinaryLinedefTypes(void) break; case 442: //Change object type state lines[i].args[0] = tag; - lines[i].args[3] = (lines[i].sidenum[1] == 0xffff) ? 1 : 0; + lines[i].args[1] = (lines[i].sidenum[1] == 0xffff) ? 1 : 0; break; case 443: //Call Lua function if (lines[i].stringargs[0] == NULL) @@ -6798,6 +6820,9 @@ static void P_ConvertBinaryThingTypes(void) default: break; } + + // Clear binary thing height hacks, to prevent interfering with UDMF-only flags + mapthings[i].options &= 0xF; } } @@ -7795,18 +7820,6 @@ boolean P_LoadLevel(boolean fromnetsave, boolean reloadinggamestate) R_InitMobjInterpolators(); P_InitCachedActions(); - if (!fromnetsave && 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; - } - // internal game map maplumpname = G_BuildMapName(gamemap); lastloadedmaplumpnum = W_CheckNumForMap(maplumpname); @@ -8238,7 +8251,7 @@ static boolean P_LoadAddon(UINT16 numlumps) { CONS_Printf(M_GetText("Current map %d replaced by added file, ending the level to ensure consistency.\n"), gamemap); if (server) - SendNetXCmd(XD_EXITLEVEL, NULL, 0); + D_SendExitLevel(false); } return true; diff --git a/src/p_slopes.c b/src/p_slopes.c index 6aca116a58f295eec7c69d3a9fcc9611914f461a..1c0ee81a7e9453d204049d2f0ab5986a07849edb 100644 --- a/src/p_slopes.c +++ b/src/p_slopes.c @@ -566,6 +566,7 @@ static void line_SpawnViaMapthingVertexes(const int linenum, const boolean spawn case TMSP_BACKCEILING: slopetoset = &line->backsector->c_slope; side = &sides[line->sidenum[1]]; + break; default: return; } diff --git a/src/p_spec.c b/src/p_spec.c index 6709515201c5343d2970e993dacdbf309568a34f..28ecc60f4dedb5f67f9aa33e092232eb0b3782f6 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -2561,11 +2561,13 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) // Change the music and apply position/fade operations else { - if (!line->stringargs[0]) - break; - - strncpy(mapmusname, line->stringargs[0], 7); - mapmusname[6] = 0; + if (!line->stringargs[0] || !strcmp(line->stringargs[0], "-")) + strcpy(mapmusname, ""); + else + { + strncpy(mapmusname, line->stringargs[0], 7); + mapmusname[6] = 0; + } mapmusflags = tracknum & MUSIC_TRACKMASK; if (!(line->args[0] & TMM_NORELOAD)) @@ -3284,19 +3286,18 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) foundrover = true; // If fading an invisible FOF whose render flags we did not yet set, - // initialize its alpha to 1 - // for relative alpha calc + // initialize its alpha to 0 for relative alpha calculation if (!(line->args[3] & TMST_DONTDOTRANSLUCENT) && // do translucent (rover->spawnflags & FOF_NOSHADE) && // do not include light blocks, which don't set FOF_NOSHADE !(rover->spawnflags & FOF_RENDERSIDES) && !(rover->spawnflags & FOF_RENDERPLANES) && !(rover->fofflags & FOF_RENDERALL)) - rover->alpha = 1; + rover->alpha = 0; P_RemoveFakeFloorFader(rover); P_FadeFakeFloor(rover, rover->alpha, - max(1, min(256, (line->args[3] & TMST_RELATIVE) ? rover->alpha + destvalue : destvalue)), + max(0, min(255, (line->args[3] & TMST_RELATIVE) ? rover->alpha + destvalue : destvalue)), 0, // set alpha immediately false, NULL, // tic-based logic false, // do not handle FOF_EXISTS @@ -3370,19 +3371,18 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) else { // If fading an invisible FOF whose render flags we did not yet set, - // initialize its alpha to 1 - // for relative alpha calc + // initialize its alpha to 1 for relative alpha calculation if (!(line->args[4] & TMFT_DONTDOTRANSLUCENT) && // do translucent (rover->spawnflags & FOF_NOSHADE) && // do not include light blocks, which don't set FOF_NOSHADE !(rover->spawnflags & FOF_RENDERSIDES) && !(rover->spawnflags & FOF_RENDERPLANES) && !(rover->fofflags & FOF_RENDERALL)) - rover->alpha = 1; + rover->alpha = 0; P_RemoveFakeFloorFader(rover); P_FadeFakeFloor(rover, rover->alpha, - max(1, min(256, (line->args[4] & TMFT_RELATIVE) ? rover->alpha + destvalue : destvalue)), + max(0, min(255, (line->args[4] & TMFT_RELATIVE) ? rover->alpha + destvalue : destvalue)), 0, // set alpha immediately false, NULL, // tic-based logic !(line->args[4] & TMFT_DONTDOEXISTS), // do not handle FOF_EXISTS @@ -6563,10 +6563,10 @@ void P_SpawnSpecials(boolean fromnetsave) //Cutting options if (ffloorflags & FOF_RENDERALL) { - //If inside is visible, cut inner walls - if ((lines[i].args[1] < 255) || (lines[i].args[3] & TMFA_SPLAT) || (lines[i].args[4] & TMFT_VISIBLEFROMINSIDE)) + //If inside is visible from the outside, cut inner walls + if (lines[i].args[1] < 255 || (lines[i].args[3] & TMFA_SPLAT)) ffloorflags |= FOF_CUTEXTRA|FOF_EXTRA; - else + else if (!(lines[i].args[4] & TMFT_VISIBLEFROMINSIDE)) ffloorflags |= FOF_CUTLEVEL; } @@ -6622,20 +6622,19 @@ void P_SpawnSpecials(boolean fromnetsave) if (lines[i].args[4] & TMFC_SPLAT) ffloorflags |= FOF_SPLAT; - //If inside is visible, cut inner walls - if (lines[i].args[1] < 0xff || (lines[i].args[3] & TMFT_VISIBLEFROMINSIDE) || (lines[i].args[4] & TMFC_SPLAT)) + //If inside is visible from the outside, cut inner walls + if (lines[i].args[1] < 255 || (lines[i].args[4] & TMFC_SPLAT)) ffloorflags |= FOF_CUTEXTRA|FOF_EXTRA; - else - ffloorflags |= FOF_CUTLEVEL; - - //If player can enter it, render insides - if (lines[i].args[3] & TMFT_VISIBLEFROMINSIDE) + //If player can view it from the inside, render insides + else if (lines[i].args[3] & TMFT_VISIBLEFROMINSIDE) { if (ffloorflags & FOF_RENDERPLANES) ffloorflags |= FOF_BOTHPLANES; if (ffloorflags & FOF_RENDERSIDES) ffloorflags |= FOF_ALLSIDES; } + else + ffloorflags |= FOF_CUTLEVEL; P_AddFakeFloorsByLine(i, lines[i].args[1], lines[i].args[2], ffloorflags, secthinkers); if (lines[i].args[4] & TMFC_AIRBOB) @@ -6686,10 +6685,10 @@ void P_SpawnSpecials(boolean fromnetsave) //Cutting options if (ffloorflags & FOF_RENDERALL) { - //If inside is visible, cut inner walls - if ((lines[i].args[1] < 255) || (lines[i].args[3] & TMFA_SPLAT) || (lines[i].args[4] & TMFT_VISIBLEFROMINSIDE)) + //If inside is visible from the outside, cut inner walls + if (lines[i].args[1] < 255 || (lines[i].args[3] & TMFA_SPLAT)) ffloorflags |= FOF_CUTEXTRA|FOF_EXTRA; - else + else if (!(lines[i].args[4] & TMFT_VISIBLEFROMINSIDE)) ffloorflags |= FOF_CUTLEVEL; } @@ -7754,15 +7753,14 @@ static boolean P_FadeFakeFloor(ffloor_t *rover, INT16 sourcevalue, INT16 destval if (rover->master->special == 258) // Laser block return false; - // If fading an invisible FOF whose render flags we did not yet set, - // initialize its alpha to 1 + // If fading an invisible FOF whose render flags we did not yet set, initialize its alpha to 1 if (dotranslucent && (rover->spawnflags & FOF_NOSHADE) && // do not include light blocks, which don't set FOF_NOSHADE !(rover->fofflags & FOF_FOG) && // do not include fog !(rover->spawnflags & FOF_RENDERSIDES) && !(rover->spawnflags & FOF_RENDERPLANES) && !(rover->fofflags & FOF_RENDERALL)) - rover->alpha = 1; + rover->alpha = 0; if (fadingdata) alpha = fadingdata->alpha; @@ -7848,7 +7846,7 @@ static boolean P_FadeFakeFloor(ffloor_t *rover, INT16 sourcevalue, INT16 destval { if (doexists && !(rover->spawnflags & FOF_BUSTUP)) { - if (alpha <= 1) + if (alpha <= 0) rover->fofflags &= ~FOF_EXISTS; else rover->fofflags |= FOF_EXISTS; @@ -7860,7 +7858,7 @@ static boolean P_FadeFakeFloor(ffloor_t *rover, INT16 sourcevalue, INT16 destval if (dotranslucent && !(rover->fofflags & FOF_FOG)) { - if (alpha >= 256) + if (alpha >= 255) { if (!(rover->fofflags & FOF_CUTSOLIDS) && (rover->spawnflags & FOF_CUTSOLIDS)) @@ -7960,11 +7958,11 @@ static boolean P_FadeFakeFloor(ffloor_t *rover, INT16 sourcevalue, INT16 destval else // clamp fadingdata->alpha to software's alpha levels { if (alpha < 12) - rover->alpha = destvalue < 12 ? destvalue : 1; // Don't even draw it + rover->alpha = destvalue < 12 ? destvalue : 0; // Don't even draw it else if (alpha < 38) rover->alpha = destvalue >= 12 && destvalue < 38 ? destvalue : 25; else if (alpha < 64) - rover->alpha = destvalue >=38 && destvalue < 64 ? destvalue : 51; + rover->alpha = destvalue >= 38 && destvalue < 64 ? destvalue : 51; else if (alpha < 89) rover->alpha = destvalue >= 64 && destvalue < 89 ? destvalue : 76; else if (alpha < 115) @@ -7980,7 +7978,7 @@ static boolean P_FadeFakeFloor(ffloor_t *rover, INT16 sourcevalue, INT16 destval else if (alpha < 243) rover->alpha = destvalue >= 217 && destvalue < 243 ? destvalue : 230; else // Opaque - rover->alpha = destvalue >= 243 ? destvalue : 256; + rover->alpha = destvalue >= 243 ? destvalue : 255; } } @@ -8010,17 +8008,16 @@ static void P_AddFakeFloorFader(ffloor_t *rover, size_t sectornum, size_t ffloor { fade_t *d; - // If fading an invisible FOF whose render flags we did not yet set, - // initialize its alpha to 1 + // If fading an invisible FOF whose render flags we did not yet set, initialize its alpha to 1 if (dotranslucent && (rover->spawnflags & FOF_NOSHADE) && // do not include light blocks, which don't set FOF_NOSHADE !(rover->spawnflags & FOF_RENDERSIDES) && !(rover->spawnflags & FOF_RENDERPLANES) && !(rover->fofflags & FOF_RENDERALL)) - rover->alpha = 1; + rover->alpha = 0; // already equal, nothing to do - if (rover->alpha == max(1, min(256, relative ? rover->alpha + destvalue : destvalue))) + if (rover->alpha == max(0, min(255, relative ? rover->alpha + destvalue : destvalue))) return; d = Z_Malloc(sizeof *d, PU_LEVSPEC, NULL); @@ -8031,7 +8028,7 @@ static void P_AddFakeFloorFader(ffloor_t *rover, size_t sectornum, size_t ffloor d->ffloornum = (UINT32)ffloornum; d->alpha = d->sourcevalue = rover->alpha; - d->destvalue = max(1, min(256, relative ? rover->alpha + destvalue : destvalue)); // rover->alpha is 1-256 + d->destvalue = max(0, min(255, relative ? rover->alpha + destvalue : destvalue)); // rover->alpha is 0-255 if (ticbased) { diff --git a/src/p_tick.c b/src/p_tick.c index b1fd367ed94721e5aedab16b3a3e743a6df63425..ec5d8a2da0a487a6e4743e39dedc04c2fb27069d 100644 --- a/src/p_tick.c +++ b/src/p_tick.c @@ -30,6 +30,10 @@ // Object place #include "m_cheat.h" +#ifdef PARANOIA +#include "deh_tables.h" // MOBJTYPE_LIST +#endif + tic_t leveltime; // @@ -211,7 +215,48 @@ void P_AddThinker(const thinklistnum_t n, thinker_t *thinker) thlist[n].prev = thinker; thinker->references = 0; // killough 11/98: init reference counter to 0 + +#ifdef PARANOIA + thinker->debug_mobjtype = MT_NULL; +#endif +} + +#ifdef PARANOIA +static const char *MobjTypeName(const mobj_t *mobj) +{ + actionf_p1 p1 = mobj->thinker.function.acp1; + + if (p1 == (actionf_p1)P_MobjThinker) + { + return MOBJTYPE_LIST[mobj->type]; + } + else if (p1 == (actionf_p1)P_RemoveThinkerDelayed) + { + if (mobj->thinker.debug_mobjtype != MT_NULL) + { + return MOBJTYPE_LIST[mobj->thinker.debug_mobjtype]; + } + } + + return "<Not a mobj>"; +} + +static const char *MobjThinkerName(const mobj_t *mobj) +{ + actionf_p1 p1 = mobj->thinker.function.acp1; + + if (p1 == (actionf_p1)P_MobjThinker) + { + return "P_MobjThinker"; + } + else if (p1 == (actionf_p1)P_RemoveThinkerDelayed) + { + return "P_RemoveThinkerDelayed"; + } + + return "<Unknown Thinker>"; } +#endif // // killough 11/98: @@ -234,20 +279,34 @@ static thinker_t *currentthinker; void P_RemoveThinkerDelayed(thinker_t *thinker) { thinker_t *next; -#ifdef PARANOIA -#define BEENAROUNDBIT (0x40000000) // has to be sufficiently high that it's unlikely to happen in regular gameplay. If you change this, pay attention to the bit pattern of INT32_MIN. - if (thinker->references & ~BEENAROUNDBIT) + + if (thinker->references != 0) { - if (thinker->references & BEENAROUNDBIT) // Usually gets cleared up in one frame; what's going on here, then? - CONS_Printf("Number of potentially faulty references: %d\n", (thinker->references & ~BEENAROUNDBIT)); - thinker->references |= BEENAROUNDBIT; +#ifdef PARANOIA + if (thinker->debug_time > leveltime) + { + thinker->debug_time = leveltime + 2; // do not print errors again + } + // Removed mobjs can be the target of another mobj. In + // that case, the other mobj will manage its reference + // to the removed mobj in P_MobjThinker. However, if + // the removed mobj is removed after the other object + // thinks, the reference management is delayed by one + // tic. + else if (thinker->debug_time < leveltime) + { + CONS_Printf( + "PARANOIA/P_RemoveThinkerDelayed: %p %s references=%d\n", + (void*)thinker, + MobjTypeName((mobj_t*)thinker), + thinker->references + ); + + thinker->debug_time = leveltime + 2; // do not print this error again + } +#endif return; } -#undef BEENAROUNDBIT -#else - if (thinker->references) - return; -#endif /* Remove from main thinker list */ next = thinker->next; @@ -291,12 +350,45 @@ void P_RemoveThinker(thinker_t *thinker) * references, and delay removal until the count is 0. */ -mobj_t *P_SetTarget(mobj_t **mop, mobj_t *targ) +mobj_t *P_SetTarget2(mobj_t **mop, mobj_t *targ +#ifdef PARANOIA + , const char *source_file, int source_line +#endif +) { - if (*mop) // If there was a target already, decrease its refcount + if (*mop) // If there was a target already, decrease its refcount + { (*mop)->thinker.references--; -if ((*mop = targ) != NULL) // Set new target and if non-NULL, increase its counter + +#ifdef PARANOIA + if ((*mop)->thinker.references < 0) + { + CONS_Printf( + "PARANOIA/P_SetTarget: %p %s %s references=%d, references go negative! (%s:%d)\n", + (void*)*mop, + MobjTypeName(*mop), + MobjThinkerName(*mop), + (*mop)->thinker.references, + source_file, + source_line + ); + } + + (*mop)->thinker.debug_time = leveltime; +#endif + } + + if (targ != NULL) // Set new target and if non-NULL, increase its counter + { targ->thinker.references++; + +#ifdef PARANOIA + targ->thinker.debug_time = leveltime; +#endif + } + + *mop = targ; + return targ; } diff --git a/src/p_tick.h b/src/p_tick.h index 594bbc7afb608ce88a54b8f63ae7e5494f96af4f..bbc227e081433652a9a3d79b8ab0513c531677bc 100644 --- a/src/p_tick.h +++ b/src/p_tick.h @@ -14,6 +14,8 @@ #ifndef __P_TICK__ #define __P_TICK__ +#include "doomdef.h" + #ifdef __GNUG__ #pragma interface #endif @@ -28,6 +30,17 @@ void P_Ticker(boolean run); void P_PreTicker(INT32 frames); void P_DoTeamscrambling(void); void P_RemoveThinkerDelayed(thinker_t *thinker); //killed -mobj_t *P_SetTarget(mobj_t **mo, mobj_t *target); // killough 11/98 + +mobj_t *P_SetTarget2(mobj_t **mo, mobj_t *target +#ifdef PARANOIA + , const char *source_file, int source_line +#endif +); + +#ifdef PARANOIA +#define P_SetTarget(...) P_SetTarget2(__VA_ARGS__, __FILE__, __LINE__) +#else +#define P_SetTarget P_SetTarget2 +#endif #endif diff --git a/src/p_user.c b/src/p_user.c index 889e887c14ea2e28898896118b951782312965c8..3b2c60e3a6d744d5da157e0a5952efd5ad0cf3d4 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -1855,6 +1855,7 @@ void P_SpawnShieldOrb(player_t *player) { ov = P_SpawnMobj(shieldobj->x, shieldobj->y, shieldobj->z, MT_OVERLAY); P_SetTarget(&ov->target, shieldobj); + P_SetTarget(&ov->dontdrawforviewmobj, player->mo); // Hide the shield in first-person P_SetMobjState(ov, shieldobj->info->seestate); P_SetTarget(&shieldobj->tracer, ov); } @@ -1862,12 +1863,14 @@ void P_SpawnShieldOrb(player_t *player) { ov = P_SpawnMobj(shieldobj->x, shieldobj->y, shieldobj->z, MT_OVERLAY); P_SetTarget(&ov->target, shieldobj); + P_SetTarget(&ov->dontdrawforviewmobj, player->mo); // Hide the shield in first-person P_SetMobjState(ov, shieldobj->info->meleestate); } if (shieldobj->info->missilestate) { ov = P_SpawnMobj(shieldobj->x, shieldobj->y, shieldobj->z, MT_OVERLAY); P_SetTarget(&ov->target, shieldobj); + P_SetTarget(&ov->dontdrawforviewmobj, player->mo); // Hide the shield in first-person P_SetMobjState(ov, shieldobj->info->missilestate); } if (player->powers[pw_shield] & SH_FORCE) @@ -2005,14 +2008,14 @@ mobj_t *P_SpawnGhostMobj(mobj_t *mobj) ghost->standingslope = mobj->standingslope; if (mobj->flags2 & MF2_OBJECTFLIP) - ghost->flags |= MF2_OBJECTFLIP; + ghost->flags2 |= MF2_OBJECTFLIP; if (mobj->player && mobj->player->followmobj) { mobj_t *ghost2 = P_SpawnGhostMobj(mobj->player->followmobj); P_SetTarget(&ghost2->tracer, ghost); P_SetTarget(&ghost->tracer, ghost2); - P_SetTarget(&ghost2->dontdrawforviewmobj, mobj); // Hide the follow-ghost for the non-follow object + P_SetTarget(&ghost2->dontdrawforviewmobj, mobj); // Hide the follow-ghost for the non-follow target ghost2->flags2 |= (mobj->player->followmobj->flags2 & MF2_LINKDRAW); } @@ -8717,7 +8720,10 @@ void P_MovePlayer(player_t *player) player->mo->height = P_GetPlayerHeight(player); if (player->mo->eflags & MFE_VERTICALFLIP && player->mo->height != oldheight) // adjust z height for reverse gravity, similar to how it's done for scaling - player->mo->z -= player->mo->height - oldheight; + { + player->mo->z -= player->mo->height - oldheight; + player->mo->old_z -= player->mo->height - oldheight; // Snap the Z adjustment, while keeping the Z interpolation + } // Crush test... if ((player->mo->ceilingz - player->mo->floorz < player->mo->height) @@ -9287,7 +9293,7 @@ mobj_t *P_LookForEnemies(player_t *player, boolean nonenemies, boolean bullet) { fixed_t zdist = (player->mo->z + player->mo->height/2) - (mo->z + mo->height/2); - dist = P_AproxDistance(player->mo->x-mo->x, player->mo->y-mo->y); + dist = R_PointToDist2(0, 0, player->mo->x-mo->x, player->mo->y-mo->y); if (bullet) { if ((R_PointToAngle2(0, 0, dist, zdist) + span) > span*2) @@ -9304,7 +9310,7 @@ mobj_t *P_LookForEnemies(player_t *player, boolean nonenemies, boolean bullet) continue; } - dist = P_AproxDistance(dist, zdist); + dist = R_PointToDist2(0, 0, dist, zdist); if (dist > maxdist) continue; // out of range } @@ -11507,7 +11513,7 @@ static void P_DoMetalJetFume(player_t *player, mobj_t *fume) } fume->movecount = dashmode; // keeps track of previous dashmode value so we know whether Metal is entering or leaving it - fume->eflags = (fume->flags2 & ~MF2_OBJECTFLIP) | (mo->flags2 & MF2_OBJECTFLIP); // Make sure to flip in reverse gravity! + fume->flags2 = (fume->flags2 & ~MF2_OBJECTFLIP) | (mo->flags2 & MF2_OBJECTFLIP); // Make sure to flip in reverse gravity! fume->eflags = (fume->eflags & ~MFE_VERTICALFLIP) | (mo->eflags & MFE_VERTICALFLIP); // Make sure to flip in reverse gravity! // Finally, set its position @@ -11623,9 +11629,12 @@ void P_PlayerThink(player_t *player) cmd = &player->cmd; - // Add some extra randomization. - if (cmd->forwardmove) - P_RandomFixed(); + if (demoplayback && demo_forwardmove_rng) + { + // Smelly demo backwards compatibility + if (cmd->forwardmove) + P_RandomFixed(); + } #ifdef PARANOIA if (player->playerstate == PST_REBORN) @@ -11755,7 +11764,7 @@ void P_PlayerThink(player_t *player) if (!total || ((4*exiting)/total) >= numneeded) { if (server) - SendNetXCmd(XD_EXITLEVEL, NULL, 0); + D_SendExitLevel(false); } else player->exiting = 3; @@ -11763,7 +11772,7 @@ void P_PlayerThink(player_t *player) else { if (server) - SendNetXCmd(XD_EXITLEVEL, NULL, 0); + D_SendExitLevel(false); } } @@ -11861,7 +11870,7 @@ void P_PlayerThink(player_t *player) mo2 = (mobj_t *)th; if (!(mo2->type == MT_RING || mo2->type == MT_COIN - || mo2->type == MT_BLUESPHERE || mo2->type == MT_BOMBSPHERE + || mo2->type == MT_BLUESPHERE // || mo2->type == MT_BOMBSPHERE || mo2->type == MT_NIGHTSCHIP || mo2->type == MT_NIGHTSSTAR)) continue; diff --git a/src/r_bbox.c b/src/r_bbox.c index 59d0893c4bfe32bd0307573b9406bbff2df28924..cf417ec37639477b43a5a5e5035b059dc81490b4 100644 --- a/src/r_bbox.c +++ b/src/r_bbox.c @@ -34,7 +34,7 @@ static CV_PossibleValue_t renderhitbox_cons_t[] = { {RENDERHITBOX_RINGS, "Rings"}, {0}}; -consvar_t cv_renderhitbox = CVAR_INIT ("renderhitbox", "Off", CV_CHEAT, renderhitbox_cons_t, NULL); +consvar_t cv_renderhitbox = CVAR_INIT ("renderhitbox", "Off", CV_CHEAT|CV_NOTINNET, renderhitbox_cons_t, NULL); consvar_t cv_renderhitboxinterpolation = CVAR_INIT ("renderhitbox_interpolation", "On", CV_SAVE, CV_OnOff, NULL); consvar_t cv_renderhitboxgldepth = CVAR_INIT ("renderhitbox_gldepth", "Off", CV_SAVE, CV_OnOff, NULL); @@ -129,9 +129,6 @@ draw_bbox_row x1 = a->x; x2 = b->x; - if (x2 >= viewwidth) - x2 = viewwidth - 1; - if (x1 == x2 || x1 >= viewwidth || x2 < 0) return; @@ -159,6 +156,9 @@ draw_bbox_row x1 = 0; } + if (x2 >= viewwidth) + x2 = viewwidth - 1; + while (x1 < x2) { raster_bbox_seg(x1, y1, s1, bb->color); @@ -268,6 +268,9 @@ boolean R_ThingBoundingBoxVisible(mobj_t *thing) { INT32 cvmode = cv_renderhitbox.value; + if (multiplayer) // No hitboxes in multiplayer to avoid cheating + return false; + // Do not render bbox for these switch (thing->type) { diff --git a/src/r_defs.h b/src/r_defs.h index a9b9a4a0835a5969b93e4def8a2f231b5d565991..dfd2d6d708f8a5a9dae0da401719ad1d3eb24235 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -757,12 +757,12 @@ typedef struct drawseg_s // Pointers to lists for sprite clipping, all three adjusted so [x1] is first value. INT16 *sprtopclip; INT16 *sprbottomclip; - INT16 *maskedtexturecol; + fixed_t *maskedtexturecol; struct visplane_s *ffloorplanes[MAXFFLOORS]; INT32 numffloorplanes; struct ffloor_s *thicksides[MAXFFLOORS]; - INT16 *thicksidecol; + fixed_t *thicksidecol; INT32 numthicksides; fixed_t frontscale[MAXVIDWIDTH]; diff --git a/src/r_draw.c b/src/r_draw.c index b0467e4f728d4cf757b53484a3d5ca4fda9d91cc..df9e1a4608b568706452df29bbc347adef075b01 100644 --- a/src/r_draw.c +++ b/src/r_draw.c @@ -179,8 +179,6 @@ CV_PossibleValue_t Color_cons_t[MAXSKINCOLORS+1]; void R_InitTranslucencyTables(void) { // Load here the transparency lookup tables 'TRANSx0' - // NOTE: the TRANSx0 resources MUST BE aligned on 64k for the asm - // optimised code (in other words, transtables pointer low word is 0) transtables = Z_MallocAlign(NUMTRANSTABLES*0x10000, PU_STATIC, NULL, 16); diff --git a/src/r_draw.h b/src/r_draw.h index ea03a8e3d53e059570822a0119ee6431f45d105a..0103ed82782b22c7a51beb10c20473a3e8ba3787 100644 --- a/src/r_draw.h +++ b/src/r_draw.h @@ -225,18 +225,6 @@ void R_DrawTiltedTransSolidColorSpan_8(void); void R_DrawWaterSolidColorSpan_8(void); void R_DrawTiltedWaterSolidColorSpan_8(void); -#ifdef USEASM -void ASMCALL R_DrawColumn_8_ASM(void); -void ASMCALL R_DrawShadeColumn_8_ASM(void); -void ASMCALL R_DrawTranslucentColumn_8_ASM(void); -void ASMCALL R_Draw2sMultiPatchColumn_8_ASM(void); - -void ASMCALL R_DrawColumn_8_MMX(void); - -void ASMCALL R_Draw2sMultiPatchColumn_8_MMX(void); -void ASMCALL R_DrawSpan_8_MMX(void); -#endif - // ------------------ // 16bpp DRAWING CODE // ------------------ diff --git a/src/r_fps.c b/src/r_fps.c index c6eb5948212972d87d1e0079c668483fb927de94..de450aaa7f465b8d47891baec585c757de361c60 100644 --- a/src/r_fps.c +++ b/src/r_fps.c @@ -292,6 +292,8 @@ void R_InterpolateMobjState(mobj_t *mobj, fixed_t frac, interpmobjstate_t *out) out->y = mobj->y; out->z = mobj->z; out->scale = mobj->scale; + out->radius = mobj->radius; + out->height = mobj->height; out->subsector = mobj->subsector; out->angle = mobj->player ? mobj->player->drawangle : mobj->angle; out->pitch = mobj->pitch; @@ -307,10 +309,22 @@ void R_InterpolateMobjState(mobj_t *mobj, fixed_t frac, interpmobjstate_t *out) out->x = R_LerpFixed(mobj->old_x, mobj->x, frac); out->y = R_LerpFixed(mobj->old_y, mobj->y, frac); out->z = R_LerpFixed(mobj->old_z, mobj->z, frac); - out->scale = mobj->resetinterp ? mobj->scale : R_LerpFixed(mobj->old_scale, mobj->scale, frac); out->spritexscale = mobj->resetinterp ? mobj->spritexscale : R_LerpFixed(mobj->old_spritexscale, mobj->spritexscale, frac); out->spriteyscale = mobj->resetinterp ? mobj->spriteyscale : R_LerpFixed(mobj->old_spriteyscale, mobj->spriteyscale, frac); + if (mobj->scale == mobj->old_scale) // Tiny optimisation - scale is usually unchanging, so let's skip a lerp, two FixedMuls, and two FixedDivs + { + out->scale = mobj->scale; + out->radius = mobj->radius; + out->height = mobj->height; + } + else + { + out->scale = R_LerpFixed(mobj->old_scale, mobj->scale, frac); + out->radius = FixedMul(mobj->radius, FixedDiv(out->scale, mobj->scale)); + out->height = FixedMul(mobj->height, FixedDiv(out->scale, mobj->scale)); + } + // Sprite offsets are not interpolated until we have a way to interpolate them explicitly in Lua. // It seems existing mods visually break more often than not if it is interpolated. out->spritexoffset = mobj->spritexoffset; @@ -340,6 +354,8 @@ void R_InterpolatePrecipMobjState(precipmobj_t *mobj, fixed_t frac, interpmobjst out->y = mobj->y; out->z = mobj->z; out->scale = FRACUNIT; + out->radius = mobj->radius; + out->height = mobj->height; out->subsector = mobj->subsector; out->angle = mobj->angle; out->pitch = mobj->angle; @@ -356,6 +372,8 @@ void R_InterpolatePrecipMobjState(precipmobj_t *mobj, fixed_t frac, interpmobjst out->y = R_LerpFixed(mobj->old_y, mobj->y, frac); out->z = R_LerpFixed(mobj->old_z, mobj->z, frac); out->scale = FRACUNIT; + out->radius = mobj->radius; + out->height = mobj->height; out->spritexscale = R_LerpFixed(mobj->old_spritexscale, mobj->spritexscale, frac); out->spriteyscale = R_LerpFixed(mobj->old_spriteyscale, mobj->spriteyscale, frac); out->spritexoffset = R_LerpFixed(mobj->old_spritexoffset, mobj->spritexoffset, frac); diff --git a/src/r_fps.h b/src/r_fps.h index 9a8bfa38aeccfcab3dcd0654cd1380ac49f39d4f..f43d29f300a8a6707a3e4c6f5fa24e1e3f0ea37f 100644 --- a/src/r_fps.h +++ b/src/r_fps.h @@ -63,6 +63,8 @@ typedef struct { angle_t roll; angle_t spriteroll; fixed_t scale; + fixed_t radius; + fixed_t height; fixed_t spritexscale; fixed_t spriteyscale; fixed_t spritexoffset; diff --git a/src/r_main.c b/src/r_main.c index 55bb9c4ffefdfee11f38ec50a28cff7de2748ffb..54f7d7639e775f73b1d8de57d9923745eb9ff493 100644 --- a/src/r_main.c +++ b/src/r_main.c @@ -41,16 +41,6 @@ #include "hardware/hw_main.h" #endif -//profile stuff --------------------------------------------------------- -//#define TIMING -#ifdef TIMING -#include "p5prof.h" -INT64 mycount; -INT64 mytotal = 0; -//unsigned long nombre = 100000; -#endif -//profile stuff --------------------------------------------------------- - // Fineangles in the SCREENWIDTH wide window. #define FIELDOFVIEW 2048 @@ -157,7 +147,8 @@ consvar_t cv_flipcam2 = CVAR_INIT ("flipcam2", "No", CV_SAVE|CV_CALL|CV_NOINIT, consvar_t cv_shadow = CVAR_INIT ("shadow", "On", CV_SAVE, CV_OnOff, NULL); consvar_t cv_skybox = CVAR_INIT ("skybox", "On", CV_SAVE, CV_OnOff, NULL); -consvar_t cv_ffloorclip = CVAR_INIT ("ffloorclip", "On", CV_SAVE, CV_OnOff, NULL); +consvar_t cv_ffloorclip = CVAR_INIT ("r_ffloorclip", "On", CV_SAVE, CV_OnOff, NULL); +consvar_t cv_spriteclip = CVAR_INIT ("r_spriteclip", "On", CV_SAVE, CV_OnOff, NULL); consvar_t cv_allowmlook = CVAR_INIT ("allowmlook", "Yes", CV_NETVAR|CV_ALLOWLUA, CV_YesNo, NULL); consvar_t cv_showhud = CVAR_INIT ("showhud", "Yes", CV_CALL|CV_ALLOWLUA, CV_YesNo, R_SetViewSize); consvar_t cv_translucenthud = CVAR_INIT ("translucenthud", "10", CV_SAVE, translucenthud_cons_t, NULL); @@ -1479,6 +1470,7 @@ void R_RenderPlayerView(player_t *player) R_ClearClipSegs(); } R_ClearDrawSegs(); + R_ClearSegTables(); R_ClearSprites(); Portal_InitList(); @@ -1489,29 +1481,17 @@ void R_RenderPlayerView(player_t *player) Mask_Pre(&masks[nummasks - 1]); curdrawsegs = ds_p; -//profile stuff --------------------------------------------------------- -#ifdef TIMING - mytotal = 0; - ProfZeroTimer(); -#endif ps_numbspcalls.value.i = ps_numpolyobjects.value.i = ps_numdrawnodes.value.i = 0; PS_START_TIMING(ps_bsptime); R_RenderBSPNode((INT32)numnodes - 1); PS_STOP_TIMING(ps_bsptime); - ps_numsprites.value.i = visspritecount; -#ifdef TIMING - RDMSR(0x10, &mycount); - mytotal += mycount; // 64bit add - - CONS_Debug(DBG_RENDER, "RenderBSPNode: 0x%d %d\n", *((INT32 *)&mytotal + 1), (INT32)mytotal); -#endif -//profile stuff --------------------------------------------------------- Mask_Post(&masks[nummasks - 1]); PS_START_TIMING(ps_sw_spritecliptime); R_ClipSprites(drawsegs, NULL); PS_STOP_TIMING(ps_sw_spritecliptime); + ps_numsprites.value.i = numvisiblesprites; // Add skybox portals caused by sky visplanes. if (cv_skybox.value && skyboxmo[0]) @@ -1602,6 +1582,7 @@ void R_RegisterEngineStuff(void) CV_RegisterVar(&cv_shadow); CV_RegisterVar(&cv_skybox); CV_RegisterVar(&cv_ffloorclip); + CV_RegisterVar(&cv_spriteclip); CV_RegisterVar(&cv_cam_dist); CV_RegisterVar(&cv_cam_still); diff --git a/src/r_main.h b/src/r_main.h index f08070d0f387b544c9b0b5089e65b6251999db99..a6fb42ba2410ba42c8adc7ba84ef8fde21e0802f 100644 --- a/src/r_main.h +++ b/src/r_main.h @@ -114,7 +114,7 @@ extern consvar_t cv_chasecam, cv_chasecam2; extern consvar_t cv_flipcam, cv_flipcam2; extern consvar_t cv_shadow; -extern consvar_t cv_ffloorclip; +extern consvar_t cv_ffloorclip, cv_spriteclip; extern consvar_t cv_translucency; extern consvar_t cv_drawdist, cv_drawdist_nights, cv_drawdist_precip; extern consvar_t cv_fov; diff --git a/src/r_plane.c b/src/r_plane.c index c568484b6ed7e71335a665a40710753d2608133f..29ce26b292e5ea529d937aded0028e41a8d294ba 100644 --- a/src/r_plane.c +++ b/src/r_plane.c @@ -53,10 +53,6 @@ INT32 numffloors; #define visplane_hash(picnum,lightlevel,height) \ ((unsigned)((picnum)*3+(lightlevel)+(height)*7) & VISPLANEHASHMASK) -//SoM: 3/23/2000: Use boom opening limit removal -size_t maxopenings; -INT16 *openings, *lastopening; /// \todo free leak - // // Clip values are the solid pixel bounding the range. // floorclip starts out SCREENHEIGHT @@ -366,8 +362,6 @@ void R_ClearPlanes(void) freehead = &(*freehead)->next; } - lastopening = openings; - // texture calculation memset(cachedheight, 0, sizeof (cachedheight)); } diff --git a/src/r_plane.h b/src/r_plane.h index 9870a43e26286e5e888a13f20fa72ecf8b38be08..917e8b041b75775016dbc2a1e10b8cc6ad7a3778 100644 --- a/src/r_plane.h +++ b/src/r_plane.h @@ -60,9 +60,6 @@ extern visplane_t *floorplane; extern visplane_t *ceilingplane; // Visplane related. -extern INT16 *lastopening, *openings; -extern size_t maxopenings; - extern INT16 floorclip[MAXVIDWIDTH], ceilingclip[MAXVIDWIDTH]; extern fixed_t frontscale[MAXVIDWIDTH], yslopetab[MAXVIDHEIGHT*16]; extern fixed_t cachedheight[MAXVIDHEIGHT]; diff --git a/src/r_segs.c b/src/r_segs.c index facab62ab76479faeaabccc5a4f14a64446db40b..9af83f0c7ff8af10057f253a5419dca41c86638c 100644 --- a/src/r_segs.c +++ b/src/r_segs.c @@ -71,9 +71,22 @@ static fixed_t topfrac, topstep; static fixed_t bottomfrac, bottomstep; static lighttable_t **walllights; -static INT16 *maskedtexturecol; +static fixed_t *maskedtexturecol; static fixed_t *maskedtextureheight = NULL; +//SoM: 3/23/2000: Use boom opening limit removal +static size_t numopenings; +static INT16 *openings, *lastopening; + +static size_t texturecolumntablesize; +static fixed_t *texturecolumntable, *curtexturecolumntable; + +void R_ClearSegTables(void) +{ + lastopening = openings; + curtexturecolumntable = texturecolumntable; +} + // ========================================================================== // R_RenderMaskedSegRange // ========================================================================== @@ -350,170 +363,115 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2) dc_texturemid += (textureheight[texnum])*times + textureheight[texnum]; else dc_texturemid -= (textureheight[texnum])*times; - // calculate lighting - if (maskedtexturecol[dc_x] != INT16_MAX) + + // Check for overflows first + overflow_test = (INT64)centeryfrac - (((INT64)dc_texturemid*spryscale)>>FRACBITS); + if (overflow_test < 0) overflow_test = -overflow_test; + if ((UINT64)overflow_test&0xFFFFFFFF80000000ULL) { - // Check for overflows first - overflow_test = (INT64)centeryfrac - (((INT64)dc_texturemid*spryscale)>>FRACBITS); - if (overflow_test < 0) overflow_test = -overflow_test; - if ((UINT64)overflow_test&0xFFFFFFFF80000000ULL) + // Eh, no, go away, don't waste our time + if (dc_numlights) { - // Eh, no, go away, don't waste our time - if (dc_numlights) + for (i = 0; i < dc_numlights; i++) { - for (i = 0; i < dc_numlights; i++) - { - rlight = &dc_lightlist[i]; - rlight->height += rlight->heightstep; - } + rlight = &dc_lightlist[i]; + rlight->height += rlight->heightstep; } - spryscale += rw_scalestep; - continue; } + spryscale += rw_scalestep; + continue; + } - if (dc_numlights) - { - lighttable_t **xwalllights; - - sprbotscreen = INT32_MAX; - sprtopscreen = windowtop = (centeryfrac - FixedMul(dc_texturemid, spryscale)); - - realbot = windowbottom = FixedMul(textureheight[texnum], spryscale) + sprtopscreen; - dc_iscale = 0xffffffffu / (unsigned)spryscale; + // calculate lighting + if (dc_numlights) + { + lighttable_t **xwalllights; - // draw the texture - col = (column_t *)((UINT8 *)R_GetColumn(texnum, maskedtexturecol[dc_x]) - 3); + sprbotscreen = INT32_MAX; + sprtopscreen = windowtop = (centeryfrac - FixedMul(dc_texturemid, spryscale)); - for (i = 0; i < dc_numlights; i++) - { - rlight = &dc_lightlist[i]; + realbot = windowbottom = FixedMul(textureheight[texnum], spryscale) + sprtopscreen; + dc_iscale = 0xffffffffu / (unsigned)spryscale; - if ((rlight->flags & FOF_NOSHADE)) - continue; + // draw the texture + col = (column_t *)((UINT8 *)R_GetColumn(texnum, (maskedtexturecol[dc_x] >> FRACBITS)) - 3); - if (rlight->lightnum < 0) - xwalllights = scalelight[0]; - else if (rlight->lightnum >= LIGHTLEVELS) - xwalllights = scalelight[LIGHTLEVELS-1]; - else - xwalllights = scalelight[rlight->lightnum]; + for (i = 0; i < dc_numlights; i++) + { + rlight = &dc_lightlist[i]; - pindex = FixedMul(spryscale, LIGHTRESOLUTIONFIX)>>LIGHTSCALESHIFT; + if ((rlight->flags & FOF_NOSHADE)) + continue; - if (pindex >= MAXLIGHTSCALE) - pindex = MAXLIGHTSCALE - 1; + if (rlight->lightnum < 0) + xwalllights = scalelight[0]; + else if (rlight->lightnum >= LIGHTLEVELS) + xwalllights = scalelight[LIGHTLEVELS-1]; + else + xwalllights = scalelight[rlight->lightnum]; - if (rlight->extra_colormap) - rlight->rcolormap = rlight->extra_colormap->colormap + (xwalllights[pindex] - colormaps); - else - rlight->rcolormap = xwalllights[pindex]; + pindex = FixedMul(spryscale, LIGHTRESOLUTIONFIX)>>LIGHTSCALESHIFT; - height = rlight->height; - rlight->height += rlight->heightstep; + if (pindex >= MAXLIGHTSCALE) + pindex = MAXLIGHTSCALE - 1; - if (height <= windowtop) - { - dc_colormap = rlight->rcolormap; - continue; - } + if (rlight->extra_colormap) + rlight->rcolormap = rlight->extra_colormap->colormap + (xwalllights[pindex] - colormaps); + else + rlight->rcolormap = xwalllights[pindex]; - windowbottom = height; - if (windowbottom >= realbot) - { - windowbottom = realbot; - colfunc_2s(col); - for (i++; i < dc_numlights; i++) - { - rlight = &dc_lightlist[i]; - rlight->height += rlight->heightstep; - } + height = rlight->height; + rlight->height += rlight->heightstep; - continue; - } - colfunc_2s(col); - windowtop = windowbottom + 1; + if (height <= windowtop) + { dc_colormap = rlight->rcolormap; + continue; } - windowbottom = realbot; - if (windowtop < windowbottom) + + windowbottom = height; + if (windowbottom >= realbot) + { + windowbottom = realbot; colfunc_2s(col); + for (i++; i < dc_numlights; i++) + { + rlight = &dc_lightlist[i]; + rlight->height += rlight->heightstep; + } - spryscale += rw_scalestep; - continue; + continue; + } + colfunc_2s(col); + windowtop = windowbottom + 1; + dc_colormap = rlight->rcolormap; } + windowbottom = realbot; + if (windowtop < windowbottom) + colfunc_2s(col); - // calculate lighting - pindex = FixedMul(spryscale, LIGHTRESOLUTIONFIX)>>LIGHTSCALESHIFT; - - if (pindex >= MAXLIGHTSCALE) - pindex = MAXLIGHTSCALE - 1; - - dc_colormap = walllights[pindex]; - - if (frontsector->extra_colormap) - dc_colormap = frontsector->extra_colormap->colormap + (dc_colormap - colormaps); - - sprtopscreen = centeryfrac - FixedMul(dc_texturemid, spryscale); - dc_iscale = 0xffffffffu / (unsigned)spryscale; - - // draw the texture - col = (column_t *)((UINT8 *)R_GetColumn(texnum, maskedtexturecol[dc_x]) - 3); - -#if 0 // Disabling this allows inside edges to render below the planes, for until the clipping is fixed to work right when POs are near the camera. -Red - if (curline->dontrenderme && curline->polyseg && (curline->polyseg->flags & POF_RENDERPLANES)) - { - fixed_t my_topscreen; - fixed_t my_bottomscreen; - fixed_t my_yl, my_yh; + spryscale += rw_scalestep; + continue; + } - my_topscreen = sprtopscreen + spryscale*col->topdelta; - my_bottomscreen = sprbotscreen == INT32_MAX ? my_topscreen + spryscale*col->length - : sprbotscreen + spryscale*col->length; + // calculate lighting + pindex = FixedMul(spryscale, LIGHTRESOLUTIONFIX)>>LIGHTSCALESHIFT; - my_yl = (my_topscreen+FRACUNIT-1)>>FRACBITS; - my_yh = (my_bottomscreen-1)>>FRACBITS; - // CONS_Debug(DBG_RENDER, "my_topscreen: %d\nmy_bottomscreen: %d\nmy_yl: %d\nmy_yh: %d\n", my_topscreen, my_bottomscreen, my_yl, my_yh); + if (pindex >= MAXLIGHTSCALE) + pindex = MAXLIGHTSCALE - 1; - if (numffloors) - { - INT32 top = my_yl; - INT32 bottom = my_yh; + dc_colormap = walllights[pindex]; - for (i = 0; i < numffloors; i++) - { - if (!ffloor[i].polyobj || ffloor[i].polyobj != curline->polyseg) - continue; + if (frontsector->extra_colormap) + dc_colormap = frontsector->extra_colormap->colormap + (dc_colormap - colormaps); - if (ffloor[i].height < viewz) - { - INT32 top_w = ffloor[i].plane->top[dc_x]; + sprtopscreen = centeryfrac - FixedMul(dc_texturemid, spryscale); + dc_iscale = 0xffffffffu / (unsigned)spryscale; - // CONS_Debug(DBG_RENDER, "Leveltime : %d\n", leveltime); - // CONS_Debug(DBG_RENDER, "Top is %d, top_w is %d\n", top, top_w); - if (top_w < top) - { - ffloor[i].plane->top[dc_x] = (INT16)top; - ffloor[i].plane->picnum = 0; - } - // CONS_Debug(DBG_RENDER, "top_w is now %d\n", ffloor[i].plane->top[dc_x]); - } - else if (ffloor[i].height > viewz) - { - INT32 bottom_w = ffloor[i].plane->bottom[dc_x]; + // draw the texture + col = (column_t *)((UINT8 *)R_GetColumn(texnum, (maskedtexturecol[dc_x] >> FRACBITS)) - 3); + colfunc_2s(col); - if (bottom_w > bottom) - { - ffloor[i].plane->bottom[dc_x] = (INT16)bottom; - ffloor[i].plane->picnum = 0; - } - } - } - } - } - else -#endif - colfunc_2s(col); - } spryscale += rw_scalestep; } } @@ -857,183 +815,182 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) // draw the columns for (dc_x = x1; dc_x <= x2; dc_x++) { - if (maskedtexturecol[dc_x] != INT16_MAX) + // skew FOF walls + if (ffloortextureslide) { - if (ffloortextureslide) { // skew FOF walls - if (oldx != -1) - dc_texturemid += FixedMul(ffloortextureslide, (maskedtexturecol[oldx]-maskedtexturecol[dc_x])<<FRACBITS); - oldx = dc_x; - } - // Calculate bounds - // clamp the values if necessary to avoid overflows and rendering glitches caused by them + if (oldx != -1) + dc_texturemid += FixedMul(ffloortextureslide, maskedtexturecol[oldx]-maskedtexturecol[dc_x]); + oldx = dc_x; + } - if (top_frac > (INT64)CLAMPMAX) sprtopscreen = windowtop = CLAMPMAX; - else if (top_frac > (INT64)CLAMPMIN) sprtopscreen = windowtop = (fixed_t)top_frac; - else sprtopscreen = windowtop = CLAMPMIN; - if (bottom_frac > (INT64)CLAMPMAX) sprbotscreen = windowbottom = CLAMPMAX; - else if (bottom_frac > (INT64)CLAMPMIN) sprbotscreen = windowbottom = (fixed_t)bottom_frac; - else sprbotscreen = windowbottom = CLAMPMIN; + // Calculate bounds + // clamp the values if necessary to avoid overflows and rendering glitches caused by them + if (top_frac > (INT64)CLAMPMAX) sprtopscreen = windowtop = CLAMPMAX; + else if (top_frac > (INT64)CLAMPMIN) sprtopscreen = windowtop = (fixed_t)top_frac; + else sprtopscreen = windowtop = CLAMPMIN; + if (bottom_frac > (INT64)CLAMPMAX) sprbotscreen = windowbottom = CLAMPMAX; + else if (bottom_frac > (INT64)CLAMPMIN) sprbotscreen = windowbottom = (fixed_t)bottom_frac; + else sprbotscreen = windowbottom = CLAMPMIN; - top_frac += top_step; - bottom_frac += bottom_step; + top_frac += top_step; + bottom_frac += bottom_step; - // SoM: If column is out of range, why bother with it?? - if (windowbottom < topbounds || windowtop > bottombounds) + // SoM: If column is out of range, why bother with it?? + if (windowbottom < topbounds || windowtop > bottombounds) + { + if (dc_numlights) { - if (dc_numlights) + for (i = 0; i < dc_numlights; i++) { - for (i = 0; i < dc_numlights; i++) - { - rlight = &dc_lightlist[i]; - rlight->height += rlight->heightstep; - if (rlight->flags & FOF_CUTLEVEL) - rlight->botheight += rlight->botheightstep; - } + rlight = &dc_lightlist[i]; + rlight->height += rlight->heightstep; + if (rlight->flags & FOF_CUTLEVEL) + rlight->botheight += rlight->botheightstep; } - spryscale += rw_scalestep; - continue; } + spryscale += rw_scalestep; + continue; + } - dc_iscale = 0xffffffffu / (unsigned)spryscale; + dc_iscale = 0xffffffffu / (unsigned)spryscale; - // Get data for the column - col = (column_t *)((UINT8 *)R_GetColumn(texnum,maskedtexturecol[dc_x]) - 3); + // Get data for the column + col = (column_t *)((UINT8 *)R_GetColumn(texnum, (maskedtexturecol[dc_x] >> FRACBITS)) - 3); - // SoM: New code does not rely on R_DrawColumnShadowed_8 which - // will (hopefully) put less strain on the stack. - if (dc_numlights) - { - lighttable_t **xwalllights; - fixed_t height; - fixed_t bheight = 0; - INT32 solid = 0; - INT32 lighteffect = 0; + // SoM: New code does not rely on R_DrawColumnShadowed_8 which + // will (hopefully) put less strain on the stack. + if (dc_numlights) + { + lighttable_t **xwalllights; + fixed_t height; + fixed_t bheight = 0; + INT32 solid = 0; + INT32 lighteffect = 0; - for (i = 0; i < dc_numlights; i++) + for (i = 0; i < dc_numlights; i++) + { + // Check if the current light effects the colormap/lightlevel + rlight = &dc_lightlist[i]; + lighteffect = !(dc_lightlist[i].flags & FOF_NOSHADE); + if (lighteffect) { - // Check if the current light effects the colormap/lightlevel - rlight = &dc_lightlist[i]; - lighteffect = !(dc_lightlist[i].flags & FOF_NOSHADE); - if (lighteffect) - { - lightnum = rlight->lightnum; - - if (lightnum < 0) - xwalllights = scalelight[0]; - else if (lightnum >= LIGHTLEVELS) - xwalllights = scalelight[LIGHTLEVELS-1]; - else - xwalllights = scalelight[lightnum]; - - pindex = FixedMul(spryscale, LIGHTRESOLUTIONFIX)>>LIGHTSCALESHIFT; + lightnum = rlight->lightnum; - if (pindex >= MAXLIGHTSCALE) - pindex = MAXLIGHTSCALE-1; + if (lightnum < 0) + xwalllights = scalelight[0]; + else if (lightnum >= LIGHTLEVELS) + xwalllights = scalelight[LIGHTLEVELS-1]; + else + xwalllights = scalelight[lightnum]; - if (pfloor->fofflags & FOF_FOG) - { - if (pfloor->master->frontsector->extra_colormap) - rlight->rcolormap = pfloor->master->frontsector->extra_colormap->colormap + (xwalllights[pindex] - colormaps); - else - rlight->rcolormap = xwalllights[pindex]; - } - else - { - if (rlight->extra_colormap) - rlight->rcolormap = rlight->extra_colormap->colormap + (xwalllights[pindex] - colormaps); - else - rlight->rcolormap = xwalllights[pindex]; - } - } + pindex = FixedMul(spryscale, LIGHTRESOLUTIONFIX)>>LIGHTSCALESHIFT; - solid = 0; // don't carry over solid-cutting flag from the previous light + if (pindex >= MAXLIGHTSCALE) + pindex = MAXLIGHTSCALE-1; - // Check if the current light can cut the current 3D floor. - if (rlight->flags & FOF_CUTSOLIDS && !(pfloor->fofflags & FOF_EXTRA)) - solid = 1; - else if (rlight->flags & FOF_CUTEXTRA && pfloor->fofflags & FOF_EXTRA) + if (pfloor->fofflags & FOF_FOG) { - if (rlight->flags & FOF_EXTRA) - { - // The light is from an extra 3D floor... Check the flags so - // there are no undesired cuts. - if ((rlight->flags & (FOF_FOG|FOF_SWIMMABLE)) == (pfloor->fofflags & (FOF_FOG|FOF_SWIMMABLE))) - solid = 1; - } + if (pfloor->master->frontsector->extra_colormap) + rlight->rcolormap = pfloor->master->frontsector->extra_colormap->colormap + (xwalllights[pindex] - colormaps); else - solid = 1; + rlight->rcolormap = xwalllights[pindex]; } else - solid = 0; - - height = rlight->height; - rlight->height += rlight->heightstep; - - if (solid) { - bheight = rlight->botheight - (FRACUNIT >> 1); - rlight->botheight += rlight->botheightstep; + if (rlight->extra_colormap) + rlight->rcolormap = rlight->extra_colormap->colormap + (xwalllights[pindex] - colormaps); + else + rlight->rcolormap = xwalllights[pindex]; } + } - if (height <= windowtop) - { - if (lighteffect) - dc_colormap = rlight->rcolormap; - if (solid && windowtop < bheight) - windowtop = bheight; - continue; - } + solid = 0; // don't carry over solid-cutting flag from the previous light - windowbottom = height; - if (windowbottom >= sprbotscreen) + // Check if the current light can cut the current 3D floor. + if (rlight->flags & FOF_CUTSOLIDS && !(pfloor->fofflags & FOF_EXTRA)) + solid = 1; + else if (rlight->flags & FOF_CUTEXTRA && pfloor->fofflags & FOF_EXTRA) + { + if (rlight->flags & FOF_EXTRA) { - windowbottom = sprbotscreen; - // draw the texture - colfunc_2s (col); - for (i++; i < dc_numlights; i++) - { - rlight = &dc_lightlist[i]; - rlight->height += rlight->heightstep; - if (rlight->flags & FOF_CUTLEVEL) - rlight->botheight += rlight->botheightstep; - } - continue; + // The light is from an extra 3D floor... Check the flags so + // there are no undesired cuts. + if ((rlight->flags & (FOF_FOG|FOF_SWIMMABLE)) == (pfloor->fofflags & (FOF_FOG|FOF_SWIMMABLE))) + solid = 1; } - // draw the texture - colfunc_2s (col); - if (solid) - windowtop = bheight; else - windowtop = windowbottom + 1; + solid = 1; + } + else + solid = 0; + + height = rlight->height; + rlight->height += rlight->heightstep; + + if (solid) + { + bheight = rlight->botheight - (FRACUNIT >> 1); + rlight->botheight += rlight->botheightstep; + } + + if (height <= windowtop) + { if (lighteffect) dc_colormap = rlight->rcolormap; + if (solid && windowtop < bheight) + windowtop = bheight; + continue; } - windowbottom = sprbotscreen; - // draw the texture, if there is any space left - if (windowtop < windowbottom) - colfunc_2s (col); - spryscale += rw_scalestep; - continue; + windowbottom = height; + if (windowbottom >= sprbotscreen) + { + windowbottom = sprbotscreen; + // draw the texture + colfunc_2s (col); + for (i++; i < dc_numlights; i++) + { + rlight = &dc_lightlist[i]; + rlight->height += rlight->heightstep; + if (rlight->flags & FOF_CUTLEVEL) + rlight->botheight += rlight->botheightstep; + } + continue; + } + // draw the texture + colfunc_2s (col); + if (solid) + windowtop = bheight; + else + windowtop = windowbottom + 1; + if (lighteffect) + dc_colormap = rlight->rcolormap; } + windowbottom = sprbotscreen; + // draw the texture, if there is any space left + if (windowtop < windowbottom) + colfunc_2s (col); - // calculate lighting - pindex = FixedMul(spryscale, LIGHTRESOLUTIONFIX)>>LIGHTSCALESHIFT; + spryscale += rw_scalestep; + continue; + } - if (pindex >= MAXLIGHTSCALE) - pindex = MAXLIGHTSCALE - 1; + // calculate lighting + pindex = FixedMul(spryscale, LIGHTRESOLUTIONFIX)>>LIGHTSCALESHIFT; - dc_colormap = walllights[pindex]; + if (pindex >= MAXLIGHTSCALE) + pindex = MAXLIGHTSCALE - 1; - if (pfloor->fofflags & FOF_FOG && pfloor->master->frontsector->extra_colormap) - dc_colormap = pfloor->master->frontsector->extra_colormap->colormap + (dc_colormap - colormaps); - else if (frontsector->extra_colormap) - dc_colormap = frontsector->extra_colormap->colormap + (dc_colormap - colormaps); + dc_colormap = walllights[pindex]; - // draw the texture - colfunc_2s (col); - spryscale += rw_scalestep; - } + if (pfloor->fofflags & FOF_FOG && pfloor->master->frontsector->extra_colormap) + dc_colormap = pfloor->master->frontsector->extra_colormap->colormap + (dc_colormap - colormaps); + else if (frontsector->extra_colormap) + dc_colormap = frontsector->extra_colormap->colormap + (dc_colormap - colormaps); + + // draw the texture + colfunc_2s (col); + spryscale += rw_scalestep; } colfunc = colfuncs[BASEDRAWFUNC]; @@ -1270,7 +1227,7 @@ static void R_RenderSegLoop (void) } oldtexturecolumn = texturecolumn; - texturecolumn >>= FRACBITS; + INT32 itexturecolumn = texturecolumn >> FRACBITS; // texturecolumn and lighting are independent of wall tiers if (segtextured) @@ -1336,7 +1293,7 @@ static void R_RenderSegLoop (void) dc_yl = yl; dc_yh = yh; dc_texturemid = rw_midtexturemid; - dc_source = R_GetColumn(midtexture,texturecolumn + (rw_offset_mid>>FRACBITS)); + dc_source = R_GetColumn(midtexture, itexturecolumn + (rw_offset_mid>>FRACBITS)); dc_texheight = textureheight[midtexture]>>FRACBITS; //profile stuff --------------------------------------------------------- @@ -1397,7 +1354,7 @@ static void R_RenderSegLoop (void) dc_yl = yl; dc_yh = mid; dc_texturemid = rw_toptexturemid; - dc_source = R_GetColumn(toptexture,texturecolumn + (rw_offset_top>>FRACBITS)); + dc_source = R_GetColumn(toptexture, itexturecolumn + (rw_offset_top>>FRACBITS)); dc_texheight = textureheight[toptexture]>>FRACBITS; colfunc(); ceilingclip[rw_x] = (INT16)mid; @@ -1433,8 +1390,7 @@ static void R_RenderSegLoop (void) dc_yl = mid; dc_yh = yh; dc_texturemid = rw_bottomtexturemid; - dc_source = R_GetColumn(bottomtexture, - texturecolumn + (rw_offset_bot>>FRACBITS)); + dc_source = R_GetColumn(bottomtexture, itexturecolumn + (rw_offset_bot>>FRACBITS)); dc_texheight = textureheight[bottomtexture]>>FRACBITS; colfunc(); floorclip[rw_x] = (INT16)mid; @@ -1453,7 +1409,7 @@ static void R_RenderSegLoop (void) { // save texturecol // for backdrawing of masked mid texture - maskedtexturecol[rw_x] = (INT16)(texturecolumn + (rw_offset_mid>>FRACBITS)); + maskedtexturecol[rw_x] = texturecolumn + rw_offset_mid; if (maskedtextureheight != NULL) { maskedtextureheight[rw_x] = (curline->linedef->flags & ML_MIDPEG) ? @@ -1512,6 +1468,73 @@ static INT64 R_CalcSegDist(seg_t* seg, INT64 x2, INT64 y2) } } +//SoM: Code to remove limits on openings. +static void R_AllocClippingTables(size_t range) +{ + size_t pos = lastopening - openings; + size_t need = range * 2; // for both sprtopclip and sprbottomclip + + if (pos + need < numopenings) + return; + + INT16 *oldopenings = openings; + INT16 *oldlast = lastopening; + + if (numopenings == 0) + numopenings = 16384; + + numopenings += need; + openings = Z_Realloc(openings, numopenings * sizeof (*openings), PU_STATIC, NULL); + lastopening = openings + pos; + + if (oldopenings == NULL) + return; + + // borrowed fix from *cough* zdoom *cough* + // [RH] We also need to adjust the openings pointers that + // were already stored in drawsegs. + for (drawseg_t *ds = drawsegs; ds < ds_p; ds++) + { + // Check if it's in range of the openings + if (ds->sprtopclip + ds->x1 >= oldopenings && ds->sprtopclip + ds->x1 <= oldlast) + ds->sprtopclip = (ds->sprtopclip - oldopenings) + openings; + if (ds->sprbottomclip + ds->x1 >= oldopenings && ds->sprbottomclip + ds->x1 <= oldlast) + ds->sprbottomclip = (ds->sprbottomclip - oldopenings) + openings; + } +} + +static void R_AllocTextureColumnTables(size_t range) +{ + size_t pos = curtexturecolumntable - texturecolumntable; + + // For both tables, we reserve exactly an amount of memory that's equivalent to + // how many columns the seg will take on the entire screen (think about it) + if (pos + range < texturecolumntablesize) + return; + + fixed_t *oldtable = texturecolumntable; + fixed_t *oldlast = curtexturecolumntable; + + if (texturecolumntablesize == 0) + texturecolumntablesize = 16384; + + texturecolumntablesize += range; + texturecolumntable = Z_Realloc(texturecolumntable, texturecolumntablesize * sizeof (*texturecolumntable), PU_STATIC, NULL); + curtexturecolumntable = texturecolumntable + pos; + + if (oldtable == NULL) + return; + + for (drawseg_t *ds = drawsegs; ds < ds_p; ds++) + { + // Check if it's in range of the tables + if (ds->maskedtexturecol + ds->x1 >= oldtable && ds->maskedtexturecol + ds->x1 <= oldlast) + ds->maskedtexturecol = (ds->maskedtexturecol - oldtable) + texturecolumntable; + if (ds->thicksidecol + ds->x1 >= oldtable && ds->thicksidecol + ds->x1 <= oldlast) + ds->thicksidecol = (ds->thicksidecol - oldtable) + texturecolumntable; + } +} + // // R_StoreWallRange // A wall segment will be drawn @@ -1580,37 +1603,6 @@ void R_StoreWallRange(INT32 start, INT32 stop) ds_p->curline = curline; rw_stopx = stop+1; - //SoM: Code to remove limits on openings. - { - size_t pos = lastopening - openings; - size_t need = (rw_stopx - start)*4 + pos; - if (need > maxopenings) - { - drawseg_t *ds; //needed for fix from *cough* zdoom *cough* - INT16 *oldopenings = openings; - INT16 *oldlast = lastopening; - - do - maxopenings = maxopenings ? maxopenings*2 : 16384; - while (need > maxopenings); - openings = Z_Realloc(openings, maxopenings * sizeof (*openings), PU_STATIC, NULL); - lastopening = openings + pos; - - // borrowed fix from *cough* zdoom *cough* - // [RH] We also need to adjust the openings pointers that - // were already stored in drawsegs. - for (ds = drawsegs; ds < ds_p; ds++) - { -#define ADJUST(p) if (ds->p + ds->x1 >= oldopenings && ds->p + ds->x1 <= oldlast) ds->p = ds->p - oldopenings + openings; - ADJUST(maskedtexturecol); - ADJUST(sprtopclip); - ADJUST(sprbottomclip); - ADJUST(thicksidecol); -#undef ADJUST - } - } - } // end of code to remove limits on openings - // calculate scale at both ends and step ds_p->scale1 = rw_scale = R_ScaleFromGlobalAngle(viewangle + xtoviewangle[start]); @@ -2026,6 +2018,8 @@ void R_StoreWallRange(INT32 start, INT32 stop) rw_toptexturemid += sidedef->rowoffset + sidedef->offsety_top; rw_bottomtexturemid += sidedef->rowoffset + sidedef->offsety_bot; + R_AllocTextureColumnTables(rw_stopx - start); + // allocate space for masked texture tables if (frontsector && backsector && !Tag_Compare(&frontsector->tags, &backsector->tags) && (backsector->ffloors || frontsector->ffloors)) { @@ -2040,8 +2034,8 @@ void R_StoreWallRange(INT32 start, INT32 stop) //markceiling = markfloor = true; maskedtexture = true; - ds_p->thicksidecol = maskedtexturecol = lastopening - rw_x; - lastopening += rw_stopx - rw_x; + ds_p->thicksidecol = maskedtexturecol = curtexturecolumntable - rw_x; + curtexturecolumntable += rw_stopx - rw_x; lowcut = max(worldbottom, worldlow) + viewz; highcut = min(worldtop, worldhigh) + viewz; @@ -2224,8 +2218,8 @@ void R_StoreWallRange(INT32 start, INT32 stop) // masked midtexture if (!ds_p->thicksidecol) { - ds_p->maskedtexturecol = maskedtexturecol = lastopening - rw_x; - lastopening += rw_stopx - rw_x; + ds_p->maskedtexturecol = maskedtexturecol = curtexturecolumntable - rw_x; + curtexturecolumntable += rw_stopx - rw_x; } else ds_p->maskedtexturecol = ds_p->thicksidecol; @@ -2737,29 +2731,34 @@ void R_StoreWallRange(INT32 start, INT32 stop) ds_p->portalpass = 0; // save sprite clipping info - if (((ds_p->silhouette & SIL_TOP) || maskedtexture) && !ds_p->sprtopclip) + if (maskedtexture || (ds_p->silhouette & (SIL_TOP | SIL_BOTTOM))) { - M_Memcpy(lastopening, ceilingclip+start, 2*(rw_stopx - start)); - ds_p->sprtopclip = lastopening - start; - lastopening += rw_stopx - start; - } + R_AllocClippingTables(rw_stopx - start); - if (((ds_p->silhouette & SIL_BOTTOM) || maskedtexture) && !ds_p->sprbottomclip) - { - M_Memcpy(lastopening, floorclip + start, 2*(rw_stopx-start)); - ds_p->sprbottomclip = lastopening - start; - lastopening += rw_stopx - start; + if (((ds_p->silhouette & SIL_TOP) || maskedtexture) && !ds_p->sprtopclip) + { + M_Memcpy(lastopening, ceilingclip + start, 2*(rw_stopx - start)); + ds_p->sprtopclip = lastopening - start; + lastopening += rw_stopx - start; + } + + if (((ds_p->silhouette & SIL_BOTTOM) || maskedtexture) && !ds_p->sprbottomclip) + { + M_Memcpy(lastopening, floorclip + start, 2*(rw_stopx - start)); + ds_p->sprbottomclip = lastopening - start; + lastopening += rw_stopx - start; + } } if (maskedtexture && !(ds_p->silhouette & SIL_TOP)) { ds_p->silhouette |= SIL_TOP; - ds_p->tsilheight = (sidedef->midtexture > 0 && sidedef->midtexture < numtextures) ? INT32_MIN: INT32_MAX; + ds_p->tsilheight = (sidedef->midtexture > 0 && sidedef->midtexture < numtextures) ? INT32_MIN : INT32_MAX; } if (maskedtexture && !(ds_p->silhouette & SIL_BOTTOM)) { ds_p->silhouette |= SIL_BOTTOM; - ds_p->bsilheight = (sidedef->midtexture > 0 && sidedef->midtexture < numtextures) ? INT32_MAX: INT32_MIN; + ds_p->bsilheight = (sidedef->midtexture > 0 && sidedef->midtexture < numtextures) ? INT32_MAX : INT32_MIN; } ds_p++; } diff --git a/src/r_segs.h b/src/r_segs.h index 09c68b27e95eb34deb1302762d9d8a50e72e44dc..cad0146748bb4ab77325285a6290fc195d4399bc 100644 --- a/src/r_segs.h +++ b/src/r_segs.h @@ -22,5 +22,6 @@ transnum_t R_GetLinedefTransTable(fixed_t alpha); void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2); void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pffloor); void R_StoreWallRange(INT32 start, INT32 stop); +void R_ClearSegTables(void); #endif diff --git a/src/r_skins.c b/src/r_skins.c index 9443ad49b03d492e6856f4125881def0b1f463e4..72598f38185acf3d5801365e315e54a920e38511 100644 --- a/src/r_skins.c +++ b/src/r_skins.c @@ -113,6 +113,7 @@ static void Sk_SetDefaultValue(skin_t *skin) strcpy(skin->realname, "Someone"); strcpy(skin->hudname, "???"); + strcpy(skin->supername, "Someone super"); skin->starttranscolor = 96; skin->prefcolor = SKINCOLOR_GREEN; @@ -682,7 +683,7 @@ void R_AddSkins(UINT16 wadnum, boolean mainfile) char *value; size_t size; skin_t *skin; - boolean hudname, realname; + boolean hudname, realname, supername; // // search for all skin markers in pwad @@ -712,7 +713,7 @@ void R_AddSkins(UINT16 wadnum, boolean mainfile) skin = &skins[numskins]; Sk_SetDefaultValue(skin); skin->wadnum = wadnum; - hudname = realname = false; + hudname = realname = supername = false; // parse stoken = strtok (buf2, "\r\n= "); while (stoken) @@ -755,7 +756,7 @@ void R_AddSkins(UINT16 wadnum, boolean mainfile) Z_Free(value2); } - // copy to hudname and fullname as a default. + // copy to hudname, realname, and supername as a default. if (!realname) { STRBUFCPY(skin->realname, skin->name); @@ -771,6 +772,19 @@ void R_AddSkins(UINT16 wadnum, boolean mainfile) strupr(skin->hudname); SYMBOLCONVERT(skin->hudname) } + if (!supername) + { + char superstring[SKINNAMESIZE+7]; + strcpy(superstring, "Super "); + strlcat(superstring, skin->name, sizeof(superstring)); + STRBUFCPY(skin->supername, superstring); + } + } + else if (!stricmp(stoken, "supername")) + { // Super name (eg. "Super Knuckles") + supername = true; + STRBUFCPY(skin->supername, value); + SYMBOLCONVERT(skin->supername) } else if (!stricmp(stoken, "realname")) { // Display name (eg. "Knuckles") @@ -779,6 +793,13 @@ void R_AddSkins(UINT16 wadnum, boolean mainfile) SYMBOLCONVERT(skin->realname) if (!hudname) HUDNAMEWRITE(skin->realname); + if (!supername) //copy over default to capitalise the name + { + char superstring[SKINNAMESIZE+7]; + strcpy(superstring, "Super "); + strlcat(superstring, skin->realname, sizeof(superstring)); + STRBUFCPY(skin->supername, superstring); + } } else if (!stricmp(stoken, "hudname")) { // Life icon name (eg. "K.T.E") @@ -831,7 +852,7 @@ void R_PatchSkins(UINT16 wadnum, boolean mainfile) char *value; size_t size; skin_t *skin; - boolean noskincomplain, realname, hudname; + boolean noskincomplain, realname, hudname, supername; // // search for all skin patch markers in pwad @@ -855,7 +876,7 @@ void R_PatchSkins(UINT16 wadnum, boolean mainfile) buf2[size] = '\0'; skin = NULL; - noskincomplain = realname = hudname = false; + noskincomplain = realname = hudname = supername = false; /* Parse. Has more phases than the parser in R_AddSkins because it needs to have the patching name first (no default skin name is acceptible for patching, unlike skin creation) @@ -894,13 +915,26 @@ void R_PatchSkins(UINT16 wadnum, boolean mainfile) else // Get the properties! { // Some of these can't go in R_ProcessPatchableFields because they have side effects for future lines. - if (!stricmp(stoken, "realname")) + if (!stricmp(stoken, "supername")) + { // Super name (eg. "Super Knuckles") + supername = true; + STRBUFCPY(skin->supername, value); + SYMBOLCONVERT(skin->supername) + } + else if (!stricmp(stoken, "realname")) { // Display name (eg. "Knuckles") realname = true; STRBUFCPY(skin->realname, value); SYMBOLCONVERT(skin->realname) if (!hudname) HUDNAMEWRITE(skin->realname); + if (!supername) //copy over default to capitalise the name + { + char superstring[SKINNAMESIZE+7]; + strcpy(superstring, "Super "); + strlcat(superstring, skin->realname, sizeof(superstring)); + STRBUFCPY(skin->supername, superstring); + } } else if (!stricmp(stoken, "hudname")) { // Life icon name (eg. "K.T.E") diff --git a/src/r_skins.h b/src/r_skins.h index 082b690dda8294ed2f250a5aaba118a765073a21..fab6fc12c0f659e8b35f5d111a497850edf127b0 100644 --- a/src/r_skins.h +++ b/src/r_skins.h @@ -35,8 +35,9 @@ typedef struct UINT16 wadnum; skinflags_t flags; - char realname[SKINNAMESIZE+1]; // Display name for level completion. + char realname[SKINNAMESIZE+1]; // Display name for level completion char hudname[SKINNAMESIZE+1]; // HUD name to display (officially exactly 5 characters long) + char supername[SKINNAMESIZE+7]; // Super name to display when collecting all emeralds UINT8 ability; // ability definition UINT8 ability2; // secondary ability definition diff --git a/src/r_splats.c b/src/r_splats.c index d182d628ba8fc09ab3d8e898a339f29b3b2d92cb..0b482d7988cc0e3a32f719a0f84a272fdf63d2f3 100644 --- a/src/r_splats.c +++ b/src/r_splats.c @@ -31,20 +31,8 @@ static void prepare_rastertab(void); static void R_RasterizeFloorSplat(floorsplat_t *pSplat, vector2_t *verts, vissprite_t *vis); -#ifdef USEASM -void ASMCALL rasterize_segment_tex_asm(INT32 x1, INT32 y1, INT32 x2, INT32 y2, INT32 tv1, INT32 tv2, INT32 tc, INT32 dir); -#endif - static void rasterize_segment_tex(INT32 x1, INT32 y1, INT32 x2, INT32 y2, INT32 tv1, INT32 tv2, INT32 tc, INT32 dir) { -#ifdef USEASM - if (R_ASM) - { - rasterize_segment_tex_asm(x1, y1, x2, y2, tv1, tv2, tc, dir); - return; - } - else -#endif { fixed_t xs, xe, count; fixed_t dx0, dx1; @@ -326,9 +314,7 @@ static void R_RasterizeFloorSplat(floorsplat_t *pSplat, vector2_t *verts, visspr fixed_t planeheight = 0; fixed_t step; - int spanfunctype = SPANDRAWFUNC_SPRITE; - - prepare_rastertab(); + int spanfunctype; #define RASTERPARAMS(vnum1, vnum2, tv1, tv2, tc, dir) \ x1 = verts[vnum1].x; \ @@ -379,21 +365,15 @@ static void R_RasterizeFloorSplat(floorsplat_t *pSplat, vector2_t *verts, visspr if (ry1 > maxy) \ maxy = ry1; - // do segment a -> top of texture - RASTERPARAMS(3,2,0,pSplat->width-1,0,0); - // do segment b -> right side of texture - RASTERPARAMS(2,1,0,pSplat->width-1,pSplat->height-1,0); - // do segment c -> bottom of texture - RASTERPARAMS(1,0,pSplat->width-1,0,pSplat->height-1,0); - // do segment d -> left side of texture - RASTERPARAMS(0,3,pSplat->width-1,0,0,1); - ds_source = (UINT8 *)pSplat->pic; ds_flatwidth = pSplat->width; ds_flatheight = pSplat->height; - ds_powersoftwo = false; - if (R_CheckPowersOfTwo()) + ds_powersoftwo = ds_solidcolor = false; + + if (R_CheckSolidColorFlat()) + ds_solidcolor = true; + else if (R_CheckPowersOfTwo()) { R_SetFlatVars(ds_flatwidth * ds_flatheight); ds_powersoftwo = true; @@ -404,9 +384,8 @@ static void R_RasterizeFloorSplat(floorsplat_t *pSplat, vector2_t *verts, visspr R_SetTiltedSpan(0); R_SetScaledSlopePlane(pSplat->slope, vis->viewpoint.x, vis->viewpoint.y, vis->viewpoint.z, pSplat->xscale, pSplat->yscale, -pSplat->verts[0].x, pSplat->verts[0].y, vis->viewpoint.angle, pSplat->angle); R_CalculateSlopeVectors(); - spanfunctype = SPANDRAWFUNC_TILTEDSPRITE; } - else + else if (!ds_solidcolor) { planeheight = abs(pSplat->z - vis->viewpoint.z); @@ -441,23 +420,70 @@ static void R_RasterizeFloorSplat(floorsplat_t *pSplat, vector2_t *verts, visspr ds_colormap = &vis->extra_colormap->colormap[ds_colormap - colormaps]; } - if (vis->transmap) + ds_transmap = vis->transmap; + + // Determine which R_DrawWhatever to use + + // Solid color + if (ds_solidcolor) { - ds_transmap = vis->transmap; + UINT16 px = *(UINT16 *)ds_source; + + // Uh, it's not visible. + if (!(px & 0xFF00)) + return; + + // Pixel color is contained in the lower 8 bits (upper 8 are the opacity), so advance the pointer + ds_source++; + if (pSplat->slope) + { + if (ds_transmap) + spanfunctype = SPANDRAWFUNC_TILTEDTRANSSOLID; + else + spanfunctype = SPANDRAWFUNC_TILTEDSOLID; + } + else + { + if (ds_transmap) + spanfunctype = SPANDRAWFUNC_TRANSSOLID; + else + spanfunctype = SPANDRAWFUNC_SOLID; + } + } + // Transparent + else if (ds_transmap) + { if (pSplat->slope) spanfunctype = SPANDRAWFUNC_TILTEDTRANSSPRITE; else spanfunctype = SPANDRAWFUNC_TRANSSPRITE; } + // Opaque else - ds_transmap = NULL; + { + if (pSplat->slope) + spanfunctype = SPANDRAWFUNC_TILTEDSPRITE; + else + spanfunctype = SPANDRAWFUNC_SPRITE; + } - if (ds_powersoftwo) + if (ds_powersoftwo || ds_solidcolor) spanfunc = spanfuncs[spanfunctype]; else spanfunc = spanfuncs_npo2[spanfunctype]; + prepare_rastertab(); + + // do segment a -> top of texture + RASTERPARAMS(3,2,0,pSplat->width-1,0,0); + // do segment b -> right side of texture + RASTERPARAMS(2,1,0,pSplat->width-1,pSplat->height-1,0); + // do segment c -> bottom of texture + RASTERPARAMS(1,0,pSplat->width-1,0,pSplat->height-1,0); + // do segment d -> left side of texture + RASTERPARAMS(0,3,pSplat->width-1,0,0,1); + if (maxy >= vid.height) maxy = vid.height-1; @@ -512,7 +538,7 @@ static void R_RasterizeFloorSplat(floorsplat_t *pSplat, vector2_t *verts, visspr if (x2 < x1) continue; - if (!pSplat->slope) + if (!ds_solidcolor && !pSplat->slope) { fixed_t xstep, ystep; fixed_t distance, span; @@ -561,7 +587,7 @@ static void R_RasterizeFloorSplat(floorsplat_t *pSplat, vector2_t *verts, visspr rastertab[y].maxx = INT32_MIN; } - if (pSplat->angle && !pSplat->slope) + if (!ds_solidcolor && pSplat->angle && !pSplat->slope) memset(cachedheight, 0, sizeof(cachedheight)); } diff --git a/src/r_things.c b/src/r_things.c index eee284d46f8e2ddb0383b97be71584a801c27386..be9c5cdffe26be0a5482489d9540a50a2a599998 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -80,6 +80,33 @@ static spriteframe_t sprtemp[64]; static size_t maxframe; static const char *spritename; +// +// Clipping against drawsegs optimization, from prboom-plus +// +// TODO: This should be done with proper subsector pass through +// sprites which would ideally remove the need to do it at all. +// Unfortunately, SRB2's drawing loop has lots of annoying +// changes from Doom for portals, which make it hard to implement. + +typedef struct drawseg_xrange_item_s +{ + INT16 x1, x2; + drawseg_t *user; +} drawseg_xrange_item_t; + +typedef struct drawsegs_xrange_s +{ + drawseg_xrange_item_t *items; + INT32 count; +} drawsegs_xrange_t; + +#define DS_RANGES_COUNT 3 +static drawsegs_xrange_t drawsegs_xranges[DS_RANGES_COUNT]; + +static drawseg_xrange_item_t *drawsegs_xrange; +static size_t drawsegs_xrange_size = 0; +static INT32 drawsegs_xrange_count = 0; + // ========================================================================== // // Sprite loading routines: support sprites in pwad, dehacked sprite renaming, @@ -497,7 +524,8 @@ void R_AddSpriteDefs(UINT16 wadnum) // // GAME FUNCTIONS // -UINT32 visspritecount; +UINT32 visspritecount, numvisiblesprites; + static UINT32 clippedvissprites; static vissprite_t *visspritechunks[MAXVISSPRITES >> VISSPRITECHUNKBITS] = {NULL}; @@ -571,7 +599,7 @@ void R_InitSprites(void) // void R_ClearSprites(void) { - visspritecount = clippedvissprites = 0; + visspritecount = numvisiblesprites = clippedvissprites = 0; } // @@ -817,6 +845,15 @@ static void R_DrawVisSprite(vissprite_t *vis) if ((UINT64)overflow_test&0xFFFFFFFF80000000ULL) return; // ditto } + // TODO This check should not be necessary. But Papersprites near to the camera will sometimes create invalid values + // for the vissprite's startfrac. This happens because they are not depth culled like other sprites. + // Someone who is more familiar with papersprites pls check and try to fix <3 + if (vis->startfrac < 0 || vis->startfrac > (patch->width << FRACBITS)) + { + // never draw vissprites with startfrac out of patch range + return; + } + colfunc = colfuncs[BASEDRAWFUNC]; // hack: this isn't resetting properly somewhere. dc_colormap = vis->colormap; dc_translation = R_GetSpriteTranslation(vis); @@ -860,7 +897,7 @@ static void R_DrawVisSprite(vissprite_t *vis) frac = vis->startfrac; windowtop = windowbottom = sprbotscreen = INT32_MAX; - if (!(vis->cut & SC_PRECIP) && vis->mobj->skin && ((skin_t *)vis->mobj->skin)->flags & SF_HIRES) + if (vis->cut & SC_SHADOW && vis->mobj->skin && ((skin_t *)vis->mobj->skin)->flags & SF_HIRES) this_scale = FixedMul(this_scale, ((skin_t *)vis->mobj->skin)->highresscale); if (this_scale <= 0) this_scale = 1; @@ -870,10 +907,10 @@ static void R_DrawVisSprite(vissprite_t *vis) { vis->scale = FixedMul(vis->scale, this_scale); vis->scalestep = FixedMul(vis->scalestep, this_scale); - vis->xiscale = FixedDiv(vis->xiscale,this_scale); + vis->xiscale = FixedDiv(vis->xiscale, this_scale); vis->cut |= SC_ISSCALED; } - dc_texturemid = FixedDiv(dc_texturemid,this_scale); + dc_texturemid = FixedDiv(dc_texturemid, this_scale); } spryscale = vis->scale; @@ -1157,7 +1194,7 @@ fixed_t R_GetShadowZ(mobj_t *thing, pslope_t **shadowslope) R_InterpolateMobjState(thing, FRACUNIT, &interp); } - halfHeight = interp.z + (thing->height >> 1); + halfHeight = interp.z + (interp.height >> 1); floorz = P_GetFloorZ(thing, interp.subsector->sector, interp.x, interp.y, NULL); ceilingz = P_GetCeilingZ(thing, interp.subsector->sector, interp.x, interp.y, NULL); @@ -1221,8 +1258,8 @@ fixed_t R_GetShadowZ(mobj_t *thing, pslope_t **shadowslope) } } - if (isflipped ? (ceilingz < groundz - (!groundslope ? 0 : FixedMul(abs(groundslope->zdelta), thing->radius*3/2))) - : (floorz > groundz + (!groundslope ? 0 : FixedMul(abs(groundslope->zdelta), thing->radius*3/2)))) + if (isflipped ? (ceilingz < groundz - (!groundslope ? 0 : FixedMul(abs(groundslope->zdelta), interp.radius*3/2))) + : (floorz > groundz + (!groundslope ? 0 : FixedMul(abs(groundslope->zdelta), interp.radius*3/2)))) { groundz = isflipped ? ceilingz : floorz; groundslope = NULL; @@ -1265,9 +1302,9 @@ static void R_SkewShadowSprite( //CONS_Printf("Shadow is sloped by %d %d\n", xslope, zslope); if (viewz < groundz) - *shadowyscale += FixedMul(FixedMul(thing->radius*2 / spriteheight, scalemul), zslope); + *shadowyscale += FixedMul(FixedMul(interp.radius*2 / spriteheight, scalemul), zslope); else - *shadowyscale -= FixedMul(FixedMul(thing->radius*2 / spriteheight, scalemul), zslope); + *shadowyscale -= FixedMul(FixedMul(interp.radius*2 / spriteheight, scalemul), zslope); *shadowyscale = abs((*shadowyscale)); *shadowskew = xslope; @@ -1318,20 +1355,18 @@ static void R_ProjectDropShadow(mobj_t *thing, vissprite_t *vis, fixed_t scale, return; } - floordiff = abs((isflipped ? thing->height : 0) + interp.z - groundz); + floordiff = abs((isflipped ? interp.height : 0) + interp.z - groundz); trans = floordiff / (100*FRACUNIT) + 3; if (trans >= 9) return; scalemul = FixedMul(FRACUNIT - floordiff/640, scale); - if ((thing->scale != thing->old_scale) && (thing->scale >= FRACUNIT/1024)) // Interpolate shadows when scaling mobjs - scalemul = FixedMul(scalemul, FixedDiv(interp.scale, thing->scale)); patch = W_CachePatchName("DSHADOW", PU_SPRITE); xscale = FixedDiv(projection, tz); yscale = FixedDiv(projectiony, tz); - shadowxscale = FixedMul(thing->radius*2, scalemul); - shadowyscale = FixedMul(FixedMul(thing->radius*2, scalemul), FixedDiv(abs(groundz - viewz), tz)); + shadowxscale = FixedMul(interp.radius*2, scalemul); + shadowyscale = FixedMul(FixedMul(interp.radius*2, scalemul), FixedDiv(abs(groundz - viewz), tz)); shadowyscale = min(shadowyscale, shadowxscale) / patch->height; shadowxscale /= patch->width; shadowskew = 0; @@ -1457,8 +1492,8 @@ static void R_ProjectBoundingBox(mobj_t *thing, vissprite_t *vis) // 0--2 // start in the (0) corner - gx = interp.x - thing->radius - viewx; - gy = interp.y - thing->radius - viewy; + gx = interp.x - interp.radius - viewx; + gy = interp.y - interp.radius - viewy; tz = FixedMul(gx, viewcos) + FixedMul(gy, viewsin); @@ -1480,14 +1515,14 @@ static void R_ProjectBoundingBox(mobj_t *thing, vissprite_t *vis) box = R_NewVisSprite(); box->mobj = thing; box->mobjflags = thing->flags; - box->thingheight = thing->height; + box->thingheight = interp.height; box->cut = SC_BBOX; box->gx = tx; box->gy = tz; - box->scale = 2 * FixedMul(thing->radius, viewsin); - box->xscale = 2 * FixedMul(thing->radius, viewcos); + box->scale = 2 * FixedMul(interp.radius, viewsin); + box->xscale = 2 * FixedMul(interp.radius, viewcos); box->pz = interp.z; box->pzt = box->pz + box->thingheight; @@ -1536,6 +1571,7 @@ static void R_ProjectSprite(mobj_t *thing) fixed_t tr_x, tr_y; fixed_t tx, tz; fixed_t xscale, yscale; //added : 02-02-98 : aaargll..if I were a math-guy!!! + fixed_t radius, height; // For drop shadows fixed_t sortscale, sortsplat = 0; fixed_t linkscale = 0; fixed_t sort_x = 0, sort_y = 0, sort_z; @@ -1611,6 +1647,8 @@ static void R_ProjectSprite(mobj_t *thing) } this_scale = interp.scale; + radius = interp.radius; // For drop shadows + height = interp.height; // Ditto // transform the origin point tr_x = interp.x - viewx; @@ -1731,9 +1769,6 @@ static void R_ProjectSprite(mobj_t *thing) I_Assert(lump < max_spritelumps); - if (thing->skin && ((skin_t *)thing->skin)->flags & SF_HIRES) - this_scale = FixedMul(this_scale, ((skin_t *)thing->skin)->highresscale); - spr_width = spritecachedinfo[lump].width; spr_height = spritecachedinfo[lump].height; spr_offset = spritecachedinfo[lump].offset; @@ -1783,6 +1818,14 @@ static void R_ProjectSprite(mobj_t *thing) // calculate edges of the shape spritexscale = interp.spritexscale; spriteyscale = interp.spriteyscale; + + if (thing->skin && ((skin_t *)thing->skin)->flags & SF_HIRES) + { + fixed_t highresscale = ((skin_t *)thing->skin)->highresscale; + spritexscale = FixedMul(spritexscale, highresscale); + spriteyscale = FixedMul(spriteyscale, highresscale); + } + if (spritexscale < 1 || spriteyscale < 1) return; @@ -1950,6 +1993,8 @@ static void R_ProjectSprite(mobj_t *thing) { R_InterpolateMobjState(thing, FRACUNIT, &tracer_interp); } + radius = tracer_interp.radius; // For drop shadows + height = tracer_interp.height; // Ditto tr_x = (tracer_interp.x + sort_x) - viewx; tr_y = (tracer_interp.y + sort_y) - viewy; @@ -2041,7 +2086,7 @@ static void R_ProjectSprite(mobj_t *thing) if (abs(groundz-viewz)/tz > 4) return; // Prevent stretchy shadows and possible crashes - floordiff = abs((isflipped ? caster->height : 0) + casterinterp.z - groundz); + floordiff = abs((isflipped ? casterinterp.height : 0) + casterinterp.z - groundz); trans += ((floordiff / (100*FRACUNIT)) + 3); shadowscale = FixedMul(FRACUNIT - floordiff/640, casterinterp.scale); } @@ -2056,8 +2101,8 @@ static void R_ProjectSprite(mobj_t *thing) if (shadowdraw) { - spritexscale = FixedMul(thing->radius * 2, FixedMul(shadowscale, spritexscale)); - spriteyscale = FixedMul(thing->radius * 2, FixedMul(shadowscale, spriteyscale)); + spritexscale = FixedMul(radius * 2, FixedMul(shadowscale, spritexscale)); + spriteyscale = FixedMul(radius * 2, FixedMul(shadowscale, spriteyscale)); spriteyscale = FixedMul(spriteyscale, FixedDiv(abs(groundz - viewz), tz)); spriteyscale = min(spriteyscale, spritexscale) / patch->height; spritexscale /= patch->width; @@ -2072,7 +2117,7 @@ static void R_ProjectSprite(mobj_t *thing) { R_SkewShadowSprite(thing, thing->standingslope, groundz, patch->height, shadowscale, &spriteyscale, &sheartan); - gzt = (isflipped ? (interp.z + thing->height) : interp.z) + patch->height * spriteyscale / 2; + gzt = (isflipped ? (interp.z + height) : interp.z) + patch->height * spriteyscale / 2; gz = gzt - patch->height * spriteyscale; cut |= SC_SHEAR; @@ -2087,7 +2132,7 @@ static void R_ProjectSprite(mobj_t *thing) // When vertical flipped, draw sprites from the top down, at least as far as offsets are concerned. // sprite height - sprite topoffset is the proper inverse of the vertical offset, of course. // remember gz and gzt should be seperated by sprite height, not thing height - thing height can be shorter than the sprite itself sometimes! - gz = interp.z + oldthing->height - FixedMul(spr_topoffset, FixedMul(spriteyscale, this_scale)); + gz = interp.z + interp.height - FixedMul(spr_topoffset, FixedMul(spriteyscale, this_scale)); gzt = gz + FixedMul(spr_height, FixedMul(spriteyscale, this_scale)); } else @@ -2166,7 +2211,7 @@ static void R_ProjectSprite(mobj_t *thing) vis->gy = interp.y; vis->gz = gz; vis->gzt = gzt; - vis->thingheight = thing->height; + vis->thingheight = height; vis->pz = interp.z; vis->pzt = vis->pz + vis->thingheight; vis->texturemid = FixedDiv(gzt - viewz, spriteyscale); @@ -2606,6 +2651,14 @@ static void R_SortVisSprites(vissprite_t* vsprsortedhead, UINT32 start, UINT32 e // bundle linkdraw for (ds = unsorted.prev; ds != &unsorted; ds = ds->prev) { + // Remove this sprite if it was determined to not be visible + if (ds->cut & SC_NOTVISIBLE) + { + ds->next->prev = ds->prev; + ds->prev->next = ds->next; + continue; + } + if (!(ds->cut & SC_LINKDRAW)) continue; @@ -2632,21 +2685,27 @@ static void R_SortVisSprites(vissprite_t* vsprsortedhead, UINT32 start, UINT32 e continue; // don't connect if the tracer's top is cut off, but lower than the link's top - if ((dsfirst->cut & SC_TOP) - && dsfirst->szt > ds->szt) + if ((dsfirst->cut & SC_TOP) && dsfirst->szt > ds->szt) continue; // don't connect if the tracer's bottom is cut off, but higher than the link's bottom - if ((dsfirst->cut & SC_BOTTOM) - && dsfirst->sz < ds->sz) + if ((dsfirst->cut & SC_BOTTOM) && dsfirst->sz < ds->sz) continue; + // If the object isn't visible, then the bounding box isn't either + if (ds->cut & SC_BBOX && dsfirst->cut & SC_NOTVISIBLE) + ds->cut |= SC_NOTVISIBLE; + break; } // remove from chain ds->next->prev = ds->prev; ds->prev->next = ds->next; + + if (ds->cut & SC_NOTVISIBLE) + continue; + linkedvissprites++; if (dsfirst != &unsorted) @@ -2698,12 +2757,15 @@ static void R_SortVisSprites(vissprite_t* vsprsortedhead, UINT32 start, UINT32 e best = ds; } } - best->next->prev = best->prev; - best->prev->next = best->next; - best->next = vsprsortedhead; - best->prev = vsprsortedhead->prev; - vsprsortedhead->prev->next = best; - vsprsortedhead->prev = best; + if (best) + { + best->next->prev = best->prev; + best->prev->next = best->next; + best->next = vsprsortedhead; + best->prev = vsprsortedhead->prev; + vsprsortedhead->prev->next = best; + vsprsortedhead->prev = best; + } } } @@ -3134,9 +3196,47 @@ static void R_HeightSecClip(vissprite_t *spr, INT32 x1, INT32 x2) } } +static boolean R_CheckSpriteVisible(vissprite_t *spr, INT32 x1, INT32 x2) +{ + INT16 sz = spr->sz; + INT16 szt = spr->szt; + + fixed_t texturemid, yscale, scalestep = spr->scalestep; + INT32 height; + + if (scalestep) + { + height = spr->patch->height; + yscale = spr->scale; + scalestep = FixedMul(scalestep, spr->spriteyscale); + + if (spr->thingscale != FRACUNIT) + texturemid = FixedDiv(spr->texturemid, max(spr->thingscale, 1)); + else + texturemid = spr->texturemid; + } + + for (INT32 x = x1; x <= x2; x++) + { + if (scalestep) + { + fixed_t top = centeryfrac - FixedMul(texturemid, yscale); + fixed_t bottom = top + (height * yscale); + szt = (INT16)(top >> FRACBITS); + sz = (INT16)(bottom >> FRACBITS); + yscale += scalestep; + } + + if (spr->cliptop[x] < spr->clipbot[x] && sz > spr->cliptop[x] && szt < spr->clipbot[x]) + return true; + } + + return false; +} + // R_ClipVisSprite // Clips vissprites without drawing, so that portals can work. -Red -void R_ClipVisSprite(vissprite_t *spr, INT32 x1, INT32 x2, drawseg_t* dsstart, portal_t* portal) +static void R_ClipVisSprite(vissprite_t *spr, INT32 x1, INT32 x2, portal_t* portal) { drawseg_t *ds; INT32 x; @@ -3156,21 +3256,23 @@ void R_ClipVisSprite(vissprite_t *spr, INT32 x1, INT32 x2, drawseg_t* dsstart, p // Pointer check was originally nonportable // and buggy, by going past LEFT end of array: - // for (ds = ds_p-1; ds >= drawsegs; ds--) old buggy code - for (ds = ds_p; ds-- > dsstart;) + // e6y: optimization + if (drawsegs_xrange_size) { - // determine if the drawseg obscures the sprite - if (ds->x1 > x2 || - ds->x2 < x1 || - (!ds->silhouette - && !ds->maskedtexturecol)) - { - // does not cover sprite - continue; - } + const drawseg_xrange_item_t *last = &drawsegs_xrange[drawsegs_xrange_count - 1]; + drawseg_xrange_item_t *curr = &drawsegs_xrange[-1]; - if (ds->portalpass != 66) + while (++curr <= last) { + // determine if the drawseg obscures the sprite + if (curr->x1 > x2 || curr->x2 < x1) + { + // does not cover sprite + continue; + } + + ds = curr->user; + if (ds->portalpass > 0 && ds->portalpass <= portalrender) continue; // is a portal @@ -3195,43 +3297,43 @@ void R_ClipVisSprite(vissprite_t *spr, INT32 x1, INT32 x2, drawseg_t* dsstart, p // seg is behind sprite continue; } - } - r1 = ds->x1 < x1 ? x1 : ds->x1; - r2 = ds->x2 > x2 ? x2 : ds->x2; + r1 = ds->x1 < x1 ? x1 : ds->x1; + r2 = ds->x2 > x2 ? x2 : ds->x2; - // clip this piece of the sprite - silhouette = ds->silhouette; + // clip this piece of the sprite + silhouette = ds->silhouette; - if (spr->gz >= ds->bsilheight) - silhouette &= ~SIL_BOTTOM; + if (spr->gz >= ds->bsilheight) + silhouette &= ~SIL_BOTTOM; - if (spr->gzt <= ds->tsilheight) - silhouette &= ~SIL_TOP; + if (spr->gzt <= ds->tsilheight) + silhouette &= ~SIL_TOP; - if (silhouette == SIL_BOTTOM) - { - // bottom sil - for (x = r1; x <= r2; x++) - if (spr->clipbot[x] == -2) - spr->clipbot[x] = ds->sprbottomclip[x]; - } - else if (silhouette == SIL_TOP) - { - // top sil - for (x = r1; x <= r2; x++) - if (spr->cliptop[x] == -2) - spr->cliptop[x] = ds->sprtopclip[x]; - } - else if (silhouette == (SIL_TOP|SIL_BOTTOM)) - { - // both - for (x = r1; x <= r2; x++) + if (silhouette == SIL_BOTTOM) { - if (spr->clipbot[x] == -2) - spr->clipbot[x] = ds->sprbottomclip[x]; - if (spr->cliptop[x] == -2) - spr->cliptop[x] = ds->sprtopclip[x]; + // bottom sil + for (x = r1; x <= r2; x++) + if (spr->clipbot[x] == -2) + spr->clipbot[x] = ds->sprbottomclip[x]; + } + else if (silhouette == SIL_TOP) + { + // top sil + for (x = r1; x <= r2; x++) + if (spr->cliptop[x] == -2) + spr->cliptop[x] = ds->sprtopclip[x]; + } + else if (silhouette == (SIL_TOP|SIL_BOTTOM)) + { + // both + for (x = r1; x <= r2; x++) + { + if (spr->clipbot[x] == -2) + spr->clipbot[x] = ds->sprbottomclip[x]; + if (spr->cliptop[x] == -2) + spr->cliptop[x] = ds->sprtopclip[x]; + } } } } @@ -3275,8 +3377,7 @@ void R_ClipVisSprite(vissprite_t *spr, INT32 x1, INT32 x2, drawseg_t* dsstart, p spr->clipbot[x] = (INT16)viewheight; if (spr->cliptop[x] == -2) - //Fab : 26-04-98: was -1, now clips against console bottom - spr->cliptop[x] = (INT16)con_clipviewtop; + spr->cliptop[x] = -1; } if (portal) @@ -3301,20 +3402,119 @@ void R_ClipVisSprite(vissprite_t *spr, INT32 x1, INT32 x2, drawseg_t* dsstart, p spr->cliptop[x] = -1; } } + + // Check if it'll be visible + // Not done for floorsprites. + if (cv_spriteclip.value && (spr->cut & SC_SPLAT) == 0) + { + if (!R_CheckSpriteVisible(spr, x1, x2)) + spr->cut |= SC_NOTVISIBLE; + } } void R_ClipSprites(drawseg_t* dsstart, portal_t* portal) { + const size_t maxdrawsegs = ds_p - drawsegs; + const INT32 cx = viewwidth / 2; + drawseg_t* ds; + INT32 i; + + // e6y + // Reducing of cache misses in the following R_DrawSprite() + // Makes sense for scenes with huge amount of drawsegs. + // ~12% of speed improvement on epic.wad map05 + for (i = 0; i < DS_RANGES_COUNT; i++) + { + drawsegs_xranges[i].count = 0; + } + + if (visspritecount - clippedvissprites <= 0) + { + return; + } + + if (drawsegs_xrange_size < maxdrawsegs) + { + drawsegs_xrange_size = 2 * maxdrawsegs; + + for (i = 0; i < DS_RANGES_COUNT; i++) + { + drawsegs_xranges[i].items = Z_Realloc( + drawsegs_xranges[i].items, + drawsegs_xrange_size * sizeof(drawsegs_xranges[i].items[0]), + PU_STATIC, NULL + ); + } + } + + for (ds = ds_p; ds-- > dsstart;) + { + if (ds->silhouette || ds->maskedtexturecol) + { + drawsegs_xranges[0].items[drawsegs_xranges[0].count].x1 = ds->x1; + drawsegs_xranges[0].items[drawsegs_xranges[0].count].x2 = ds->x2; + drawsegs_xranges[0].items[drawsegs_xranges[0].count].user = ds; + + // e6y: ~13% of speed improvement on sunder.wad map10 + if (ds->x1 < cx) + { + drawsegs_xranges[1].items[drawsegs_xranges[1].count] = + drawsegs_xranges[0].items[drawsegs_xranges[0].count]; + drawsegs_xranges[1].count++; + } + + if (ds->x2 >= cx) + { + drawsegs_xranges[2].items[drawsegs_xranges[2].count] = + drawsegs_xranges[0].items[drawsegs_xranges[0].count]; + drawsegs_xranges[2].count++; + } + + drawsegs_xranges[0].count++; + } + } + for (; clippedvissprites < visspritecount; clippedvissprites++) { vissprite_t *spr = R_GetVisSprite(clippedvissprites); - if (!(spr->cut & SC_BBOX)) // Do not clip bounding boxes + if (cv_spriteclip.value + && (spr->szt > vid.height || spr->sz < 0) + && !((spr->cut & SC_SPLAT) || spr->scalestep)) { - INT32 x1 = (spr->cut & SC_SPLAT) ? 0 : spr->x1; - INT32 x2 = (spr->cut & SC_SPLAT) ? viewwidth : spr->x2; - R_ClipVisSprite(spr, x1, x2, dsstart, portal); + spr->cut |= SC_NOTVISIBLE; + continue; } + + if (spr->cut & SC_BBOX) + { + numvisiblesprites++; + continue; + } + + INT32 x1 = (spr->cut & SC_SPLAT) ? 0 : spr->x1; + INT32 x2 = (spr->cut & SC_SPLAT) ? viewwidth : spr->x2; + + if (x2 < cx) + { + drawsegs_xrange = drawsegs_xranges[1].items; + drawsegs_xrange_count = drawsegs_xranges[1].count; + } + else if (x1 >= cx) + { + drawsegs_xrange = drawsegs_xranges[2].items; + drawsegs_xrange_count = drawsegs_xranges[2].count; + } + else + { + drawsegs_xrange = drawsegs_xranges[0].items; + drawsegs_xrange_count = drawsegs_xranges[0].count; + } + + R_ClipVisSprite(spr, x1, x2, portal); + + if ((spr->cut & SC_NOTVISIBLE) == 0) + numvisiblesprites++; } } diff --git a/src/r_things.h b/src/r_things.h index bb8a1e97b024e5b2cb749d71b46ef2eff785460b..318234886bbbfa2b603f1883d50bbfea4c67d370 100644 --- a/src/r_things.h +++ b/src/r_things.h @@ -123,21 +123,22 @@ typedef enum SC_NONE = 0, SC_TOP = 1, SC_BOTTOM = 1<<1, + SC_NOTVISIBLE = 1<<2, // other flags - SC_PRECIP = 1<<2, - SC_LINKDRAW = 1<<3, - SC_FULLBRIGHT = 1<<4, - SC_SEMIBRIGHT = 1<<5, - SC_FULLDARK = 1<<6, - SC_VFLIP = 1<<7, - SC_ISSCALED = 1<<8, - SC_ISROTATED = 1<<9, - SC_SHADOW = 1<<10, - SC_SHEAR = 1<<11, - SC_SPLAT = 1<<12, - SC_BBOX = 1<<13, + SC_PRECIP = 1<<3, + SC_LINKDRAW = 1<<4, + SC_FULLBRIGHT = 1<<5, + SC_SEMIBRIGHT = 1<<6, + SC_FULLDARK = 1<<7, + SC_VFLIP = 1<<8, + SC_ISSCALED = 1<<9, + SC_ISROTATED = 1<<10, + SC_SHADOW = 1<<11, + SC_SHEAR = 1<<12, + SC_SPLAT = 1<<13, + SC_BBOX = 1<<14, // masks - SC_CUTMASK = SC_TOP|SC_BOTTOM, + SC_CUTMASK = SC_TOP|SC_BOTTOM|SC_NOTVISIBLE, SC_FLAGMASK = ~SC_CUTMASK } spritecut_e; @@ -219,10 +220,9 @@ typedef struct vissprite_s INT32 dispoffset; // copy of mobj->dispoffset, affects ordering but not drawing } vissprite_t; -extern UINT32 visspritecount; +extern UINT32 visspritecount, numvisiblesprites; void R_ClipSprites(drawseg_t* dsstart, portal_t* portal); -void R_ClipVisSprite(vissprite_t *spr, INT32 x1, INT32 x2, drawseg_t* dsstart, portal_t* portal); boolean R_SpriteIsFlashing(vissprite_t *vis); diff --git a/src/screen.c b/src/screen.c index fe5b399958e7082bd872478a53a4ef2b3da37df1..417e793bde540c62a9edf2b6a0b8073250ee7f73 100644 --- a/src/screen.c +++ b/src/screen.c @@ -44,10 +44,6 @@ // SRB2Kart #include "r_fps.h" // R_GetFramerateCap -#if defined (USEASM) && !defined (NORUSEASM)//&& (!defined (_MSC_VER) || (_MSC_VER <= 1200)) -#define RUSEASM //MSC.NET can't patch itself -#endif - // -------------------------------------------- // assembly or c drawer routines for 8bpp/16bpp // -------------------------------------------- @@ -102,7 +98,6 @@ UINT8 *scr_borderpatch; // flat used to fill the reduced view borders set at ST_ // Short and Tall sky drawer, for the current color mode void (*walldrawerfunc)(void); -boolean R_ASM = true; boolean R_486 = false; boolean R_586 = false; boolean R_MMX = false; @@ -169,26 +164,6 @@ void SCR_SetDrawFuncs(void) spanfuncs_npo2[SPANDRAWFUNC_WATER] = R_DrawWaterSpan_NPO2_8; spanfuncs_npo2[SPANDRAWFUNC_TILTEDWATER] = R_DrawTiltedWaterSpan_NPO2_8; -#ifdef RUSEASM - if (R_ASM) - { - if (R_MMX) - { - colfuncs[BASEDRAWFUNC] = R_DrawColumn_8_MMX; - //colfuncs[COLDRAWFUNC_SHADE] = R_DrawShadeColumn_8_ASM; - //colfuncs[COLDRAWFUNC_FUZZY] = R_DrawTranslucentColumn_8_ASM; - colfuncs[COLDRAWFUNC_TWOSMULTIPATCH] = R_Draw2sMultiPatchColumn_8_MMX; - spanfuncs[BASEDRAWFUNC] = R_DrawSpan_8_MMX; - } - else - { - colfuncs[BASEDRAWFUNC] = R_DrawColumn_8_ASM; - //colfuncs[COLDRAWFUNC_SHADE] = R_DrawShadeColumn_8_ASM; - //colfuncs[COLDRAWFUNC_FUZZY] = R_DrawTranslucentColumn_8_ASM; - colfuncs[COLDRAWFUNC_TWOSMULTIPATCH] = R_Draw2sMultiPatchColumn_8_ASM; - } - } -#endif } /* else if (vid.bpp > 1) { @@ -271,8 +246,6 @@ void SCR_Startup(void) CONS_Printf("CPU Info: 486: %i, 586: %i, MMX: %i, 3DNow: %i, MMXExt: %i, SSE2: %i\n", R_486, R_586, R_MMX, R_3DNow, R_MMXExt, R_SSE2); } - if (M_CheckParm("-noASM")) - R_ASM = false; if (M_CheckParm("-486")) R_486 = true; if (M_CheckParm("-586")) diff --git a/src/sdl/CMakeLists.txt b/src/sdl/CMakeLists.txt index be540b778b733976a9ceb08c636bcd30d36d29d2..4c4cdafb640e7806ee1efb79380ee10eaf26e119 100644 --- a/src/sdl/CMakeLists.txt +++ b/src/sdl/CMakeLists.txt @@ -1,17 +1,17 @@ # Declare SDL2 interface sources -target_sources(SRB2SDL2 PRIVATE mixer_sound.c) - -target_sourcefile(c) - -target_sources(SRB2SDL2 PRIVATE ogl_sdl.c) - -target_sources(SRB2SDL2 PRIVATE i_threads.c) - -if(${SRB2_USEASM}) - set_source_files_properties(${SRB2_ASM_SOURCES} PROPERTIES LANGUAGE C) - set_source_files_properties(${SRB2_ASM_SOURCES} PROPERTIES COMPILE_FLAGS "-x assembler-with-cpp") -endif() +target_sources(SRB2SDL2 PRIVATE + mixer_sound.c + ogl_sdl.c + i_threads.c + i_net.c + i_system.c + i_main.c + i_video.c + dosstr.c + endtxt.c + hwsym_sdl.c +) if("${CMAKE_SYSTEM_NAME}" MATCHES Windows) target_sources(SRB2SDL2 PRIVATE @@ -68,18 +68,6 @@ if("${CMAKE_SYSTEM_NAME}" MATCHES Linux) target_link_libraries(SRB2SDL2 PRIVATE m rt) endif() -if(${SRB2_USEASM}) - if(${SRB2_CONFIG_YASM}) - set(ASM_ASSEMBLER_TEMP ${CMAKE_ASM_YASM_COMPILER}) - set(ASM_ASSEMBLER_OBJFORMAT ${CMAKE_ASM_YASM_OBJECT_FORMAT}) - set_source_files_properties(${SRB2_NASM_SOURCES} LANGUAGE ASM_YASM) - else() - set(ASM_ASSEMBLER_TEMP ${CMAKE_ASM_NASM_COMPILER}) - set(ASM_ASSEMBLER_OBJFORMAT ${CMAKE_ASM_NASM_OBJECT_FORMAT}) - set_source_files_properties(${SRB2_NASM_SOURCES} LANGUAGE ASM_NASM) - endif() -endif() - if("${CMAKE_SYSTEM_NAME}" MATCHES Windows) target_link_libraries(SRB2SDL2 PRIVATE ws2_32 diff --git a/src/sdl/MakeCYG.cfg b/src/sdl/MakeCYG.cfg index 5907579c1bc9d16abb0e338cb709566fd75b6c61..b78316b00142dfcb96188f6fb45baa047a628ed0 100644 --- a/src/sdl/MakeCYG.cfg +++ b/src/sdl/MakeCYG.cfg @@ -7,7 +7,6 @@ NOHW=1 NOHS=1 - NOASM=1 OPTS+=-DLINUX diff --git a/src/sdl/i_main.c b/src/sdl/i_main.c index 1dee379c0d8d95db186f1e9e3bb301554ed0549f..3eeacd83569188bd3bfdb5c8f2b9e720b5dce9f4 100644 --- a/src/sdl/i_main.c +++ b/src/sdl/i_main.c @@ -70,39 +70,6 @@ char logfilename[1024]; typedef BOOL (WINAPI *p_IsDebuggerPresent)(VOID); #endif -#if defined (_WIN32) -static inline VOID MakeCodeWritable(VOID) -{ -#ifdef USEASM // Disable write-protection of code segment - DWORD OldRights; - const DWORD NewRights = PAGE_EXECUTE_READWRITE; - PBYTE pBaseOfImage = (PBYTE)GetModuleHandle(NULL); - PIMAGE_DOS_HEADER dosH =(PIMAGE_DOS_HEADER)pBaseOfImage; - PIMAGE_NT_HEADERS ntH = (PIMAGE_NT_HEADERS)(pBaseOfImage + dosH->e_lfanew); - PIMAGE_OPTIONAL_HEADER oH = (PIMAGE_OPTIONAL_HEADER) - ((PBYTE)ntH + sizeof (IMAGE_NT_SIGNATURE) + sizeof (IMAGE_FILE_HEADER)); - LPVOID pA = pBaseOfImage+oH->BaseOfCode; - SIZE_T pS = oH->SizeOfCode; -#if 1 // try to find the text section - PIMAGE_SECTION_HEADER ntS = IMAGE_FIRST_SECTION (ntH); - WORD s; - for (s = 0; s < ntH->FileHeader.NumberOfSections; s++) - { - if (memcmp (ntS[s].Name, ".text\0\0", 8) == 0) - { - pA = pBaseOfImage+ntS[s].VirtualAddress; - pS = ntS[s].Misc.VirtualSize; - break; - } - } -#endif - - if (!VirtualProtect(pA,pS,NewRights,&OldRights)) - I_Error("Could not make code writable\n"); -#endif -} -#endif - #ifdef LOGMESSAGES static void InitLogging(void) { @@ -243,7 +210,6 @@ int main(int argc, char **argv) #ifndef __MINGW32__ prevExceptionFilter = SetUnhandledExceptionFilter(RecordExceptionInfo); #endif - MakeCodeWritable(); #endif // startup SRB2 diff --git a/src/sdl/i_system.c b/src/sdl/i_system.c index 847ab2646f2502151a45de214640f1da5945f578..902194f4f332592f69f8b0f872bdf04f0159ba90 100644 --- a/src/sdl/i_system.c +++ b/src/sdl/i_system.c @@ -23,12 +23,6 @@ /// \file /// \brief SRB2 system stuff for SDL -#ifdef CMAKECONFIG -#include "config.h" -#else -#include "../config.h.in" -#endif - #include <signal.h> #ifdef _WIN32 @@ -41,6 +35,12 @@ typedef DWORD (WINAPI *p_timeGetTime) (void); typedef UINT (WINAPI *p_timeEndPeriod) (UINT); typedef HANDLE (WINAPI *p_OpenFileMappingA) (DWORD, BOOL, LPCSTR); typedef LPVOID (WINAPI *p_MapViewOfFile) (HANDLE, DWORD, DWORD, DWORD, SIZE_T); + +// This is for RtlGenRandom. +#define SystemFunction036 NTAPI SystemFunction036 +#include <ntsecapi.h> +#undef SystemFunction036 + #endif #include <stdio.h> #include <stdlib.h> @@ -90,7 +90,7 @@ typedef LPVOID (WINAPI *p_MapViewOfFile) (HANDLE, DWORD, DWORD, DWORD, SIZE_T); #include <kvm.h> #endif #include <nlist.h> -#include <sys/vmmeter.h> +#include <sys/sysctl.h> #endif #endif @@ -325,8 +325,10 @@ static void write_backtrace(INT32 signal) static void I_ReportSignal(int num, int coredumped) { //static char msg[] = "oh no! back to reality!\r\n"; - const char *sigmsg, *sigttl; + const char *sigmsg, *signame; char ttl[128]; + char sigttl[512] = "Process killed by signal: "; + const char *reportmsg = "\n\nTo help us figure out the cause, you can visit our official Discord server\nwhere you will find more instructions on how to submit a crash report.\n\nSorry for the inconvenience!"; switch (num) { @@ -335,16 +337,16 @@ static void I_ReportSignal(int num, int coredumped) // sigmsg = "SRB2 was interrupted prematurely by the user."; // break; case SIGILL: - sigmsg = "SRB2 has attempted to execute an illegal instruction and needs to close. %s"; - sigttl = "SIGILL"; // illegal instruction - invalid function image + sigmsg = "SRB2 has attempted to execute an illegal instruction and needs to close."; + signame = "SIGILL"; // illegal instruction - invalid function image break; case SIGFPE: - sigmsg = "SRB2 has encountered a mathematical exception and needs to close. %s"; - sigttl = "SIGFPE"; // mathematical exception + sigmsg = "SRB2 has encountered a mathematical exception and needs to close."; + signame = "SIGFPE"; // mathematical exception break; case SIGSEGV: - sigmsg = "SRB2 has attempted to access a memory location that it shouldn't and needs to close. %s"; - sigttl = "SIGSEGV"; // segment violation + sigmsg = "SRB2 has attempted to access a memory location that it shouldn't and needs to close."; + signame = "SIGSEGV"; // segment violation break; // case SIGTERM: // sigmsg = "SRB2 was terminated by a kill signal."; @@ -355,34 +357,31 @@ static void I_ReportSignal(int num, int coredumped) // sigttl = "SIGBREAK" // Ctrl-Break sequence // break; case SIGABRT: - sigmsg = "SRB2 was terminated by an abort signal. %s"; - sigttl = "SIGABRT"; // abnormal termination triggered by abort call + sigmsg = "SRB2 was terminated by an abort signal."; + signame = "SIGABRT"; // abnormal termination triggered by abort call break; default: - sigmsg = "SRB2 was terminated by an unknown signal. %s"; + sigmsg = "SRB2 was terminated by an unknown signal."; sprintf(ttl, "number %d", num); if (coredumped) - sigttl = 0; + signame = 0; else - sigttl = ttl; + signame = ttl; } if (coredumped) { - if (sigttl) - sprintf(ttl, "%s (core dumped)", sigttl); + if (signame) + sprintf(ttl, "%s (core dumped)", signame); else strcat(ttl, " (core dumped)"); - sigttl = ttl; + signame = ttl; } - sprintf(ttl, "Process killed by signal: %s", sigttl); - - sigttl = ttl; - - I_OutputMsg("\n%s\n\n", sigttl); + strcat(sigttl, signame); + I_OutputMsg("%s\n", sigttl); if (M_CheckParm("-dedicated")) return; @@ -396,8 +395,7 @@ static void I_ReportSignal(int num, int coredumped) SDL_MESSAGEBOX_ERROR, /* .flags */ NULL, /* .window */ sigttl, /* .title */ - va(sigmsg, - "\n\nTo help us figure out the cause, you can visit our official Discord server\nwhere you will find more instructions on how to submit a crash report.\n\nSorry for the inconvenience!"), /* .message */ + va("%s %s", sigmsg, reportmsg), /* .message */ SDL_arraysize(buttons), /* .numbuttons */ buttons, /* .buttons */ NULL /* .colorScheme */ @@ -2356,7 +2354,10 @@ INT32 I_StartupSystem(void) #endif I_StartupConsole(); #ifdef NEWSIGNALHANDLER - I_Fork(); + // This is useful when debugging. It lets GDB attach to + // the correct process easily. + if (!M_CheckParm("-nofork")) + I_Fork(); #endif I_RegisterSignals(); I_OutputMsg("Compiled for SDL version: %d.%d.%d\n", @@ -2642,9 +2643,10 @@ void I_ShutdownSystem(void) { INT32 c; -#ifndef NEWSIGNALHANDLER - I_ShutdownConsole(); +#ifdef NEWSIGNALHANDLER + if (M_CheckParm("-nofork")) #endif + I_ShutdownConsole(); for (c = MAX_QUIT_FUNCS-1; c >= 0; c--) if (quit_funcs[c]) @@ -2776,6 +2778,38 @@ INT32 I_PutEnv(char *variable) #endif } +size_t I_GetRandomBytes(char *destination, size_t count) +{ +#if defined (__unix__) || defined (UNIXCOMMON) || defined(__APPLE__) + 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; +#elif defined (_WIN32) + if (RtlGenRandom(destination, count)) + return count; + + I_OutputMsg("I_GetRandomBytes(): couldn't get any random bytes"); + return 0; +#else + #warning SDL I_GetRandomBytes is not implemented on this platform. + return 0; +#endif +} + INT32 I_ClipboardCopy(const char *data, size_t size) { char storage[256]; @@ -2999,40 +3033,17 @@ static long get_entry(const char* name, const char* buf) size_t I_GetFreeMem(size_t *total) { #ifdef FREEBSD - struct vmmeter sum; - kvm_t *kd; - struct nlist namelist[] = - { -#define X_SUM 0 - {"_cnt"}, - {NULL} - }; - if ((kd = kvm_open(NULL, NULL, NULL, O_RDONLY, "kvm_open")) == NULL) - { - if (total) - *total = 0L; - return 0; - } - if (kvm_nlist(kd, namelist) != 0) - { - kvm_close (kd); - if (total) - *total = 0L; - return 0; - } - if (kvm_read(kd, namelist[X_SUM].n_value, &sum, - sizeof (sum)) != sizeof (sum)) - { - kvm_close(kd); - if (total) - *total = 0L; - return 0; - } - kvm_close(kd); + u_int v_free_count, v_page_size, v_page_count; + size_t size = sizeof(v_free_count); + sysctlbyname("vm.stat.vm.v_free_count", &v_free_count, &size, NULL, 0); + size_t size = sizeof(v_page_size); + sysctlbyname("vm.stat.vm.v_page_size", &v_page_size, &size, NULL, 0); + size_t size = sizeof(v_page_count); + sysctlbyname("vm.stat.vm.v_page_count", &v_page_count, &size, NULL, 0); if (total) - *total = sum.v_page_count * sum.v_page_size; - return sum.v_free_count * sum.v_page_size; + *total = v_page_count * v_page_size; + return v_free_count * v_page_size; #elif defined (SOLARIS) /* Just guess */ if (total) diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c index b2215f634a189d1bce50083ef8394ad63b434e85..590d7d142a7a536678bfb96d3891c78264a19fba 100644 --- a/src/sdl/i_video.c +++ b/src/sdl/i_video.c @@ -1593,7 +1593,6 @@ boolean VID_CheckRenderer(void) else if (vid.glstate == VID_GL_LIBRARY_ERROR) rendererchanged = false; } - else #endif if (!contextcreated) diff --git a/src/st_stuff.c b/src/st_stuff.c index c6e6befc62ee046e2a0ab7b333d33db1d5a7a494..b9f0c6bb93e1ab4d1b9e35a958670571883086e4 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -174,7 +174,7 @@ static huddrawlist_h luahuddrawlist_titlecard; skincolornum_t linkColor[3][NUMLINKCOLORS] = { {SKINCOLOR_SHAMROCK, SKINCOLOR_AQUA, SKINCOLOR_SKY, SKINCOLOR_BLUE, SKINCOLOR_PURPLE, SKINCOLOR_MAGENTA, SKINCOLOR_ROSY, SKINCOLOR_RED, SKINCOLOR_ORANGE, SKINCOLOR_GOLD, SKINCOLOR_YELLOW, SKINCOLOR_PERIDOT}, -{SKINCOLOR_EMERALD, SKINCOLOR_AQUAMARINE, SKINCOLOR_WAVE, SKINCOLOR_SAPPHIRE, SKINCOLOR_GALAXY, SKINCOLOR_CRYSTAL, +{SKINCOLOR_EMERALD, SKINCOLOR_OCEAN, SKINCOLOR_AQUAMARINE, SKINCOLOR_SAPPHIRE, SKINCOLOR_GALAXY, SKINCOLOR_SIBERITE, SKINCOLOR_TAFFY, SKINCOLOR_RUBY, SKINCOLOR_GARNET, SKINCOLOR_TOPAZ, SKINCOLOR_LEMON, SKINCOLOR_LIME}, {SKINCOLOR_ISLAND, SKINCOLOR_TURQUOISE, SKINCOLOR_DREAM, SKINCOLOR_DAYBREAK, SKINCOLOR_VAPOR, SKINCOLOR_FUCHSIA, SKINCOLOR_VIOLET, SKINCOLOR_EVENTIDE, SKINCOLOR_KETCHUP, SKINCOLOR_FOUNDATION, SKINCOLOR_HEADLIGHT, SKINCOLOR_CHARTREUSE}}; @@ -2512,6 +2512,8 @@ num: static INT32 ST_drawEmeraldHuntIcon(mobj_t *hunt, patch_t **patches, INT32 offset) { INT32 interval, i; + if (stplyr->mo == NULL) + return 0; // player just joined after spectating, can happen on custom gamemodes. UINT32 dist = ((UINT32)P_AproxDistance(P_AproxDistance(stplyr->mo->x - hunt->x, stplyr->mo->y - hunt->y), stplyr->mo->z - hunt->z))>>FRACBITS; if (dist < 128) diff --git a/src/strcasestr.c b/src/strcasestr.c index 2796f11d52658f2376b547a3d41d6b2d2974f15e..37899a8425b3d2082957c41cbdae07056798fe74 100644 --- a/src/strcasestr.c +++ b/src/strcasestr.c @@ -61,7 +61,7 @@ swapp (char ***ppap, char ***ppbp, char **cpap, char **cpbp) } char * -strcasestr (const char *s, const char *q) +nongnu_strcasestr (const char *s, const char *q) { size_t qn; diff --git a/src/string.c b/src/string.c index dd3080a979ca3ccffa811f27ee408bef7540bb26..2f16fa4c68a35fa287156f546fc2973e9d4ad426 100644 --- a/src/string.c +++ b/src/string.c @@ -15,7 +15,7 @@ #include <string.h> #include "doomdef.h" -#if !defined (__APPLE__) +#ifndef SRB2_HAVE_STRLCPY // Like the OpenBSD version, but it doesn't check for src not being a valid // C string. diff --git a/src/tests/CMakeLists.txt b/src/tests/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..28c4ce492f2d8b4e7590e3ac10f9ce6a95d98a0f --- /dev/null +++ b/src/tests/CMakeLists.txt @@ -0,0 +1,3 @@ +target_sources(srb2tests PRIVATE + boolcompat.cpp +) diff --git a/src/tests/boolcompat.cpp b/src/tests/boolcompat.cpp new file mode 100644 index 0000000000000000000000000000000000000000..fee40cd36f2bce34217a875024d6b41fe71adbd1 --- /dev/null +++ b/src/tests/boolcompat.cpp @@ -0,0 +1,8 @@ +#include <catch2/catch_test_macros.hpp> + +#include "../doomtype.h" + +TEST_CASE("C++ bool is convertible to doomtype.h boolean") { + REQUIRE(static_cast<boolean>(true) == 1); + REQUIRE(static_cast<boolean>(false) == 0); +} diff --git a/src/tmap.nas b/src/tmap.nas deleted file mode 100644 index 85091cbd5d8dd9b1ab33cdd4938325eefeb1922b..0000000000000000000000000000000000000000 --- a/src/tmap.nas +++ /dev/null @@ -1,957 +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: -;; tmap.nas -;; DESCRIPTION: -;; Assembler optimised rendering code for software mode. -;; Draw wall columns. - - -[BITS 32] - -%define FRACBITS 16 -%define TRANSPARENTPIXEL 255 - -%ifdef LINUX -%macro cextern 1 -[extern %1] -%endmacro - -%macro cglobal 1 -[global %1] -%endmacro - -%else -%macro cextern 1 -%define %1 _%1 -[extern %1] -%endmacro - -%macro cglobal 1 -%define %1 _%1 -[global %1] -%endmacro - -%endif - - -; The viddef_s structure. We only need the width field. -struc viddef_s - resb 12 -.width: resb 4 - resb 44 -endstruc - -;; externs -;; columns -cextern dc_x -cextern dc_yl -cextern dc_yh -cextern ylookup -cextern columnofs -cextern dc_source -cextern dc_texturemid -cextern dc_texheight -cextern dc_iscale -cextern dc_hires -cextern centery -cextern centeryfrac -cextern dc_colormap -cextern dc_transmap -cextern colormaps -cextern vid -cextern topleft - -; DELME -cextern R_DrawColumn_8 - -; polygon edge rasterizer -cextern prastertab - -[SECTION .data] - -;;.align 4 -loopcount dd 0 -pixelcount dd 0 -tystep dd 0 - -[SECTION .text] - -;;---------------------------------------------------------------------- -;; -;; R_DrawColumn : 8bpp column drawer -;; -;; New optimised version 10-01-1998 by D.Fabrice and P.Boris -;; Revised by G. Dick July 2010 to support the intervening twelve years' -;; worth of changes to the renderer. Since I only vaguely know what I'm -;; doing, this is probably rather suboptimal. Help appreciated! -;; -;;---------------------------------------------------------------------- -;; fracstep, vid.width in memory -;; eax = accumulator -;; ebx = colormap -;; ecx = count -;; edx = heightmask -;; esi = source -;; edi = dest -;; ebp = frac -;;---------------------------------------------------------------------- - -cglobal R_DrawColumn_8_ASM -; align 16 -R_DrawColumn_8_ASM: - push ebp ;; preserve caller's stack frame pointer - push esi ;; preserve register variables - push edi - push ebx -;; -;; dest = ylookup[dc_yl] + columnofs[dc_x]; -;; - mov ebp,[dc_yl] - mov edi,[ylookup+ebp*4] - mov ebx,[dc_x] - add edi,[columnofs+ebx*4] ;; edi = dest -;; -;; pixelcount = yh - yl + 1 -;; - mov ecx,[dc_yh] - add ecx,1 - sub ecx,ebp ;; pixel count - jle near .done ;; nothing to scale -;; -;; fracstep = dc_iscale; // But we just use [dc_iscale] -;; frac = (dc_texturemid + FixedMul((dc_yl << FRACBITS) - centeryfrac, fracstep)); -;; - mov eax,ebp ;; dc_yl - shl eax,FRACBITS - sub eax,[centeryfrac] - imul dword [dc_iscale] - shrd eax,edx,FRACBITS - add eax,[dc_texturemid] - mov ebp,eax ;; ebp = frac - - mov ebx,[dc_colormap] - - mov esi,[dc_source] -;; -;; if (dc_hires) frac = 0; -;; - test byte [dc_hires],0x01 - jz .texheightcheck - xor ebp,ebp - -;; -;; Check for power of two -;; -.texheightcheck: - mov edx,[dc_texheight] - sub edx,1 ;; edx = heightmask - test edx,[dc_texheight] - jnz .notpowertwo - - test ecx,0x01 ;; Test for odd no. pixels - jnz .odd - -;; -;; Texture height is a power of two, so we get modular arithmetic by -;; masking -;; -.powertwo: - mov eax,ebp ;; eax = frac - sar eax,FRACBITS ;; Integer part - and eax,edx ;; eax &= heightmask - movzx eax,byte [esi + eax] ;; eax = texel - add ebp,[dc_iscale] ;; frac += fracstep - movzx eax,byte [ebx+eax] ;; Map through colormap - mov [edi],al ;; Write pixel - ;; dest += vid.width - add edi,[vid + viddef_s.width] - -.odd: - mov eax,ebp ;; eax = frac - sar eax,FRACBITS ;; Integer part - and eax,edx ;; eax &= heightmask - movzx eax,byte [esi + eax] ;; eax = texel - add ebp,[dc_iscale] ;; frac += fracstep - movzx eax,byte [ebx+eax] ;; Map through colormap - mov [edi],al ;; Write pixel - ;; dest += vid.width - add edi,[vid + viddef_s.width] - - - sub ecx,2 ;; count -= 2 - jg .powertwo - - jmp .done - -.notpowertwo: - add edx,1 - shl edx,FRACBITS - test ebp,ebp - jns .notpowtwoloop - -.makefracpos: - add ebp,edx ;; frac is negative; make it positive - js .makefracpos - -.notpowtwoloop: - cmp ebp,edx ;; Reduce mod height - jl .writenonpowtwo - sub ebp,edx - jmp .notpowtwoloop - -.writenonpowtwo: - mov eax,ebp ;; eax = frac - sar eax,FRACBITS ;; Integer part. - mov bl,[esi + eax] ;; ebx = colormap + texel - add ebp,[dc_iscale] ;; frac += fracstep - movzx eax,byte [ebx] ;; Map through colormap - mov [edi],al ;; Write pixel - ;; dest += vid.width - add edi,[vid + viddef_s.width] - - sub ecx,1 - jnz .notpowtwoloop - -;; - -.done: - pop ebx ;; restore register variables - pop edi - pop esi - pop ebp ;; restore caller's stack frame pointer - ret - - -;;---------------------------------------------------------------------- -;; -;; R_Draw2sMultiPatchColumn : Like R_DrawColumn, but omits transparent -;; pixels. -;; -;; New optimised version 10-01-1998 by D.Fabrice and P.Boris -;; Revised by G. Dick July 2010 to support the intervening twelve years' -;; worth of changes to the renderer. Since I only vaguely know what I'm -;; doing, this is probably rather suboptimal. Help appreciated! -;; -;;---------------------------------------------------------------------- -;; fracstep, vid.width in memory -;; eax = accumulator -;; ebx = colormap -;; ecx = count -;; edx = heightmask -;; esi = source -;; edi = dest -;; ebp = frac -;;---------------------------------------------------------------------- - -cglobal R_Draw2sMultiPatchColumn_8_ASM -; align 16 -R_Draw2sMultiPatchColumn_8_ASM: - push ebp ;; preserve caller's stack frame pointer - push esi ;; preserve register variables - push edi - push ebx -;; -;; dest = ylookup[dc_yl] + columnofs[dc_x]; -;; - mov ebp,[dc_yl] - mov edi,[ylookup+ebp*4] - mov ebx,[dc_x] - add edi,[columnofs+ebx*4] ;; edi = dest -;; -;; pixelcount = yh - yl + 1 -;; - mov ecx,[dc_yh] - add ecx,1 - sub ecx,ebp ;; pixel count - jle near .done ;; nothing to scale -;; -;; fracstep = dc_iscale; // But we just use [dc_iscale] -;; frac = (dc_texturemid + FixedMul((dc_yl << FRACBITS) - centeryfrac, fracstep)); -;; - mov eax,ebp ;; dc_yl - shl eax,FRACBITS - sub eax,[centeryfrac] - imul dword [dc_iscale] - shrd eax,edx,FRACBITS - add eax,[dc_texturemid] - mov ebp,eax ;; ebp = frac - - mov ebx,[dc_colormap] - - mov esi,[dc_source] -;; -;; if (dc_hires) frac = 0; -;; - test byte [dc_hires],0x01 - jz .texheightcheck - xor ebp,ebp - -;; -;; Check for power of two -;; -.texheightcheck: - mov edx,[dc_texheight] - sub edx,1 ;; edx = heightmask - test edx,[dc_texheight] - jnz .notpowertwo - - test ecx,0x01 ;; Test for odd no. pixels - jnz .odd - -;; -;; Texture height is a power of two, so we get modular arithmetic by -;; masking -;; -.powertwo: - mov eax,ebp ;; eax = frac - sar eax,FRACBITS ;; Integer part - and eax,edx ;; eax &= heightmask - movzx eax,byte [esi + eax] ;; eax = texel - add ebp,[dc_iscale] ;; frac += fracstep - cmp al,TRANSPARENTPIXEL ;; Is pixel transparent? - je .nextpowtwoeven ;; If so, advance. - movzx eax,byte [ebx+eax] ;; Map through colormap - mov [edi],al ;; Write pixel -.nextpowtwoeven: - ;; dest += vid.width - add edi,[vid + viddef_s.width] - -.odd: - mov eax,ebp ;; eax = frac - sar eax,FRACBITS ;; Integer part - and eax,edx ;; eax &= heightmask - movzx eax,byte [esi + eax] ;; eax = texel - add ebp,[dc_iscale] ;; frac += fracstep - cmp al,TRANSPARENTPIXEL ;; Is pixel transparent? - je .nextpowtwoodd ;; If so, advance. - movzx eax,byte [ebx+eax] ;; Map through colormap - mov [edi],al ;; Write pixel -.nextpowtwoodd: - ;; dest += vid.width - add edi,[vid + viddef_s.width] - - - sub ecx,2 ;; count -= 2 - jg .powertwo - - jmp .done - -.notpowertwo: - add edx,1 - shl edx,FRACBITS - test ebp,ebp - jns .notpowtwoloop - -.makefracpos: - add ebp,edx ;; frac is negative; make it positive - js .makefracpos - -.notpowtwoloop: - cmp ebp,edx ;; Reduce mod height - jl .writenonpowtwo - sub ebp,edx - jmp .notpowtwoloop - -.writenonpowtwo: - mov eax,ebp ;; eax = frac - sar eax,FRACBITS ;; Integer part. - mov bl,[esi + eax] ;; ebx = colormap + texel - add ebp,[dc_iscale] ;; frac += fracstep - cmp bl,TRANSPARENTPIXEL ;; Is pixel transparent? - je .nextnonpowtwo ;; If so, advance. - movzx eax,byte [ebx] ;; Map through colormap - mov [edi],al ;; Write pixel -.nextnonpowtwo: - ;; dest += vid.width - add edi,[vid + viddef_s.width] - - sub ecx,1 - jnz .notpowtwoloop - -;; - -.done: - pop ebx ;; restore register variables - pop edi - pop esi - pop ebp ;; restore caller's stack frame pointer - ret - -;;---------------------------------------------------------------------- -;; R_DrawTranslucentColumnA_8 -;; -;; Vertical column texture drawer, with transparency. Replaces Doom2's -;; 'fuzz' effect, which was not so beautiful. -;; Transparency is always impressive in some way, don't know why... -;;---------------------------------------------------------------------- - -cglobal R_DrawTranslucentColumn_8_ASM -R_DrawTranslucentColumn_8_ASM: - push ebp ;; preserve caller's stack frame pointer - push esi ;; preserve register variables - push edi - push ebx -;; -;; dest = ylookup[dc_yl] + columnofs[dc_x]; -;; - mov ebp,[dc_yl] - mov ebx,ebp - mov edi,[ylookup+ebx*4] - mov ebx,[dc_x] - add edi,[columnofs+ebx*4] ;; edi = dest -;; -;; pixelcount = yh - yl + 1 -;; - mov eax,[dc_yh] - inc eax - sub eax,ebp ;; pixel count - mov [pixelcount],eax ;; save for final pixel - jle near vtdone ;; nothing to scale -;; -;; frac = dc_texturemid - (centery-dc_yl)*fracstep; -;; - mov ecx,[dc_iscale] ;; fracstep - mov eax,[centery] - sub eax,ebp - imul eax,ecx - mov edx,[dc_texturemid] - sub edx,eax - mov ebx,edx - - shr ebx,16 ;; frac int. - and ebx,0x7f - shl edx,16 ;; y frac up - - mov ebp,ecx - shl ebp,16 ;; fracstep f. up - shr ecx,16 ;; fracstep i. ->cl - and cl,0x7f - push cx - mov ecx,edx - pop cx - mov edx,[dc_colormap] - mov esi,[dc_source] -;; -;; lets rock :) ! -;; - mov eax,[pixelcount] - shr eax,0x2 - test byte [pixelcount],0x3 - mov ch,al ;; quad count - mov eax,[dc_transmap] - je vt4quadloop -;; -;; do un-even pixel -;; - test byte [pixelcount],0x1 - je trf2 - - mov ah,[esi+ebx] ;; fetch texel : colormap number - add ecx,ebp - adc bl,cl - mov al,[edi] ;; fetch dest : index into colormap - and bl,0x7f - mov dl,[eax] - mov dl,[edx] - mov [edi],dl -pf: add edi,0x12345678 -;; -;; do two non-quad-aligned pixels -;; -trf2: test byte [pixelcount],0x2 - je trf3 - - mov ah,[esi+ebx] ;; fetch texel : colormap number - add ecx,ebp - adc bl,cl - mov al,[edi] ;; fetch dest : index into colormap - and bl,0x7f - mov dl,[eax] - mov dl,[edx] - mov [edi],dl -pg: add edi,0x12345678 - - mov ah,[esi+ebx] ;; fetch texel : colormap number - add ecx,ebp - adc bl,cl - mov al,[edi] ;; fetch dest : index into colormap - and bl,0x7f - mov dl,[eax] - mov dl,[edx] - mov [edi],dl -ph: add edi,0x12345678 -;; -;; test if there was at least 4 pixels -;; -trf3: test ch,0xff ;; test quad count - je near vtdone - -;; -;; ebp : ystep frac. upper 24 bits -;; edx : y frac. upper 24 bits -;; ebx : y i. lower 7 bits, masked for index -;; ecx : ch = counter, cl = y step i. -;; eax : colormap aligned 256 -;; esi : source texture column -;; edi : dest screen -;; -vt4quadloop: - mov ah,[esi+ebx] ;; fetch texel : colormap number - mov [tystep],ebp -pi: add edi,0x12345678 - mov al,[edi] ;; fetch dest : index into colormap -pj: sub edi,0x12345678 - mov ebp,edi -pk: sub edi,0x12345678 - jmp short inloop -align 4 -vtquadloop: - add ecx,[tystep] - adc bl,cl -q1: add ebp,0x23456789 - and bl,0x7f - mov dl,[eax] - mov ah,[esi+ebx] ;; fetch texel : colormap number - mov dl,[edx] - mov [edi],dl - mov al,[ebp] ;; fetch dest : index into colormap -inloop: - add ecx,[tystep] - adc bl,cl -q2: add edi,0x23456789 - and bl,0x7f - mov dl,[eax] - mov ah,[esi+ebx] ;; fetch texel : colormap number - mov dl,[edx] - mov [ebp+0x0],dl - mov al,[edi] ;; fetch dest : index into colormap - - add ecx,[tystep] - adc bl,cl -q3: add ebp,0x23456789 - and bl,0x7f - mov dl,[eax] - mov ah,[esi+ebx] ;; fetch texel : colormap number - mov dl,[edx] - mov [edi],dl - mov al,[ebp] ;; fetch dest : index into colormap - - add ecx,[tystep] - adc bl,cl -q4: add edi,0x23456789 - and bl,0x7f - mov dl,[eax] - mov ah,[esi+ebx] ;; fetch texel : colormap number - mov dl,[edx] - mov [ebp],dl - mov al,[edi] ;; fetch dest : index into colormap - - dec ch - jne vtquadloop -vtdone: - pop ebx - pop edi - pop esi - pop ebp - ret - -;;---------------------------------------------------------------------- -;; R_DrawShadeColumn -;; -;; for smoke..etc.. test. -;;---------------------------------------------------------------------- -cglobal R_DrawShadeColumn_8_ASM -R_DrawShadeColumn_8_ASM: - push ebp ;; preserve caller's stack frame pointer - push esi ;; preserve register variables - push edi - push ebx - -;; -;; dest = ylookup[dc_yl] + columnofs[dc_x]; -;; - mov ebp,[dc_yl] - mov ebx,ebp - mov edi,[ylookup+ebx*4] - mov ebx,[dc_x] - add edi,[columnofs+ebx*4] ;; edi = dest -;; -;; pixelcount = yh - yl + 1 -;; - mov eax,[dc_yh] - inc eax - sub eax,ebp ;; pixel count - mov [pixelcount],eax ;; save for final pixel - jle near shdone ;; nothing to scale -;; -;; frac = dc_texturemid - (centery-dc_yl)*fracstep; -;; - mov ecx,[dc_iscale] ;; fracstep - mov eax,[centery] - sub eax,ebp - imul eax,ecx - mov edx,[dc_texturemid] - sub edx,eax - mov ebx,edx - shr ebx,16 ;; frac int. - and ebx,byte +0x7f - shl edx,16 ;; y frac up - - mov ebp,ecx - shl ebp,16 ;; fracstep f. up - shr ecx,16 ;; fracstep i. ->cl - and cl,0x7f - - mov esi,[dc_source] -;; -;; lets rock :) ! -;; - mov eax,[pixelcount] - mov dh,al - shr eax,2 - mov ch,al ;; quad count - mov eax,[colormaps] - test dh,3 - je sh4quadloop -;; -;; do un-even pixel -;; - test dh,0x1 - je shf2 - - mov ah,[esi+ebx] ;; fetch texel : colormap number - add edx,ebp - adc bl,cl - mov al,[edi] ;; fetch dest : index into colormap - and bl,0x7f - mov dl,[eax] - mov [edi],dl -pl: add edi,0x12345678 -;; -;; do two non-quad-aligned pixels -;; -shf2: - test dh,0x2 - je shf3 - - mov ah,[esi+ebx] ;; fetch texel : colormap number - add edx,ebp - adc bl,cl - mov al,[edi] ;; fetch dest : index into colormap - and bl,0x7f - mov dl,[eax] - mov [edi],dl -pm: add edi,0x12345678 - - mov ah,[esi+ebx] ;; fetch texel : colormap number - add edx,ebp - adc bl,cl - mov al,[edi] ;; fetch dest : index into colormap - and bl,0x7f - mov dl,[eax] - mov [edi],dl -pn: add edi,0x12345678 -;; -;; test if there was at least 4 pixels -;; -shf3: - test ch,0xff ;; test quad count - je near shdone - -;; -;; ebp : ystep frac. upper 24 bits -;; edx : y frac. upper 24 bits -;; ebx : y i. lower 7 bits, masked for index -;; ecx : ch = counter, cl = y step i. -;; eax : colormap aligned 256 -;; esi : source texture column -;; edi : dest screen -;; -sh4quadloop: - mov dh,0x7f ;; prep mask - mov ah,[esi+ebx] ;; fetch texel : colormap number - mov [tystep],ebp -po: add edi,0x12345678 - mov al,[edi] ;; fetch dest : index into colormap -pp: sub edi,0x12345678 - mov ebp,edi -pq: sub edi,0x12345678 - jmp short shinloop - -align 4 -shquadloop: - add edx,[tystep] - adc bl,cl - and bl,dh -q5: add ebp,0x12345678 - mov dl,[eax] - mov ah,[esi+ebx] ;; fetch texel : colormap number - mov [edi],dl - mov al,[ebp] ;; fetch dest : index into colormap -shinloop: - add edx,[tystep] - adc bl,cl - and bl,dh -q6: add edi,0x12345678 - mov dl,[eax] - mov ah,[esi+ebx] ;; fetch texel : colormap number - mov [ebp],dl - mov al,[edi] ;; fetch dest : index into colormap - - add edx,[tystep] - adc bl,cl - and bl,dh -q7: add ebp,0x12345678 - mov dl,[eax] - mov ah,[esi+ebx] ;; fetch texel : colormap number - mov [edi],dl - mov al,[ebp] ;; fetch dest : index into colormap - - add edx,[tystep] - adc bl,cl - and bl,dh -q8: add edi,0x12345678 - mov dl,[eax] - mov ah,[esi+ebx] ;; fetch texel : colormap number - mov [ebp],dl - mov al,[edi] ;; fetch dest : index into colormap - - dec ch - jne shquadloop - -shdone: - pop ebx ;; restore register variables - pop edi - pop esi - pop ebp ;; restore caller's stack frame pointer - ret - - -;; ======================================================================== -;; Rasterization of the segments of a LINEAR polygne textur of manire. -;; It is thus a question of interpolating coordinate them at the edges of texture in -;; the time that the X-coordinates minx/maxx for each line. -;; the argument ' dir' indicates which edges of texture are Interpol?: -;; 0: segments associs at edge TOP? and BOTTOM? (constant TY) -;; 1: segments associs at the LEFT and RIGHT edge (constant TX) -;; ======================================================================== -;; -;; void rasterize_segment_tex( LONG x1, LONG y1, LONG x2, LONG y2, LONG tv1, LONG tv2, LONG tc, LONG dir ); -;; ARG1 ARG2 ARG3 ARG4 ARG5 ARG6 ARG7 ARG8 -;; -;; Pour dir = 0, (tv1,tv2) = (tX1,tX2), tc = tY, en effet TY est constant. -;; -;; Pour dir = 1, (tv1,tv2) = (tY1,tY2), tc = tX, en effet TX est constant. -;; -;; -;; Uses: extern struct rastery *_rastertab; -;; - -MINX EQU 0 -MAXX EQU 4 -TX1 EQU 8 -TY1 EQU 12 -TX2 EQU 16 -TY2 EQU 20 -RASTERY_SIZEOF EQU 24 - -cglobal rasterize_segment_tex_asm -rasterize_segment_tex_asm: - push ebp - mov ebp,esp - - sub esp,byte +0x8 ;; allocate the local variables - - push ebx - push esi - push edi - o16 mov ax,es - push eax - -;; #define DX [ebp-4] -;; #define TD [ebp-8] - - mov eax,[ebp+0xc] ;; y1 - mov ebx,[ebp+0x14] ;; y2 - cmp ebx,eax - je near .L_finished ;; special (y1==y2) segment horizontal, exit! - - jg near .L_rasterize_right - -;;rasterize_left: ;; one rasterize a segment LEFT of the polygne - - mov ecx,eax - sub ecx,ebx - inc ecx ;; y1-y2+1 - - mov eax,RASTERY_SIZEOF - mul ebx ;; * y2 - mov esi,[prastertab] - add esi,eax ;; point into rastertab[y2] - - mov eax,[ebp+0x8] ;; ARG1 - sub eax,[ebp+0x10] ;; ARG3 - shl eax,0x10 ;; ((x1-x2)<<PRE) ... - cdq - idiv ecx ;; dx = ... / (y1-y2+1) - mov [ebp-0x4],eax ;; DX - - mov eax,[ebp+0x18] ;; ARG5 - sub eax,[ebp+0x1c] ;; ARG6 - shl eax,0x10 - cdq - idiv ecx ;; tdx =((tx1-tx2)<<PRE) / (y1-y2+1) - mov [ebp-0x8],eax ;; idem tdy =((ty1-ty2)<<PRE) / (y1-y2+1) - - mov eax,[ebp+0x10] ;; ARG3 - shl eax,0x10 ;; x = x2<<PRE - - mov ebx,[ebp+0x1c] ;; ARG6 - shl ebx,0x10 ;; tx = tx2<<PRE d0 - ;; ty = ty2<<PRE d1 - mov edx,[ebp+0x20] ;; ARG7 - shl edx,0x10 ;; ty = ty<<PRE d0 - ;; tx = tx<<PRE d1 - push ebp - mov edi,[ebp-0x4] ;; DX - cmp dword [ebp+0x24],byte +0x0 ;; ARG8 direction ? - - mov ebp,[ebp-0x8] ;; TD - je .L_rleft_h_loop -;; -;; TY varies, TX is constant -;; -.L_rleft_v_loop: - mov [esi+MINX],eax ;; rastertab[y].minx = x - add ebx,ebp - mov [esi+TX1],edx ;; .tx1 = tx - add eax,edi - mov [esi+TY1],ebx ;; .ty1 = ty - - ;;addl DX, %eax // x += dx - ;;addl TD, %ebx // ty += tdy - - add esi,RASTERY_SIZEOF ;; next raster line into rastertab[] - dec ecx - jne .L_rleft_v_loop - pop ebp - jmp .L_finished -;; -;; TX varies, TY is constant -;; -.L_rleft_h_loop: - mov [esi+MINX],eax ;; rastertab[y].minx = x - add eax,edi - mov [esi+TX1],ebx ;; .tx1 = tx - add ebx,ebp - mov [esi+TY1],edx ;; .ty1 = ty - - ;;addl DX, %eax // x += dx - ;;addl TD, %ebx // tx += tdx - - add esi,RASTERY_SIZEOF ;; next raster line into rastertab[] - dec ecx - jne .L_rleft_h_loop - pop ebp - jmp .L_finished -;; -;; one rasterize a segment LINE of the polygne -;; -.L_rasterize_right: - mov ecx,ebx - sub ecx,eax - inc ecx ;; y2-y1+1 - - mov ebx,RASTERY_SIZEOF - mul ebx ;; * y1 - mov esi,[prastertab] - add esi,eax ;; point into rastertab[y1] - - mov eax,[ebp+0x10] ;; ARG3 - sub eax,[ebp+0x8] ;; ARG1 - shl eax,0x10 ;; ((x2-x1)<<PRE) ... - cdq - idiv ecx ;; dx = ... / (y2-y1+1) - mov [ebp-0x4],eax ;; DX - - mov eax,[ebp+0x1c] ;; ARG6 - sub eax,[ebp+0x18] ;; ARG5 - shl eax,0x10 - cdq - idiv ecx ;; tdx =((tx2-tx1)<<PRE) / (y2-y1+1) - mov [ebp-0x8],eax ;; idem tdy =((ty2-ty1)<<PRE) / (y2-y1+1) - - mov eax,[ebp+0x8] ;; ARG1 - shl eax,0x10 ;; x = x1<<PRE - - mov ebx,[ebp+0x18] ;; ARG5 - shl ebx,0x10 ;; tx = tx1<<PRE d0 - ;; ty = ty1<<PRE d1 - mov edx,[ebp+0x20] ;; ARG7 - shl edx,0x10 ;; ty = ty<<PRE d0 - ;; tx = tx<<PRE d1 - push ebp - mov edi,[ebp-0x4] ;; DX - - cmp dword [ebp+0x24], 0 ;; direction ? - - mov ebp,[ebp-0x8] ;; TD - je .L_rright_h_loop -;; -;; TY varies, TX is constant -;; -.L_rright_v_loop: - - mov [esi+MAXX],eax ;; rastertab[y].maxx = x - add ebx,ebp - mov [esi+TX2],edx ;; .tx2 = tx - add eax,edi - mov [esi+TY2],ebx ;; .ty2 = ty - - ;;addl DX, %eax // x += dx - ;;addl TD, %ebx // ty += tdy - - add esi,RASTERY_SIZEOF - dec ecx - jne .L_rright_v_loop - - pop ebp - - jmp short .L_finished -;; -;; TX varies, TY is constant -;; -.L_rright_h_loop: - mov [esi+MAXX],eax ;; rastertab[y].maxx = x - add eax,edi - mov [esi+TX2],ebx ;; .tx2 = tx - add ebx,ebp - mov [esi+TY2],edx ;; .ty2 = ty - - ;;addl DX, %eax // x += dx - ;;addl TD, %ebx // tx += tdx - - add esi,RASTERY_SIZEOF - dec ecx - jne .L_rright_h_loop - - pop ebp - -.L_finished: - pop eax - o16 mov es,ax - pop edi - pop esi - pop ebx - - mov esp,ebp - pop ebp - ret diff --git a/src/tmap.s b/src/tmap.s deleted file mode 100644 index d98d82e25cedbea383b71beb122e7f250e12d765..0000000000000000000000000000000000000000 --- a/src/tmap.s +++ /dev/null @@ -1,1587 +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 tmap.s -/// \brief optimised drawing routines for span/column rendering - -// structures, must match the C structures! -#include "asm_defs.inc" - -// Rappel: seuls EAX, ECX, EDX peuvent �tre �cras�s librement. -// il faut sauver esi,edi, cd...gs - -/* Attention aux comparaisons! */ -/* */ -/* Intel_compare: */ -/* */ -/* cmp A,B // A-B , set flags */ -/* jg A_greater_than_B */ -/* */ -/* AT&T_compare: */ -/* */ -/* cmp A,B // B-A , set flags */ -/* jg B_greater_than_A */ -/* */ -/* (soustrait l'op�rande source DE l'op�rande destination, */ -/* comme sur Motorola! ) */ - -// RAPPEL: Intel -// SECTION:[BASE+INDEX*SCALE+DISP] -// devient SECTION:DISP(BASE,INDEX,SCALE) - -//---------------------------------------------------------------------- -// -// R_DrawColumn -// -// New optimised version 10-01-1998 by D.Fabrice and P.Boris -// TO DO: optimise it much farther... should take at most 3 cycles/pix -// once it's fixed, add code to patch the offsets so that it -// works in every screen width. -// -//---------------------------------------------------------------------- - - .data -#ifdef LINUX - .align 2 -#else - .align 4 -#endif -C(loopcount): .long 0 -C(pixelcount): .long 0 -C(tystep): .long 0 - -C(vidwidth): .long 0 //use this one out of the inner loops - //so you don't need to patch everywhere... - -#ifdef USEASM -#if !defined( LINUX) - .text -#endif -.globl C(ASM_PatchRowBytes) -C(ASM_PatchRowBytes): - pushl %ebp - movl %esp, %ebp // assure l'"adressabilit� du stack" - - movl ARG1, %edx // read first arg - movl %edx, C(vidwidth) - - // 1 * vidwidth - movl %edx,p1+2 - movl %edx,w1+2 //water - movl %edx,p1b+2 //sky - - movl %edx,p5+2 - movl %edx,sh5+2 //smokie test - - // 2 * vidwidth - addl ARG1,%edx - - movl %edx,p2+2 - movl %edx,w2+2 //water - movl %edx,p2b+2 //sky - - movl %edx,p6+2 - movl %edx,p7+2 - movl %edx,p8+2 - movl %edx,p9+2 - movl %edx,sh6+2 //smokie test - movl %edx,sh7+2 - movl %edx,sh8+2 - movl %edx,sh9+2 - - // 3 * vidwidth - addl ARG1,%edx - - movl %edx,p3+2 - movl %edx,w3+2 //water - movl %edx,p3b+2 //sky - - // 4 * vidwidth - addl ARG1,%edx - - movl %edx,p4+2 - movl %edx,w4+2 //water - movl %edx,p4b+2 //sky - - popl %ebp - ret - - -#ifdef LINUX - .align 2 -#else - .align 5 -#endif -.globl C(R_DrawColumn_8) -C(R_DrawColumn_8): - pushl %ebp // preserve caller's stack frame pointer - pushl %esi // preserve register variables - pushl %edi - pushl %ebx - -// -// dest = ylookup[dc_yl] + columnofs[dc_x]; -// - movl C(dc_yl),%ebp - movl %ebp,%ebx - movl C(ylookup)(,%ebx,4),%edi - movl C(dc_x),%ebx - addl C(columnofs)(,%ebx,4),%edi // edi = dest - -// -// pixelcount = yh - yl + 1 -// - movl C(dc_yh),%eax - incl %eax - subl %ebp,%eax // pixel count - movl %eax,C(pixelcount) // save for final pixel - jle vdone // nothing to scale - -// -// frac = dc_texturemid - (centery-dc_yl)*fracstep; -// - movl C(dc_iscale),%ecx // fracstep - movl C(centery),%eax - subl %ebp,%eax - imul %ecx,%eax - movl C(dc_texturemid),%edx - subl %eax,%edx - movl %edx,%ebx - shrl $16,%ebx // frac int. - andl $0x0000007f,%ebx - shll $16,%edx // y frac up - - movl %ecx,%ebp - shll $16,%ebp // fracstep f. up - shrl $16,%ecx // fracstep i. ->cl - andb $0x7f,%cl - - movl C(dc_source),%esi - -// -// lets rock :) ! -// - movl C(pixelcount),%eax - movb %al,%dh - shrl $2,%eax - movb %al,%ch // quad count - movl C(dc_colormap),%eax - testb $3,%dh - jz v4quadloop - -// -// do un-even pixel -// - testb $1,%dh - jz 2f - - movb (%esi,%ebx),%al // prep un-even loops - addl %ebp,%edx // ypos f += ystep f - adcb %cl,%bl // ypos i += ystep i - movb (%eax),%dl // colormap texel - andb $0x7f,%bl // mask 0-127 texture index - movb %dl,(%edi) // output pixel - addl C(vidwidth),%edi - -// -// do two non-quad-aligned pixels -// -2: - testb $2,%dh - jz 3f - - movb (%esi,%ebx),%al // fetch source texel - addl %ebp,%edx // ypos f += ystep f - adcb %cl,%bl // ypos i += ystep i - movb (%eax),%dl // colormap texel - andb $0x7f,%bl // mask 0-127 texture index - movb %dl,(%edi) // output pixel - - movb (%esi,%ebx),%al // fetch source texel - addl %ebp,%edx // ypos f += ystep f - adcb %cl,%bl // ypos i += ystep i - movb (%eax),%dl // colormap texel - andb $0x7f,%bl // mask 0-127 texture index - addl C(vidwidth),%edi - movb %dl,(%edi) // output pixel - - addl C(vidwidth),%edi - -// -// test if there was at least 4 pixels -// -3: - testb $0xFF,%ch // test quad count - jz vdone - -// -// ebp : ystep frac. upper 24 bits -// edx : y frac. upper 24 bits -// ebx : y i. lower 7 bits, masked for index -// ecx : ch = counter, cl = y step i. -// eax : colormap aligned 256 -// esi : source texture column -// edi : dest screen -// -v4quadloop: - movb $0x7f,%dh // prep mask -// .align 4 -vquadloop: - movb (%esi,%ebx),%al // prep loop - addl %ebp,%edx // ypos f += ystep f - adcb %cl,%bl // ypos i += ystep i - movb (%eax),%dl // colormap texel - movb %dl,(%edi) // output pixel - andb $0x7f,%bl // mask 0-127 texture index - - movb (%esi,%ebx),%al // fetch source texel - addl %ebp,%edx - adcb %cl,%bl - movb (%eax),%dl -p1: movb %dl,0x12345678(%edi) - andb $0x7f,%bl - - movb (%esi,%ebx),%al // fetch source texel - addl %ebp,%edx - adcb %cl,%bl - movb (%eax),%dl -p2: movb %dl,2*0x12345678(%edi) - andb $0x7f,%bl - - movb (%esi,%ebx),%al // fetch source texel - addl %ebp,%edx - adcb %cl,%bl - movb (%eax),%dl -p3: movb %dl,3*0x12345678(%edi) - andb $0x7f,%bl - -p4: addl $4*0x12345678,%edi - - decb %ch - jnz vquadloop - -vdone: - popl %ebx // restore register variables - popl %edi - popl %esi - popl %ebp // restore caller's stack frame pointer - ret - -#ifdef HORIZONTALDRAW -// -------------------------------------------------------------------------- -// Horizontal Column Drawer Optimisation -// -------------------------------------------------------------------------- - -#ifdef LINUX - .align 2 -#else - .align 5 -#endif -.globl C(R_DrawHColumn_8) -C(R_DrawHColumn_8): - pushl %ebp - pushl %esi - pushl %edi - pushl %ebx - -// -// dest = yhlookup[dc_x] + hcolumnofs[dc_yl]; -// - movl C(dc_x),%ebx - movl C(yhlookup)(,%ebx,4),%edi - movl C(dc_yl),%ebp - movl %ebp,%ebx - addl C(hcolumnofs)(,%ebx,4),%edi // edi = dest - -// -// pixelcount = yh - yl + 1 -// - movl C(dc_yh),%eax - incl %eax - subl %ebp,%eax // pixel count - movl %eax,C(pixelcount) // save for final pixel - jle vhdone // nothing to scale - -// -// frac = dc_texturemid - (centery-dc_yl)*fracstep; -// - movl C(dc_iscale),%ecx // fracstep - movl C(centery),%eax - subl %ebp,%eax - imul %ecx,%eax - movl C(dc_texturemid),%edx - subl %eax,%edx - movl %edx,%ebx - shrl $16,%ebx // frac int. - andl $0x0000007f,%ebx - shll $16,%edx // y frac up - - movl %ecx,%ebp - shll $16,%ebp // fracstep f. up - shrl $16,%ecx // fracstep i. ->cl - andb $0x7f,%cl - - movl C(dc_source),%esi - -// -// lets rock :) ! -// - - movl C(pixelcount),%eax - movb %al,%dh - shrl $2,%eax - movb %al,%ch // quad count - - testb %ch, %ch - jz vhnearlydone - - movl C(dc_colormap),%eax - decl %edi //----- - -vhloop: - movb (%esi,%ebx),%al // fetch source texel - addl %ebp,%edx - adcb %cl,%bl - andb $0x7f,%bl - incl %edi //----- - movb (%eax),%dh - movb %dh,(%edi) //----- - - movb (%esi,%ebx),%al // fetch source texel - addl %ebp,%edx - incl %edi //----- - adcb %cl,%bl - movb (%eax),%dl - andb $0x7f,%bl - movb %dl,(%edi) //----- - - movb (%esi,%ebx),%al // fetch source texel - addl %ebp,%edx - adcb %cl,%bl -// shll $16,%edx - andb $0x7f,%bl - incl %edi //----- - movb (%eax),%dh - movb %dh,(%edi) //----- - - movb (%esi,%ebx),%al // fetch source texel - addl %ebp,%edx - incl %edi //----- - adcb %cl,%bl - movb (%eax),%dl - andb $0x7f,%bl - movb %dl,(%edi) -// movl %edx,(%edi) -// addl $4,%edi - - decb %ch - jnz vhloop - -vhnearlydone: -// movl C(pixelcount) - -vhdone: - popl %ebx - popl %edi - popl %esi - popl %ebp - ret - - -// -------------------------------------------------------------------------- -// Rotate a buffer 90 degree in clockwise order after horiz.col. draws -// -------------------------------------------------------------------------- - -#ifdef LINUX - .align 2 -#else - .align 5 -#endif -.globl C(R_RotateBuffer) -C(R_RotateBuffer): - pushl %ebp - pushl %esi - pushl %edi - pushl %ebx - - - movl C(dc_source),%esi - movl C(dc_colormap),%edi - - - movb (%esi),%ah - addl $200,%esi - movb (%ebx),%al - addl $200,%ebx - bswap %eax - movb (%esi),%ah - addl $200,%esi - movb (%ebx),%al - addl $200,%ebx - movl %eax,(%edi) - addl $4,%edi - - - popl %ebx - popl %edi - popl %esi - popl %ebp - ret -#endif - -//---------------------------------------------------------------------- -//13-02-98: -// R_DrawSkyColumn : same as R_DrawColumn but: -// -// - wrap around 256 instead of 127. -// this is needed because we have a higher texture for mouselook, -// we need at least 200 lines for the sky. -// -// NOTE: the sky should never wrap, so it could use a faster method. -// for the moment, we'll still use a wrapping method... -// -// IT S JUST A QUICK CUT N PASTE, WAS NOT OPTIMISED AS IT SHOULD BE !!! -// -//---------------------------------------------------------------------- - -#ifdef LINUX - .align 2 -#else - .align 5 -#endif -.globl C(R_DrawSkyColumn_8) -C(R_DrawSkyColumn_8): - pushl %ebp - pushl %esi - pushl %edi - pushl %ebx - -// -// dest = ylookup[dc_yl] + columnofs[dc_x]; -// - movl C(dc_yl),%ebp - movl %ebp,%ebx - movl C(ylookup)(,%ebx,4),%edi - movl C(dc_x),%ebx - addl C(columnofs)(,%ebx,4),%edi // edi = dest - -// -// pixelcount = yh - yl + 1 -// - movl C(dc_yh),%eax - incl %eax - subl %ebp,%eax // pixel count - movl %eax,C(pixelcount) // save for final pixel - jle vskydone // nothing to scale - -// -// frac = dc_texturemid - (centery-dc_yl)*fracstep; -// - movl C(dc_iscale),%ecx // fracstep - movl C(centery),%eax - subl %ebp,%eax - imul %ecx,%eax - movl C(dc_texturemid),%edx - subl %eax,%edx - movl %edx,%ebx - shrl $16,%ebx // frac int. - andl $0x000000ff,%ebx - shll $16,%edx // y frac up - - movl %ecx,%ebp - shll $16,%ebp // fracstep f. up - shrl $16,%ecx // fracstep i. ->cl - - movl C(dc_source),%esi - -// -// lets rock :) ! -// - movl C(pixelcount),%eax - movb %al,%dh - shrl $2,%eax - movb %al,%ch // quad count - movl C(dc_colormap),%eax - testb $3,%dh - jz v4skyquadloop - -// -// do un-even pixel -// - testb $1,%dh - jz 2f - - movb (%esi,%ebx),%al // prep un-even loops - addl %ebp,%edx // ypos f += ystep f - adcb %cl,%bl // ypos i += ystep i - movb (%eax),%dl // colormap texel - movb %dl,(%edi) // output pixel - addl C(vidwidth),%edi - -// -// do two non-quad-aligned pixels -// -2: - testb $2,%dh - jz 3f - - movb (%esi,%ebx),%al // fetch source texel - addl %ebp,%edx // ypos f += ystep f - adcb %cl,%bl // ypos i += ystep i - movb (%eax),%dl // colormap texel - movb %dl,(%edi) // output pixel - - movb (%esi,%ebx),%al // fetch source texel - addl %ebp,%edx // ypos f += ystep f - adcb %cl,%bl // ypos i += ystep i - movb (%eax),%dl // colormap texel - addl C(vidwidth),%edi - movb %dl,(%edi) // output pixel - - addl C(vidwidth),%edi - -// -// test if there was at least 4 pixels -// -3: - testb $0xFF,%ch // test quad count - jz vskydone - -// -// ebp : ystep frac. upper 24 bits -// edx : y frac. upper 24 bits -// ebx : y i. lower 7 bits, masked for index -// ecx : ch = counter, cl = y step i. -// eax : colormap aligned 256 -// esi : source texture column -// edi : dest screen -// -v4skyquadloop: -// .align 4 -vskyquadloop: - movb (%esi,%ebx),%al // prep loop - addl %ebp,%edx // ypos f += ystep f - adcb %cl,%bl // ypos i += ystep i - movb (%eax),%dl // colormap texel - movb %dl,(%edi) // output pixel - - movb (%esi,%ebx),%al // fetch source texel - addl %ebp,%edx - adcb %cl,%bl - movb (%eax),%dl -p1b: movb %dl,0x12345678(%edi) - - movb (%esi,%ebx),%al // fetch source texel - addl %ebp,%edx - adcb %cl,%bl - movb (%eax),%dl -p2b: movb %dl,2*0x12345678(%edi) - - movb (%esi,%ebx),%al // fetch source texel - addl %ebp,%edx - adcb %cl,%bl - movb (%eax),%dl -p3b: movb %dl,3*0x12345678(%edi) - -p4b: addl $4*0x12345678,%edi - - decb %ch - jnz vskyquadloop - -vskydone: - popl %ebx // restore register variables - popl %edi - popl %esi - popl %ebp // restore caller's stack frame pointer - ret - - - -//---------------------------------------------------------------------- -// -// R_DrawSpan -// -// Horizontal texture mapping -// -//---------------------------------------------------------------------- - - .data - -ystep: .long 0 -xstep: .long 0 -C(texwidth): .long 64 // texture width -#if !defined( LINUX) - .text -#endif -#ifdef LINUX - .align 2 -#else - .align 4 -#endif -.globl C(R_DrawSpan_8) -C(R_DrawSpan_8): - pushl %ebp // preserve caller's stack frame pointer - pushl %esi // preserve register variables - pushl %edi - pushl %ebx - - -// -// find loop count -// - movl C(ds_x2),%eax - incl %eax - subl C(ds_x1),%eax // pixel count - movl %eax,C(pixelcount) // save for final pixel - js hdone // nothing to scale - shrl $1,%eax // double pixel count - movl %eax,C(loopcount) - -// -// build composite position -// - movl C(ds_xfrac),%ebp - shll $10,%ebp - andl $0x0ffff0000,%ebp - movl C(ds_yfrac),%eax - shrl $6,%eax - andl $0x0ffff,%eax - movl C(ds_y),%edi - orl %eax,%ebp - - movl C(ds_source),%esi - -// -// calculate screen dest -// - - movl C(ylookup)(,%edi,4),%edi - movl C(ds_x1),%eax - addl C(columnofs)(,%eax,4),%edi - -// -// build composite step -// - movl C(ds_xstep),%ebx - shll $10,%ebx - andl $0x0ffff0000,%ebx - movl C(ds_ystep),%eax - shrl $6,%eax - andl $0x0ffff,%eax - orl %eax,%ebx - - //movl %eax,OFFSET hpatch1+2 // convice tasm to modify code... - movl %ebx,hpatch1+2 - //movl %eax,OFFSET hpatch2+2 // convice tasm to modify code... - movl %ebx,hpatch2+2 - movl %esi,hpatch3+2 - movl %esi,hpatch4+2 -// %eax aligned colormap -// %ebx aligned colormap -// %ecx,%edx scratch -// %esi virtual source -// %edi moving destination pointer -// %ebp frac - movl C(ds_colormap),%eax -// shld $22,%ebp,%ecx // begin calculating third pixel (y units) -// shld $6,%ebp,%ecx // begin calculating third pixel (x units) - movl %ebp,%ecx - addl %ebx,%ebp // advance frac pointer - shrw $10,%cx - roll $6,%ecx - andl $4095,%ecx // finish calculation for third pixel -// shld $22,%ebp,%edx // begin calculating fourth pixel (y units) -// shld $6,%ebp,%edx // begin calculating fourth pixel (x units) - movl %ebp,%edx - shrw $10,%dx - roll $6,%edx - addl %ebx,%ebp // advance frac pointer - andl $4095,%edx // finish calculation for fourth pixel - movl %eax,%ebx - movb (%esi,%ecx),%al // get first pixel - movb (%esi,%edx),%bl // get second pixel - testl $0x0fffffffe,C(pixelcount) - movb (%eax),%dl // color translate first pixel - -// jnz hdoubleloop // at least two pixels to map -// jmp hchecklast - -// movw $0xf0f0,%dx //see visplanes start - - jz hchecklast - movb (%ebx),%dh // color translate second pixel - movl C(loopcount),%esi -// .align 4 -hdoubleloop: -// shld $22,%ebp,%ecx // begin calculating third pixel (y units) -// shld $6,%ebp,%ecx // begin calculating third pixel (x units) - movl %ebp,%ecx - shrw $10,%cx - roll $6,%ecx -hpatch1: - addl $0x012345678,%ebp // advance frac pointer - movw %dx,(%edi) // write first pixel - andl $4095,%ecx // finish calculation for third pixel -// shld $22,%ebp,%edx // begin calculating fourth pixel (y units) -// shld $6,%ebp,%edx // begin calculating fourth pixel (x units) - movl %ebp,%edx - shrw $10,%dx - roll $6,%edx -hpatch3: - movb 0x012345678(%ecx),%al // get third pixel -// movb %bl,1(%edi) // write second pixel - andl $4095,%edx // finish calculation for fourth pixel -hpatch2: - addl $0x012345678,%ebp // advance frac pointer -hpatch4: - movb 0x012345678(%edx),%bl // get fourth pixel - movb (%eax),%dl // color translate third pixel - addl $2,%edi // advance to third pixel destination - decl %esi // done with loop? - movb (%ebx),%dh // color translate fourth pixel - jnz hdoubleloop - -// check for final pixel -hchecklast: - testl $1,C(pixelcount) - jz hdone - movb %dl,(%edi) // write final pixel - -hdone: - popl %ebx // restore register variables - popl %edi - popl %esi - popl %ebp // restore caller's stack frame pointer - ret - - -//.endif - - -//---------------------------------------------------------------------- -// R_DrawTransColumn -// -// Vertical column texture drawer, with transparency. Replaces Doom2's -// 'fuzz' effect, which was not so beautiful. -// Transparency is always impressive in some way, don't know why... -//---------------------------------------------------------------------- - -#ifdef LINUX - .align 2 -#else - .align 5 -#endif - -.globl C(R_DrawTranslucentColumn_8) -C(R_DrawTranslucentColumn_8): - pushl %ebp // preserve caller's stack frame pointer - pushl %esi // preserve register variables - pushl %edi - pushl %ebx - -// -// dest = ylookup[dc_yl] + columnofs[dc_x]; -// - movl C(dc_yl),%ebp - movl %ebp,%ebx - movl C(ylookup)(,%ebx,4),%edi - movl C(dc_x),%ebx - addl C(columnofs)(,%ebx,4),%edi // edi = dest - -// -// pixelcount = yh - yl + 1 -// - movl C(dc_yh),%eax - incl %eax - subl %ebp,%eax // pixel count - movl %eax,C(pixelcount) // save for final pixel - jle vtdone // nothing to scale - -// -// frac = dc_texturemid - (centery-dc_yl)*fracstep; -// - movl C(dc_iscale),%ecx // fracstep - movl C(centery),%eax - subl %ebp,%eax - imul %ecx,%eax - movl C(dc_texturemid),%edx - subl %eax,%edx - movl %edx,%ebx - - shrl $16,%ebx // frac int. - andl $0x0000007f,%ebx - shll $16,%edx // y frac up - - movl %ecx,%ebp - shll $16,%ebp // fracstep f. up - shrl $16,%ecx // fracstep i. ->cl - andb $0x7f,%cl - pushw %cx - movl %edx,%ecx - popw %cx - movl C(dc_colormap),%edx - movl C(dc_source),%esi - -// -// lets rock :) ! -// - movl C(pixelcount),%eax - shrl $2,%eax - testb $0x03,C(pixelcount) - movb %al,%ch // quad count - movl C(dc_transmap),%eax - jz vt4quadloop -// -// do un-even pixel -// - testb $1,C(pixelcount) - jz 2f - - movb (%esi,%ebx),%ah // fetch texel : colormap number - addl %ebp,%ecx - adcb %cl,%bl - movb (%edi),%al // fetch dest : index into colormap - andb $0x7f,%bl - movb (%eax),%dl - movb (%edx), %dl // use colormap now ! - movb %dl,(%edi) - addl C(vidwidth),%edi -// -// do two non-quad-aligned pixels -// -2: - testb $2,C(pixelcount) - jz 3f - - movb (%esi,%ebx),%ah // fetch texel : colormap number - addl %ebp,%ecx - adcb %cl,%bl - movb (%edi),%al // fetch dest : index into colormap - andb $0x7f,%bl - movb (%eax),%dl - movb (%edx), %dl // use colormap now ! - movb %dl,(%edi) - addl C(vidwidth),%edi - - movb (%esi,%ebx),%ah // fetch texel : colormap number - addl %ebp,%ecx - adcb %cl,%bl - movb (%edi),%al // fetch dest : index into colormap - andb $0x7f,%bl - movb (%eax),%dl - movb (%edx), %dl // use colormap now ! - movb %dl,(%edi) - addl C(vidwidth),%edi - -// -// test if there was at least 4 pixels -// -3: - testb $0xFF,%ch // test quad count - jz vtdone - -// -// tystep : ystep frac. upper 24 bits -// edx : upper 24 bit : colomap -// dl : tmp pixel to write -// ebx : y i. lower 7 bits, masked for index -// ecx : y frac. upper 16 bits -// ecx : ch = counter, cl = y step i. -// eax : transmap aligned 65535 (upper 16 bit) -// ah : background pixel (from the screen buffer) -// al : foreground pixel (from the texture) -// esi : source texture column -// ebp,edi : dest screen -// -vt4quadloop: - movb (%esi,%ebx),%ah // fetch texel : colormap number -p5: movb 0x12345678(%edi),%al // fetch dest : index into colormap - - movl %ebp,C(tystep) - movl %edi,%ebp - subl C(vidwidth),%edi - jmp inloop -// .align 4 -vtquadloop: - addl C(tystep),%ecx - adcb %cl,%bl -p6: addl $2*0x12345678,%ebp - andb $0x7f,%bl - movb (%eax),%dl - movb (%esi,%ebx),%ah // fetch texel : colormap number - movb (%edx), %dl // use colormap now ! - movb %dl,(%edi) - movb (%ebp),%al // fetch dest : index into colormap -inloop: - addl C(tystep),%ecx - adcb %cl,%bl -p7: addl $2*0x12345678,%edi - andb $0x7f,%bl - movb (%eax),%dl - movb (%esi,%ebx),%ah // fetch texel : colormap number - movb (%edx), %dl // use colormap now ! - movb %dl,(%ebp) - movb (%edi),%al // fetch dest : index into colormap - - addl C(tystep),%ecx - adcb %cl,%bl -p8: addl $2*0x12345678,%ebp - andb $0x7f,%bl - movb (%eax),%dl - movb (%esi,%ebx),%ah // fetch texel : colormap number - movb (%edx), %dl // use colormap now ! - movb %dl,(%edi) - movb (%ebp),%al // fetch dest : index into colormap - - addl C(tystep),%ecx - adcb %cl,%bl -p9: addl $2*0x12345678,%edi - andb $0x7f,%bl - movb (%eax),%dl - movb (%esi,%ebx),%ah // fetch texel : colormap number - movb (%edx), %dl // use colormap now ! - movb %dl,(%ebp) - movb (%edi),%al // fetch dest : index into colormap - - decb %ch - jnz vtquadloop - -vtdone: - popl %ebx // restore register variables - popl %edi - popl %esi - popl %ebp // restore caller's stack frame pointer - ret - -#endif // ifdef USEASM - - - -//---------------------------------------------------------------------- -// R_DrawShadeColumn -// -// for smoke..etc.. test. -//---------------------------------------------------------------------- - -#ifdef LINUX - .align 2 -#else - .align 5 -#endif -.globl C(R_DrawShadeColumn_8) -C(R_DrawShadeColumn_8): - pushl %ebp // preserve caller's stack frame pointer - pushl %esi // preserve register variables - pushl %edi - pushl %ebx - -// -// dest = ylookup[dc_yl] + columnofs[dc_x]; -// - movl C(dc_yl),%ebp - movl %ebp,%ebx - movl C(ylookup)(,%ebx,4),%edi - movl C(dc_x),%ebx - addl C(columnofs)(,%ebx,4),%edi // edi = dest - -// -// pixelcount = yh - yl + 1 -// - movl C(dc_yh),%eax - incl %eax - subl %ebp,%eax // pixel count - movl %eax,C(pixelcount) // save for final pixel - jle shdone // nothing to scale - -// -// frac = dc_texturemid - (centery-dc_yl)*fracstep; -// - movl C(dc_iscale),%ecx // fracstep - movl C(centery),%eax - subl %ebp,%eax - imul %ecx,%eax - movl C(dc_texturemid),%edx - subl %eax,%edx - movl %edx,%ebx - shrl $16,%ebx // frac int. - andl $0x0000007f,%ebx - shll $16,%edx // y frac up - - movl %ecx,%ebp - shll $16,%ebp // fracstep f. up - shrl $16,%ecx // fracstep i. ->cl - andb $0x7f,%cl - - movl C(dc_source),%esi - -// -// lets rock :) ! -// - movl C(pixelcount),%eax - movb %al,%dh - shrl $2,%eax - movb %al,%ch // quad count - movl C(colormaps),%eax - testb $0x03,%dh - jz sh4quadloop - -// -// do un-even pixel -// - testb $1,%dh - jz 2f - - movb (%esi,%ebx),%ah // fetch texel : colormap number - addl %ebp,%edx - adcb %cl,%bl - movb (%edi),%al // fetch dest : index into colormap - andb $0x7f,%bl - movb (%eax),%dl - movb %dl,(%edi) - addl C(vidwidth),%edi - -// -// do two non-quad-aligned pixels -// -2: - testb $2,%dh - jz 3f - - movb (%esi,%ebx),%ah // fetch texel : colormap number - addl %ebp,%edx - adcb %cl,%bl - movb (%edi),%al // fetch dest : index into colormap - andb $0x7f,%bl - movb (%eax),%dl - movb %dl,(%edi) - addl C(vidwidth),%edi - - movb (%esi,%ebx),%ah // fetch texel : colormap number - addl %ebp,%edx - adcb %cl,%bl - movb (%edi),%al // fetch dest : index into colormap - andb $0x7f,%bl - movb (%eax),%dl - movb %dl,(%edi) - addl C(vidwidth),%edi - -// -// test if there was at least 4 pixels -// -3: - testb $0xFF,%ch // test quad count - jz shdone - -// -// ebp : ystep frac. upper 24 bits -// edx : y frac. upper 24 bits -// ebx : y i. lower 7 bits, masked for index -// ecx : ch = counter, cl = y step i. -// eax : colormap aligned 256 -// esi : source texture column -// edi : dest screen -// -sh4quadloop: - movb $0x7f,%dh // prep mask - - movb (%esi,%ebx),%ah // fetch texel : colormap number -sh5: movb 0x12345678(%edi),%al // fetch dest : index into colormap - - movl %ebp,C(tystep) - movl %edi,%ebp - subl C(vidwidth),%edi - jmp shinloop -// .align 4 -shquadloop: - addl C(tystep),%edx - adcb %cl,%bl - andb %dh,%bl -sh6: addl $2*0x12345678,%ebp - movb (%eax),%dl - movb (%esi,%ebx),%ah // fetch texel : colormap number - movb %dl,(%edi) - movb (%ebp),%al // fetch dest : index into colormap -shinloop: - addl C(tystep),%edx - adcb %cl,%bl - andb %dh,%bl -sh7: addl $2*0x12345678,%edi - movb (%eax),%dl - movb (%esi,%ebx),%ah // fetch texel : colormap number - movb %dl,(%ebp) - movb (%edi),%al // fetch dest : index into colormap - - addl C(tystep),%edx - adcb %cl,%bl - andb %dh,%bl -sh8: addl $2*0x12345678,%ebp - movb (%eax),%dl - movb (%esi,%ebx),%ah // fetch texel : colormap number - movb %dl,(%edi) - movb (%ebp),%al // fetch dest : index into colormap - - addl C(tystep),%edx - adcb %cl,%bl - andb %dh,%bl -sh9: addl $2*0x12345678,%edi - movb (%eax),%dl - movb (%esi,%ebx),%ah // fetch texel : colormap number - movb %dl,(%ebp) - movb (%edi),%al // fetch dest : index into colormap - - decb %ch - jnz shquadloop - -shdone: - popl %ebx // restore register variables - popl %edi - popl %esi - popl %ebp // restore caller's stack frame pointer - ret - - - -//---------------------------------------------------------------------- -// -// R_DrawWaterColumn : basically it's just a copy of R_DrawColumn, -// but it uses dc_colormap from dc_yl to dc_yw-1 -// then it uses dc_wcolormap from dc_yw to dc_yh -// -// Thus, the 'underwater' part of the walls is remapped to 'water-like' -// colors. -// -//---------------------------------------------------------------------- - -#ifdef LINUX - .align 2 -#else - .align 5 -#endif -.globl C(R_DrawWaterColumn) -C(R_DrawWaterColumn): - pushl %ebp // preserve caller's stack frame pointer - pushl %esi // preserve register variables - pushl %edi - pushl %ebx - -// -// dest = ylookup[dc_yl] + columnofs[dc_x]; -// - movl C(dc_yl),%ebp - movl %ebp,%ebx - movl C(ylookup)(,%ebx,4),%edi - movl C(dc_x),%ebx - addl C(columnofs)(,%ebx,4),%edi // edi = dest - -// -// pixelcount = yh - yl + 1 -// - movl C(dc_yh),%eax - incl %eax - subl %ebp,%eax // pixel count - movl %eax,C(pixelcount) // save for final pixel - jle wdone // nothing to scale - -// -// frac = dc_texturemid - (centery-dc_yl)*fracstep; -// - movl C(dc_iscale),%ecx // fracstep - movl C(centery),%eax - subl %ebp,%eax - imul %ecx,%eax - movl C(dc_texturemid),%edx - subl %eax,%edx - movl %edx,%ebx - shrl $16,%ebx // frac int. - andl $0x0000007f,%ebx - shll $16,%edx // y frac up - - movl %ecx,%ebp - shll $16,%ebp // fracstep f. up - shrl $16,%ecx // fracstep i. ->cl - andb $0x7f,%cl - - movl C(dc_source),%esi - -// -// lets rock :) ! -// - movl C(pixelcount),%eax - movb %al,%dh - shrl $2,%eax - movb %al,%ch // quad count - movl C(dc_wcolormap),%eax - testb $3,%dh - jz w4quadloop - -// -// do un-even pixel -// - testb $1,%dh - jz 2f - - movb (%esi,%ebx),%al // prep un-even loops - addl %ebp,%edx // ypos f += ystep f - adcb %cl,%bl // ypos i += ystep i - movb (%eax),%dl // colormap texel - andb $0x7f,%bl // mask 0-127 texture index - movb %dl,(%edi) // output pixel - addl C(vidwidth),%edi - -// -// do two non-quad-aligned pixels -// -2: - testb $2,%dh - jz 3f - - movb (%esi,%ebx),%al // fetch source texel - addl %ebp,%edx // ypos f += ystep f - adcb %cl,%bl // ypos i += ystep i - movb (%eax),%dl // colormap texel - andb $0x7f,%bl // mask 0-127 texture index - movb %dl,(%edi) // output pixel - - movb (%esi,%ebx),%al // fetch source texel - addl %ebp,%edx // ypos f += ystep f - adcb %cl,%bl // ypos i += ystep i - movb (%eax),%dl // colormap texel - andb $0x7f,%bl // mask 0-127 texture index - addl C(vidwidth),%edi - movb %dl,(%edi) // output pixel - - addl C(vidwidth),%edi - -// -// test if there was at least 4 pixels -// -3: - testb $0xFF,%ch // test quad count - jz wdone - -// -// ebp : ystep frac. upper 24 bits -// edx : y frac. upper 24 bits -// ebx : y i. lower 7 bits, masked for index -// ecx : ch = counter, cl = y step i. -// eax : colormap aligned 256 -// esi : source texture column -// edi : dest screen -// -w4quadloop: - movb $0x7f,%dh // prep mask -// .align 4 -wquadloop: - movb (%esi,%ebx),%al // prep loop - addl %ebp,%edx // ypos f += ystep f - adcb %cl,%bl // ypos i += ystep i - movb (%eax),%dl // colormap texel - movb %dl,(%edi) // output pixel - andb $0x7f,%bl // mask 0-127 texture index - - movb (%esi,%ebx),%al // fetch source texel - addl %ebp,%edx - adcb %cl,%bl - movb (%eax),%dl -w1: movb %dl,0x12345678(%edi) - andb $0x7f,%bl - - movb (%esi,%ebx),%al // fetch source texel - addl %ebp,%edx - adcb %cl,%bl - movb (%eax),%dl -w2: movb %dl,2*0x12345678(%edi) - andb $0x7f,%bl - - movb (%esi,%ebx),%al // fetch source texel - addl %ebp,%edx - adcb %cl,%bl - movb (%eax),%dl -w3: movb %dl,3*0x12345678(%edi) - andb $0x7f,%bl - -w4: addl $4*0x12345678,%edi - - decb %ch - jnz wquadloop - -wdone: - popl %ebx // restore register variables - popl %edi - popl %esi - popl %ebp // restore caller's stack frame pointer - ret - - - - - - - -//---------------------------------------------------------------------- -// -// R_DrawSpanNoWrap -// -// Horizontal texture mapping, does not remap colors, -// neither needs to wrap around the source texture. -// -// Thus, a special optimisation can be used... -// -//---------------------------------------------------------------------- - - .data - -advancetable: .long 0, 0 -#if !defined( LINUX) - .text -#endif -#ifdef LINUX - .align 2 -#else - .align 4 -#endif -.globl C(R_DrawSpanNoWrap) -C(R_DrawSpanNoWrap): - pushl %ebp // preserve caller's stack frame pointer - pushl %esi // preserve register variables - pushl %edi - pushl %ebx - -// -// find loop count -// - - movl C(ds_x2),%eax - incl %eax - subl C(ds_x1),%eax // pixel count - movl %eax,C(pixelcount) // save for final pixel - jle htvdone // nothing to scale -// shrl $1,%eax // double pixel count -// movl %eax,C(loopcount) - -// -// calculate screen dest -// - - movl C(ds_y),%edi //full destination start address - -// -// set up advancetable -// - - movl C(ds_xstep),%ebp - movl C(ds_ystep),%ecx - movl %ecx,%eax - movl %ebp,%edx - sarl $16,%edx // xstep >>= 16; - movl C(vidwidth),%ebx - sarl $16,%eax // ystep >>= 16; - jz 0f - imull %ebx,%eax // (ystep >> 16) * texwidth; -0: - addl %edx,%eax // add in xstep - // (ystep >> 16) * texwidth + (xstep >> 16); - - movl %eax,advancetable+4 // advance base in y - addl %ebx,%eax // ((ystep >> 16) + 1) * texwidth + - // (xstep >> 16); - movl %eax,advancetable // advance extra in y - - shll $16,%ebp // left-justify xstep fractional part - movl %ebp,xstep - shll $16,%ecx // left-justify ystep fractional part - movl %ecx,ystep - -// -// calculate the texture starting address -// - movl C(ds_source),%esi // texture source - - movl C(ds_yfrac),%eax - movl %eax,%edx - sarl $16,%eax - movl C(ds_xfrac),%ecx - imull %ebx,%eax // (yfrac >> 16) * texwidth - movl %ecx,%ebx - sarl $16,%ecx - movl %ecx,%ebp - addl %eax,%ebp // source = (xfrac >> 16) + - // ((yfrac >> 16) * texwidth); - -// -// esi : texture source -// edi : screen dest -// eax : colormap aligned on 256 boundary, hehehe... -// ebx : xfrac << 16 -// ecx : used in loop, contains either 0 or -1, *4, offset into advancetable -// edx : yfrac << 16 -// ebp : offset into texture -// - - shll $16,%edx // yfrac upper word, lower byte will be used - movl C(ds_colormap),%eax - shll $16,%ebx // xfrac upper word, lower unused - - movl C(pixelcount),%ecx - shrl $2,%ecx - movb %cl,%dh // quad pixels count - - movl C(pixelcount),%ecx - andl $3,%ecx - jz htvquadloop // pixelcount is multiple of 4 - decl %ecx - jz 1f - decl %ecx - jz 2f - -// -// do one to three pixels first -// - addl ystep,%edx // yfrac += ystep - sbbl %ecx,%ecx // turn carry into 0 or -1 if set - movb (%esi,%ebp),%al // get texture pixel - addl xstep,%ebx // xfrac += xstep -// movb (%eax),%dl // pixel goes through colormap - adcl advancetable+4(,%ecx,4),%ebp // advance source - movb %al,(%edi) // write pixel dest - - incl %edi - -2: - addl ystep,%edx // yfrac += ystep - sbbl %ecx,%ecx // turn carry into 0 or -1 if set - movb (%esi,%ebp),%al // get texture pixel - addl xstep,%ebx // xfrac += xstep -// movb (%eax),%dl // pixel goes through colormap - adcl advancetable+4(,%ecx,4),%ebp // advance source - movb %al,(%edi) // write pixel dest - - incl %edi - -1: - addl ystep,%edx // yfrac += ystep - sbbl %ecx,%ecx // turn carry into 0 or -1 if set - movb (%esi,%ebp),%al // get texture pixel - addl xstep,%ebx // xfrac += xstep -// movb (%eax),%dl // pixel goes through colormap - adcl advancetable+4(,%ecx,4),%ebp // advance source - movb %al,(%edi) // write pixel dest - - incl %edi - -// -// test if there was at least 4 pixels -// - testb $0xFF,%dh - jz htvdone - -// -// two pixels per loop -// U -// V -htvquadloop: - addl ystep,%edx // yfrac += ystep - sbbl %ecx,%ecx // turn carry into 0 or -1 if set - movb (%esi,%ebp),%al // get texture pixel - addl xstep,%ebx // xfrac += xstep -// movb (%eax),%dl // pixel goes through colormap - adcl advancetable+4(,%ecx,4),%ebp // advance source - movb %al,(%edi) // write pixel dest - - addl ystep,%edx - sbbl %ecx,%ecx - movb (%esi,%ebp),%al - addl xstep,%ebx -// movb (%eax),%dl - adcl advancetable+4(,%ecx,4),%ebp - movb %al,1(%edi) - - addl ystep,%edx - sbbl %ecx,%ecx - movb (%esi,%ebp),%al - addl xstep,%ebx -// movb (%eax),%dl - adcl advancetable+4(,%ecx,4),%ebp - movb %al,2(%edi) - - addl ystep,%edx - sbbl %ecx,%ecx - movb (%esi,%ebp),%al - addl xstep,%ebx -// movb (%eax),%dl - adcl advancetable+4(,%ecx,4),%ebp - movb %al,3(%edi) - - addl $4, %edi - incl %ecx //dummy - - decb %dh - jnz htvquadloop // paire dans V-pipe - -htvdone: - popl %ebx // restore register variables - popl %edi - popl %esi - popl %ebp // restore caller's stack frame pointer - ret - - -//.endif - -#ifdef HORIZONTALDRAW -// void R_RotateBuffere (void) - -#ifdef LINUX - .align 2 -#else - .align 4 -#endif -.globl C(R_RotateBufferasm) -C(R_RotateBufferasm): - pushl %ebp // preserve caller's stack frame pointer - pushl %esi // preserve register variables - pushl %edi - pushl %ebx - - movl C(dc_source),%esi - movl C(dc_colormap),%edi - - movl $200,%edx -ra2: - movl $40,%ecx -ra: - movb -2*200(%esi),%al - movb -6*200(%esi),%bl - movb -3*200(%esi),%ah - movb -7*200(%esi),%bh - shll $16,%eax - shll $16,%ebx - movb (%esi),%al - movb -4*200(%esi),%bl - movb -1*200(%esi),%ah - movb -5*200(%esi),%bh - movl %eax,(%edi) - subl $8*200,%esi - movl %ebx,4(%edi) - addl $8,%edi - decl %ecx - jnz ra - - addl $320*200+1,%esi //32*480 passe a la ligne suivante -// addl 320-32,%edi - - decl %edx - jnz ra2 - - pop %ebp // preserve caller's stack frame pointer - pop %esi // preserve register variables - pop %edi - pop %ebx - ret -#endif diff --git a/src/tmap_asm.s b/src/tmap_asm.s deleted file mode 100644 index d8967178cdf28e3b9bedbda863232ef0bf0978d4..0000000000000000000000000000000000000000 --- a/src/tmap_asm.s +++ /dev/null @@ -1,322 +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 tmap_asm.s -/// \brief ??? - -//.comm _dc_colormap,4 -//.comm _dc_x,4 -//.comm _dc_yl,4 -//.comm _dc_yh,4 -//.comm _dc_iscale,4 -//.comm _dc_texturemid,4 -//.comm _dc_source,4 -//.comm _ylookup,4 -//.comm _columnofs,4 -//.comm _loopcount,4 -//.comm _pixelcount,4 -.data -_pixelcount: -.long 0x00000000 -_loopcount: -.long 0x00000000 -.align 8 -_mmxcomm: -.long 0x00000000 -.text - - .align 4 -.globl _R_DrawColumn8_NOMMX -_R_DrawColumn8_NOMMX: - pushl %ebp - pushl %esi - pushl %edi - pushl %ebx - movl _dc_yl,%edx - movl _dc_yh,%eax - subl %edx,%eax - leal 1(%eax),%ebx - testl %ebx,%ebx - jle rdc8ndone - movl _dc_x,%eax - movl _ylookup, %edi - movl (%edi,%edx,4),%esi - movl _columnofs, %edi - addl (%edi,%eax,4),%esi - movl _dc_iscale,%edi - movl %edx,%eax - imull %edi,%eax - movl _dc_texturemid,%ecx - addl %eax,%ecx - - movl _dc_source,%ebp - xorl %edx, %edx - subl $0x12345678, %esi -.globl rdc8nwidth1 -rdc8nwidth1: - .align 4,0x90 -rdc8nloop: - movl %ecx,%eax - shrl $16,%eax - addl %edi,%ecx - andl $127,%eax - addl $0x12345678,%esi -.globl rdc8nwidth2 -rdc8nwidth2: - movb (%eax,%ebp),%dl - movl _dc_colormap,%eax - movb (%eax,%edx),%al - movb %al,(%esi) - decl %ebx - jne rdc8nloop -rdc8ndone: - popl %ebx - popl %edi - popl %esi - popl %ebp - ret - -// -// Optimised specifically for P54C/P55C (aka Pentium with/without MMX) -// By ES 1998/08/01 -// - -.globl _R_DrawColumn_8_Pentium -_R_DrawColumn_8_Pentium: - pushl %ebp - pushl %ebx - pushl %esi - pushl %edi - movl _dc_yl,%eax // Top pixel - movl _dc_yh,%ebx // Bottom pixel - movl _ylookup, %edi - movl (%edi,%ebx,4),%ecx - subl %eax,%ebx // ebx=number of pixels-1 - jl rdc8pdone // no pixel to draw, done - jnz rdc8pmany - movl _dc_x,%edx // Special case: only one pixel - movl _columnofs, %edi - addl (%edi,%edx,4),%ecx // dest pixel at (%ecx) - movl _dc_iscale,%esi - imull %esi,%eax - movl _dc_texturemid,%edi - addl %eax,%edi // texture index in edi - movl _dc_colormap,%edx - shrl $16, %edi - movl _dc_source,%ebp - andl $127,%edi - movb (%edi,%ebp),%dl // read texture pixel - movb (%edx),%al // lookup for light - movb %al,0(%ecx) // write it - jmp rdc8pdone // done! -.align 4, 0x90 -rdc8pmany: // draw >1 pixel - movl _dc_x,%edx - movl _columnofs, %edi - movl (%edi,%edx,4),%edx - leal 0x12345678(%edx, %ecx), %edi // edi = two pixels above bottom -.globl rdc8pwidth5 -rdc8pwidth5: // DeadBeef = -2*SCREENWIDTH - movl _dc_iscale,%edx // edx = fracstep - imull %edx,%eax - shll $9, %edx // fixme: Should get 7.25 fix as input - movl _dc_texturemid,%ecx - addl %eax,%ecx // ecx = frac - movl _dc_colormap,%eax // eax = lighting/special effects LUT - shll $9, %ecx - movl _dc_source,%esi // esi = source ptr - - imull $0x12345678, %ebx // ebx = negative offset to pixel -.globl rdc8pwidth6 -rdc8pwidth6: // DeadBeef = -SCREENWIDTH - -// Begin the calculation of the two first pixels - leal (%ecx, %edx), %ebp - shrl $25, %ecx - movb (%esi, %ecx), %al - leal (%edx, %ebp), %ecx - shrl $25, %ebp - movb (%eax), %dl - -// The main loop -rdc8ploop: - movb (%esi,%ebp), %al // load 1 - leal (%ecx, %edx), %ebp // calc frac 3 - - shrl $25, %ecx // shift frac 2 - movb %dl, 0x12345678(%edi, %ebx)// store 0 -.globl rdc8pwidth1 -rdc8pwidth1: // DeadBeef = 2*SCREENWIDTH - - movb (%eax), %al // lookup 1 - - movb %al, 0x12345678(%edi, %ebx)// store 1 -.globl rdc8pwidth2 -rdc8pwidth2: // DeadBeef = 3*SCREENWIDTH - movb (%esi, %ecx), %al // load 2 - - leal (%ebp, %edx), %ecx // calc frac 4 - - shrl $25, %ebp // shift frac 3 - movb (%eax), %dl // lookup 2 - - addl $0x12345678, %ebx // counter -.globl rdc8pwidth3 -rdc8pwidth3: // DeadBeef = 2*SCREENWIDTH - jl rdc8ploop // loop - -// End of loop. Write extra pixel or just exit. - jnz rdc8pdone - movb %dl, 0x12345678(%edi, %ebx)// Write odd pixel -.globl rdc8pwidth4 -rdc8pwidth4: // DeadBeef = 2*SCREENWIDTH - -rdc8pdone: - - popl %edi - popl %esi - popl %ebx - popl %ebp - ret - -// -// MMX asm version, optimised for K6 -// By ES 1998/07/05 -// - -.globl _R_DrawColumn_8_K6_MMX -_R_DrawColumn_8_K6_MMX: - pushl %ebp - pushl %ebx - pushl %esi - pushl %edi - - movl %esp, %eax // Push 8 or 12, so that (%esp) gets aligned by 8 - andl $7,%eax - addl $8,%eax - movl %eax, _mmxcomm // Temp storage in mmxcomm: (%esp) is used instead - subl %eax,%esp - - movl _dc_yl,%edx // Top pixel - movl _dc_yh,%ebx // Bottom pixel - movl _ylookup, %edi - movl (%edi,%ebx,4),%ecx - subl %edx,%ebx // ebx=number of pixels-1 - jl 0x12345678 // no pixel to draw, done -.globl rdc8moffs1 -rdc8moffs1: - jnz rdc8mmany - movl _dc_x,%eax // Special case: only one pixel - movl _columnofs, %edi - addl (%edi,%eax,4),%ecx // dest pixel at (%ecx) - movl _dc_iscale,%esi - imull %esi,%edx - movl _dc_texturemid,%edi - addl %edx,%edi // texture index in edi - movl _dc_colormap,%edx - shrl $16, %edi - movl _dc_source,%ebp - andl $127,%edi - movb (%edi,%ebp),%dl // read texture pixel - movb (%edx),%al // lookup for light - movb %al,0(%ecx) // write it - jmp rdc8mdone // done! -.globl rdc8moffs2 -rdc8moffs2: -.align 4, 0x90 -rdc8mmany: // draw >1 pixel - movl _dc_x,%eax - movl _columnofs, %edi - movl (%edi,%eax,4),%eax - leal 0x12345678(%eax, %ecx), %esi // esi = two pixels above bottom -.globl rdc8mwidth3 -rdc8mwidth3: // DeadBeef = -2*SCREENWIDTH - movl _dc_iscale,%ecx // ecx = fracstep - imull %ecx,%edx - shll $9, %ecx // fixme: Should get 7.25 fix as input - movl _dc_texturemid,%eax - addl %edx,%eax // eax = frac - movl _dc_colormap,%edx // edx = lighting/special effects LUT - shll $9, %eax - leal (%ecx, %ecx), %edi - movl _dc_source,%ebp // ebp = source ptr - movl %edi, 0(%esp) // Start moving frac and fracstep to MMX regs - - imull $0x12345678, %ebx // ebx = negative offset to pixel -.globl rdc8mwidth5 -rdc8mwidth5: // DeadBeef = -SCREENWIDTH - - movl %edi, 4(%esp) - leal (%eax, %ecx), %edi - movq 0(%esp), %mm1 // fracstep:fracstep in mm1 - movl %eax, 0(%esp) - shrl $25, %eax - movl %edi, 4(%esp) - movzbl (%ebp, %eax), %eax - movq 0(%esp), %mm0 // frac:frac in mm0 - - paddd %mm1, %mm0 - shrl $25, %edi - movq %mm0, %mm2 - psrld $25, %mm2 // texture index in mm2 - paddd %mm1, %mm0 - movq %mm2, 0(%esp) - -.globl rdc8mloop -rdc8mloop: // The main loop - movq %mm0, %mm2 // move 4-5 to temp reg - movzbl (%ebp, %edi), %edi // read 1 - - psrld $25, %mm2 // shift 4-5 - movb (%edx,%eax), %cl // lookup 0 - - movl 0(%esp), %eax // load 2 - addl $0x12345678, %ebx // counter -.globl rdc8mwidth2 -rdc8mwidth2: // DeadBeef = 2*SCREENWIDTH - - movb %cl, (%esi, %ebx) // write 0 - movb (%edx,%edi), %ch // lookup 1 - - movb %ch, 0x12345678(%esi, %ebx) // write 1 -.globl rdc8mwidth1 -rdc8mwidth1: // DeadBeef = SCREENWIDTH - movl 4(%esp), %edi // load 3 - - paddd %mm1, %mm0 // frac 6-7 - movzbl (%ebp, %eax), %eax // lookup 2 - - movq %mm2, 0(%esp) // store texture index 4-5 - jl rdc8mloop - - jnz rdc8mno_odd - movb (%edx,%eax), %cl // write the last odd pixel - movb %cl, 0x12345678(%esi) -.globl rdc8mwidth4 -rdc8mwidth4: // DeadBeef = 2*SCREENWIDTH -rdc8mno_odd: - -.globl rdc8mdone -rdc8mdone: - emms - - addl _mmxcomm, %esp - popl %edi - popl %esi - popl %ebx - popl %ebp - ret - -// Need some extra space to align run-time -.globl R_DrawColumn_8_K6_MMX_end -R_DrawColumn_8_K6_MMX_end: -nop;nop;nop;nop;nop;nop;nop;nop; -nop;nop;nop;nop;nop;nop;nop;nop; -nop;nop;nop;nop;nop;nop;nop;nop; -nop;nop;nop;nop;nop;nop;nop; diff --git a/src/tmap_mmx.nas b/src/tmap_mmx.nas deleted file mode 100644 index a45667e23d539997193e0df23862dba71458c6f6..0000000000000000000000000000000000000000 --- a/src/tmap_mmx.nas +++ /dev/null @@ -1,674 +0,0 @@ -;; SONIC ROBO BLAST 2 -;;----------------------------------------------------------------------------- -;; Copyright (C) 1998-2000 by DOSDOOM. -;; Copyright (C) 2010-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: -;; tmap_mmx.nas -;; DESCRIPTION: -;; Assembler optimised rendering code for software mode, using SIMD -;; instructions. -;; Draw wall columns. - - -[BITS 32] - -%define FRACBITS 16 -%define TRANSPARENTPIXEL 255 - -%ifdef LINUX -%macro cextern 1 -[extern %1] -%endmacro - -%macro cglobal 1 -[global %1] -%endmacro - -%else -%macro cextern 1 -%define %1 _%1 -[extern %1] -%endmacro - -%macro cglobal 1 -%define %1 _%1 -[global %1] -%endmacro - -%endif - - -; The viddef_s structure. We only need the width field. -struc viddef_s - resb 12 -.width: resb 4 - resb 44 -endstruc - - -;; externs -;; columns -cextern dc_colormap -cextern dc_x -cextern dc_yl -cextern dc_yh -cextern dc_iscale -cextern dc_texturemid -cextern dc_texheight -cextern dc_source -cextern dc_hires -cextern centery -cextern centeryfrac -cextern dc_transmap - -cextern R_DrawColumn_8_ASM -cextern R_Draw2sMultiPatchColumn_8_ASM - -;; spans -cextern nflatshiftup -cextern nflatxshift -cextern nflatyshift -cextern nflatmask -cextern ds_xfrac -cextern ds_yfrac -cextern ds_xstep -cextern ds_ystep -cextern ds_x1 -cextern ds_x2 -cextern ds_y -cextern ds_source -cextern ds_colormap - -cextern ylookup -cextern columnofs -cextern vid - -[SECTION .data] - -nflatmask64 dq 0 - - -[SECTION .text] - -;;---------------------------------------------------------------------- -;; -;; R_DrawColumn : 8bpp column drawer -;; -;; MMX column drawer. -;; -;;---------------------------------------------------------------------- -;; eax = accumulator -;; ebx = colormap -;; ecx = count -;; edx = accumulator -;; esi = source -;; edi = dest -;; ebp = vid.width -;; mm0 = accumulator -;; mm1 = heightmask, twice -;; mm2 = 2 * fracstep, twice -;; mm3 = pair of consecutive fracs -;;---------------------------------------------------------------------- - - -cglobal R_DrawColumn_8_MMX -R_DrawColumn_8_MMX: - push ebp ;; preserve caller's stack frame pointer - push esi ;; preserve register variables - push edi - push ebx - -;; -;; Our algorithm requires that the texture height be a power of two. -;; If not, fall back to the non-MMX drawer. -;; -.texheightcheck: - mov edx, [dc_texheight] - sub edx, 1 ;; edx = heightmask - test edx, [dc_texheight] - jnz near .usenonMMX - - mov ebp, edx ;; Keep a copy of heightmask in a - ;; GPR for the time being. - -;; -;; Fill mm1 with heightmask -;; - movd mm1, edx ;; low dword = heightmask - punpckldq mm1, mm1 ;; copy low dword to high dword - -;; -;; dest = ylookup[dc_yl] + columnofs[dc_x]; -;; - mov eax, [dc_yl] - mov edi, [ylookup+eax*4] - mov ebx, [dc_x] - add edi, [columnofs+ebx*4] ;; edi = dest - - -;; -;; pixelcount = yh - yl + 1 -;; - mov ecx, [dc_yh] - add ecx, 1 - sub ecx, eax ;; pixel count - jle near .done ;; nothing to scale - -;; -;; fracstep = dc_iscale; -;; - movd mm2, [dc_iscale] ;; fracstep in low dword - punpckldq mm2, mm2 ;; copy to high dword - - mov ebx, [dc_colormap] - mov esi, [dc_source] - -;; -;; frac = (dc_texturemid + FixedMul((dc_yl << FRACBITS) - centeryfrac, fracstep)); -;; - ;; eax == dc_yl already - shl eax, FRACBITS - sub eax, [centeryfrac] - imul dword [dc_iscale] - shrd eax, edx, FRACBITS - add eax, [dc_texturemid] - -;; -;; if (dc_hires) frac = 0; -;; - test byte [dc_hires], 0x01 - jz .mod2 - xor eax, eax - - -;; -;; Do mod-2 pixel. -;; -.mod2: - test ecx, 1 - jz .pairprepare - mov edx, eax ;; edx = frac - add eax, [dc_iscale] ;; eax += fracstep - sar edx, FRACBITS - and edx, ebp ;; edx &= heightmask - movzx edx, byte [esi + edx] - movzx edx, byte [ebx + edx] - mov [edi], dl - - add edi, [vid + viddef_s.width] - sub ecx, 1 - jz .done - -.pairprepare: -;; -;; Prepare for the main loop. -;; - movd mm3, eax ;; Low dword = frac - movq mm4, mm3 ;; Copy to intermediate register - paddd mm4, mm2 ;; dwords of mm4 += fracstep - punpckldq mm3, mm4 ;; Low dword = first frac, high = second - pslld mm2, 1 ;; fracstep *= 2 - -;; -;; ebp = vid.width -;; - mov ebp, [vid + viddef_s.width] - - align 16 -.pairloop: - movq mm0, mm3 ;; 3B 1u. - psrad mm0, FRACBITS ;; 4B 1u. - pand mm0, mm1 ;; 3B 1u. frac &= heightmask - paddd mm3, mm2 ;; 3B 1u. frac += fracstep - - movd eax, mm0 ;; 3B 1u. Get first frac -;; IFETCH boundary - movzx eax, byte [esi + eax] ;; 4B 1u. Texture map - movzx eax, byte [ebx + eax] ;; 4B 1u. Colormap - - punpckhdq mm0, mm0 ;; 3B 1(2)u. low dword = high dword - movd edx, mm0 ;; 3B 1u. Get second frac - mov [edi], al ;; 2B 1(2)u. First pixel -;; IFETCH boundary - - movzx edx, byte [esi + edx] ;; 4B 1u. Texture map - movzx edx, byte [ebx + edx] ;; 4B 1u. Colormap - mov [edi + 1*ebp], dl ;; 3B 1(2)u. Second pixel - - lea edi, [edi + 2*ebp] ;; 3B 1u. edi += 2 * vid.width -;; IFETCH boundary - sub ecx, 2 ;; 3B 1u. count -= 2 - jnz .pairloop ;; 2B 1u. if(count != 0) goto .pairloop - - -.done: -;; -;; Clear MMX state, or else FPU operations will go badly awry. -;; - emms - - pop ebx - pop edi - pop esi - pop ebp - ret - -.usenonMMX: - call R_DrawColumn_8_ASM - jmp .done - - -;;---------------------------------------------------------------------- -;; -;; R_Draw2sMultiPatchColumn : Like R_DrawColumn, but omits transparent -;; pixels. -;; -;; MMX column drawer. -;; -;;---------------------------------------------------------------------- -;; eax = accumulator -;; ebx = colormap -;; ecx = count -;; edx = accumulator -;; esi = source -;; edi = dest -;; ebp = vid.width -;; mm0 = accumulator -;; mm1 = heightmask, twice -;; mm2 = 2 * fracstep, twice -;; mm3 = pair of consecutive fracs -;;---------------------------------------------------------------------- - - -cglobal R_Draw2sMultiPatchColumn_8_MMX -R_Draw2sMultiPatchColumn_8_MMX: - push ebp ;; preserve caller's stack frame pointer - push esi ;; preserve register variables - push edi - push ebx - -;; -;; Our algorithm requires that the texture height be a power of two. -;; If not, fall back to the non-MMX drawer. -;; -.texheightcheck: - mov edx, [dc_texheight] - sub edx, 1 ;; edx = heightmask - test edx, [dc_texheight] - jnz near .usenonMMX - - mov ebp, edx ;; Keep a copy of heightmask in a - ;; GPR for the time being. - -;; -;; Fill mm1 with heightmask -;; - movd mm1, edx ;; low dword = heightmask - punpckldq mm1, mm1 ;; copy low dword to high dword - -;; -;; dest = ylookup[dc_yl] + columnofs[dc_x]; -;; - mov eax, [dc_yl] - mov edi, [ylookup+eax*4] - mov ebx, [dc_x] - add edi, [columnofs+ebx*4] ;; edi = dest - - -;; -;; pixelcount = yh - yl + 1 -;; - mov ecx, [dc_yh] - add ecx, 1 - sub ecx, eax ;; pixel count - jle near .done ;; nothing to scale -;; -;; fracstep = dc_iscale; -;; - movd mm2, [dc_iscale] ;; fracstep in low dword - punpckldq mm2, mm2 ;; copy to high dword - - mov ebx, [dc_colormap] - mov esi, [dc_source] - -;; -;; frac = (dc_texturemid + FixedMul((dc_yl << FRACBITS) - centeryfrac, fracstep)); -;; - ;; eax == dc_yl already - shl eax, FRACBITS - sub eax, [centeryfrac] - imul dword [dc_iscale] - shrd eax, edx, FRACBITS - add eax, [dc_texturemid] - -;; -;; if (dc_hires) frac = 0; -;; - test byte [dc_hires], 0x01 - jz .mod2 - xor eax, eax - - -;; -;; Do mod-2 pixel. -;; -.mod2: - test ecx, 1 - jz .pairprepare - mov edx, eax ;; edx = frac - add eax, [dc_iscale] ;; eax += fracstep - sar edx, FRACBITS - and edx, ebp ;; edx &= heightmask - movzx edx, byte [esi + edx] - cmp dl, TRANSPARENTPIXEL - je .nextmod2 - movzx edx, byte [ebx + edx] - mov [edi], dl - -.nextmod2: - add edi, [vid + viddef_s.width] - sub ecx, 1 - jz .done - -.pairprepare: -;; -;; Prepare for the main loop. -;; - movd mm3, eax ;; Low dword = frac - movq mm4, mm3 ;; Copy to intermediate register - paddd mm4, mm2 ;; dwords of mm4 += fracstep - punpckldq mm3, mm4 ;; Low dword = first frac, high = second - pslld mm2, 1 ;; fracstep *= 2 - -;; -;; ebp = vid.width -;; - mov ebp, [vid + viddef_s.width] - - align 16 -.pairloop: - movq mm0, mm3 ;; 3B 1u. - psrad mm0, FRACBITS ;; 4B 1u. - pand mm0, mm1 ;; 3B 1u. frac &= heightmask - paddd mm3, mm2 ;; 3B 1u. frac += fracstep - - movd eax, mm0 ;; 3B 1u. Get first frac -;; IFETCH boundary - movzx eax, byte [esi + eax] ;; 4B 1u. Texture map - punpckhdq mm0, mm0 ;; 3B 1(2)u. low dword = high dword - movd edx, mm0 ;; 3B 1u. Get second frac - cmp al, TRANSPARENTPIXEL ;; 2B 1u. - je .secondinpair ;; 2B 1u. -;; IFETCH boundary - movzx eax, byte [ebx + eax] ;; 4B 1u. Colormap - mov [edi], al ;; 2B 1(2)u. First pixel - -.secondinpair: - movzx edx, byte [esi + edx] ;; 4B 1u. Texture map - cmp dl, TRANSPARENTPIXEL ;; 2B 1u. - je .nextpair ;; 2B 1u. -;; IFETCH boundary - movzx edx, byte [ebx + edx] ;; 4B 1u. Colormap - mov [edi + 1*ebp], dl ;; 3B 1(2)u. Second pixel - -.nextpair: - lea edi, [edi + 2*ebp] ;; 3B 1u. edi += 2 * vid.width - sub ecx, 2 ;; 3B 1u. count -= 2 - jnz .pairloop ;; 2B 1u. if(count != 0) goto .pairloop - - -.done: -;; -;; Clear MMX state, or else FPU operations will go badly awry. -;; - emms - - pop ebx - pop edi - pop esi - pop ebp - ret - -.usenonMMX: - call R_Draw2sMultiPatchColumn_8_ASM - jmp .done - - -;;---------------------------------------------------------------------- -;; -;; R_DrawSpan : 8bpp span drawer -;; -;; MMX span drawer. -;; -;;---------------------------------------------------------------------- -;; eax = accumulator -;; ebx = colormap -;; ecx = count -;; edx = accumulator -;; esi = source -;; edi = dest -;; ebp = two pixels -;; mm0 = accumulator -;; mm1 = xposition -;; mm2 = yposition -;; mm3 = 2 * xstep -;; mm4 = 2 * ystep -;; mm5 = nflatxshift -;; mm6 = nflatyshift -;; mm7 = accumulator -;;---------------------------------------------------------------------- - -cglobal R_DrawSpan_8_MMX -R_DrawSpan_8_MMX: - push ebp ;; preserve caller's stack frame pointer - push esi ;; preserve register variables - push edi - push ebx - -;; -;; esi = ds_source -;; ebx = ds_colormap -;; - mov esi, [ds_source] - mov ebx, [ds_colormap] - -;; -;; edi = ylookup[ds_y] + columnofs[ds_x1] -;; - mov eax, [ds_y] - mov edi, [ylookup + eax*4] - mov edx, [ds_x1] - add edi, [columnofs + edx*4] - -;; -;; ecx = ds_x2 - ds_x1 + 1 -;; - mov ecx, [ds_x2] - sub ecx, edx - add ecx, 1 - -;; -;; Needed for fracs and steps -;; - movd mm7, [nflatshiftup] - -;; -;; mm3 = xstep -;; - movd mm3, [ds_xstep] - pslld mm3, mm7 - punpckldq mm3, mm3 - -;; -;; mm4 = ystep -;; - movd mm4, [ds_ystep] - pslld mm4, mm7 - punpckldq mm4, mm4 - -;; -;; mm1 = pair of consecutive xpositions -;; - movd mm1, [ds_xfrac] - pslld mm1, mm7 - movq mm6, mm1 - paddd mm6, mm3 - punpckldq mm1, mm6 - -;; -;; mm2 = pair of consecutive ypositions -;; - movd mm2, [ds_yfrac] - pslld mm2, mm7 - movq mm6, mm2 - paddd mm6, mm4 - punpckldq mm2, mm6 - -;; -;; mm5 = nflatxshift -;; mm6 = nflatyshift -;; - movd mm5, [nflatxshift] - movd mm6, [nflatyshift] - -;; -;; Mask is in memory due to lack of registers. -;; - mov eax, [nflatmask] - mov [nflatmask64], eax - mov [nflatmask64 + 4], eax - - -;; -;; Go until we reach a dword boundary. -;; -.unaligned: - test edi, 3 - jz .alignedprep -.stragglers: - cmp ecx, 0 - je .done ;; If ecx == 0, we're finished. - -;; -;; eax = ((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift) -;; - movq mm0, mm1 ;; mm0 = xposition - movq mm7, mm2 ;; mm7 = yposition - paddd mm1, mm3 ;; xposition += xstep (once!) - paddd mm2, mm4 ;; yposition += ystep (once!) - psrld mm0, mm5 ;; shift - psrld mm7, mm6 ;; shift - pand mm7, [nflatmask64] ;; mask - por mm0, mm7 ;; or x and y together - - movd eax, mm0 ;; eax = index of first pixel - movzx eax, byte [esi + eax] ;; al = source[eax] - movzx eax, byte [ebx + eax] ;; al = colormap[al] - - mov [edi], al - add edi, 1 - - sub ecx, 1 - jmp .unaligned - - -.alignedprep: -;; -;; We can double the steps now. -;; - pslld mm3, 1 - pslld mm4, 1 - - -;; -;; Generate chunks of four pixels. -;; -.alignedloop: - -;; -;; Make sure we have at least four pixels. -;; - cmp ecx, 4 - jl .prestragglers - -;; -;; First two pixels. -;; - movq mm0, mm1 ;; mm0 = xposition - movq mm7, mm2 ;; mm7 = yposition - paddd mm1, mm3 ;; xposition += xstep - paddd mm2, mm4 ;; yposition += ystep - psrld mm0, mm5 ;; shift - psrld mm7, mm6 ;; shift - pand mm7, [nflatmask64] ;; mask - por mm0, mm7 ;; or x and y together - - movd eax, mm0 ;; eax = index of first pixel - movzx eax, byte [esi + eax] ;; al = source[eax] - movzx ebp, byte [ebx + eax] ;; ebp = colormap[al] - - punpckhdq mm0, mm0 ;; both dwords = high dword - movd eax, mm0 ;; eax = index of second pixel - movzx eax, byte [esi + eax] ;; al = source[eax] - movzx eax, byte [ebx + eax] ;; al = colormap[al] - shl eax, 8 ;; get pixel in right byte - or ebp, eax ;; put pixel in ebp - -;; -;; Next two pixels. -;; - movq mm0, mm1 ;; mm0 = xposition - movq mm7, mm2 ;; mm7 = yposition - paddd mm1, mm3 ;; xposition += xstep - paddd mm2, mm4 ;; yposition += ystep - psrld mm0, mm5 ;; shift - psrld mm7, mm6 ;; shift - pand mm7, [nflatmask64] ;; mask - por mm0, mm7 ;; or x and y together - - movd eax, mm0 ;; eax = index of third pixel - movzx eax, byte [esi + eax] ;; al = source[eax] - movzx eax, byte [ebx + eax] ;; al = colormap[al] - shl eax, 16 ;; get pixel in right byte - or ebp, eax ;; put pixel in ebp - - punpckhdq mm0, mm0 ;; both dwords = high dword - movd eax, mm0 ;; eax = index of second pixel - movzx eax, byte [esi + eax] ;; al = source[eax] - movzx eax, byte [ebx + eax] ;; al = colormap[al] - shl eax, 24 ;; get pixel in right byte - or ebp, eax ;; put pixel in ebp - -;; -;; Write pixels. -;; - mov [edi], ebp - add edi, 4 - - sub ecx, 4 - jmp .alignedloop - -.prestragglers: -;; -;; Back to one step at a time. -;; - psrad mm3, 1 - psrad mm4, 1 - jmp .stragglers - -.done: -;; -;; Clear MMX state, or else FPU operations will go badly awry. -;; - emms - - pop ebx - pop edi - pop esi - pop ebp - ret diff --git a/src/tmap_vc.nas b/src/tmap_vc.nas deleted file mode 100644 index c85cf70035f8588387420d479725242bb708cc42..0000000000000000000000000000000000000000 --- a/src/tmap_vc.nas +++ /dev/null @@ -1,48 +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: -;; tmap_vc.nas -;; DESCRIPTION: -;; Assembler optimised math code for Visual C++. - - -[BITS 32] - -%macro cglobal 1 -%define %1 _%1 -[global %1] -%endmacro - -[SECTION .text write] - -;---------------------------------------------------------------------------- -;fixed_t FixedMul (fixed_t a, fixed_t b) -;---------------------------------------------------------------------------- -cglobal FixedMul -; align 16 -FixedMul: - mov eax,[esp+4] - imul dword [esp+8] - shrd eax,edx,16 - ret - -;---------------------------------------------------------------------------- -;fixed_t FixedDiv2 (fixed_t a, fixed_t b); -;---------------------------------------------------------------------------- -cglobal FixedDiv2 -; align 16 -FixedDiv2: - mov eax,[esp+4] - mov edx,eax ;; these two instructions allow the next - sar edx,31 ;; two to pair, on the Pentium processor. - shld edx,eax,16 - sal eax,16 - idiv dword [esp+8] - ret diff --git a/src/v_video.c b/src/v_video.c index 461a5e3bc7671684f5fdcc62a8c1a728ea913a55..3f958b286cdfdcc275a23c5822605812d218c242 100644 --- a/src/v_video.c +++ b/src/v_video.c @@ -447,12 +447,6 @@ static void CV_palette_OnChange(void) V_SetPalette(0); } -#if defined (__GNUC__) && defined (__i386__) && !defined (NOASM) && !defined (__APPLE__) && !defined (NORUSEASM) -void VID_BlitLinearScreen_ASM(const UINT8 *srcptr, UINT8 *destptr, INT32 width, INT32 height, size_t srcrowbytes, - size_t destrowbytes); -#define HAVE_VIDCOPY -#endif - static void CV_constextsize_OnChange(void) { if (!con_refresh) @@ -466,9 +460,6 @@ static void CV_constextsize_OnChange(void) void VID_BlitLinearScreen(const UINT8 *srcptr, UINT8 *destptr, INT32 width, INT32 height, size_t srcrowbytes, size_t destrowbytes) { -#ifdef HAVE_VIDCOPY - VID_BlitLinearScreen_ASM(srcptr,destptr,width,height,srcrowbytes,destrowbytes); -#else if (srcrowbytes == destrowbytes) M_Memcpy(destptr, srcptr, srcrowbytes * height); else @@ -481,7 +472,6 @@ void VID_BlitLinearScreen(const UINT8 *srcptr, UINT8 *destptr, INT32 width, INT3 srcptr += srcrowbytes; } } -#endif } static UINT8 hudplusalpha[11] = { 10, 8, 6, 4, 2, 0, 0, 0, 0, 0, 0}; diff --git a/src/version.h b/src/version.h index 083c531343cf0dd0628133110d338374fde71231..3242cad672df6757e74741ca482a403f7544e31b 100644 --- a/src/version.h +++ b/src/version.h @@ -1,4 +1,4 @@ -#define SRB2VERSION "2.2.11"/* this must be the first line, for cmake !! */ +#define SRB2VERSION "2.2.13"/* this must be the first line, for cmake !! */ // The Modification ID; must be obtained from a Master Server Admin ( https://mb.srb2.org/members/?key=ms_admin ). // DO NOT try to set this otherwise, or your modification will be unplayable through the Master Server. @@ -9,7 +9,7 @@ // it's only for detection of the version the player is using so the MS can alert them of an update. // Only set it higher, not lower, obviously. // Note that we use this to help keep internal testing in check; this is why v2.2.0 is not version "1". -#define MODVERSION 52 +#define MODVERSION 54 // Define this as a prerelease version suffix (pre#, RC#) //#define BETAVERSION "pre1" diff --git a/src/vid_copy.s b/src/vid_copy.s deleted file mode 100644 index 1473a3856f192145e3739738de85bd4f6cb96222..0000000000000000000000000000000000000000 --- a/src/vid_copy.s +++ /dev/null @@ -1,61 +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 vid_copy.s -/// \brief code for updating the linear frame buffer screen. - -#include "asm_defs.inc" // structures, must match the C structures! - -// DJGPPv2 is as fast as this one, but then someone may compile with a less -// good version of DJGPP than mine, so this little asm will do the trick! - -#define srcptr 4+16 -#define destptr 8+16 -#define width 12+16 -#define height 16+16 -#define srcrowbytes 20+16 -#define destrowbytes 24+16 - -// VID_BlitLinearScreen( src, dest, width, height, srcwidth, destwidth ); -// width is given as BYTES - -#ifdef __i386__ - -.globl C(VID_BlitLinearScreen_ASM) -C(VID_BlitLinearScreen_ASM): - pushl %ebp // preserve caller's stack frame - pushl %edi - pushl %esi // preserve register variables - pushl %ebx - - cld - movl srcptr(%esp),%esi - movl destptr(%esp),%edi - movl width(%esp),%ebx - movl srcrowbytes(%esp),%eax - subl %ebx,%eax - movl destrowbytes(%esp),%edx - subl %ebx,%edx - shrl $2,%ebx - movl height(%esp),%ebp -LLRowLoop: - movl %ebx,%ecx - rep/movsl (%esi),(%edi) - addl %eax,%esi - addl %edx,%edi - decl %ebp - jnz LLRowLoop - - popl %ebx // restore register variables - popl %esi - popl %edi - popl %ebp // restore the caller's stack frame - - ret -#endif diff --git a/src/w_wad.c b/src/w_wad.c index 171eab4f31bc246281424157a3f35a047d9d8c4f..c8880f6934f0f04bbe892da599e90f487339b242 100644 --- a/src/w_wad.c +++ b/src/w_wad.c @@ -1150,6 +1150,7 @@ UINT16 W_InitFolder(const char *path, boolean mainfile, boolean startup) Z_Calloc(numlumps * sizeof (*wadfile->patchcache), PU_STATIC, &wadfile->patchcache); CONS_Printf(M_GetText("Added folder %s (%u files, %u folders)\n"), fn, numlumps, foldercount); + wadfiles = Z_Realloc(wadfiles, sizeof(wadfile_t *) * (numwadfiles + 1), PU_STATIC, NULL); wadfiles[numwadfiles] = wadfile; numwadfiles++; diff --git a/src/win32/Srb2win.rc b/src/win32/Srb2win.rc index 869c0e7d36e24a86f299d6013ec933c69a92ec4b..b699007463ad3f37527367b40e4a1c29411012ab 100644 --- a/src/win32/Srb2win.rc +++ b/src/win32/Srb2win.rc @@ -77,8 +77,8 @@ END #include "../doomdef.h" // Needed for version string VS_VERSION_INFO VERSIONINFO - FILEVERSION 2,2,11,0 - PRODUCTVERSION 2,2,11,0 + FILEVERSION 2,2,13,0 + PRODUCTVERSION 2,2,13,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L diff --git a/src/y_inter.c b/src/y_inter.c index 6e7d362a779d9f8bcfb43d7999aacaf433cb2ee1..8bec2b30f4e9314eb529defe4578daac5d0b697b 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -998,8 +998,7 @@ void Y_Ticker(void) if (paused || P_AutoPause()) return; - LUA_HookBool(intertype == int_spec && stagefailed, - HOOK(IntermissionThinker)); + LUA_HookBool(stagefailed, HOOK(IntermissionThinker)); intertic++; @@ -1477,10 +1476,10 @@ void Y_StartIntermission(void) if (players[consoleplayer].charflags & SF_SUPER) { strcpy(data.spec.passed3, "can now become"); - snprintf(data.spec.passed4, - sizeof data.spec.passed4, "Super %s", - skins[players[consoleplayer].skin].realname); - data.spec.passed4[sizeof data.spec.passed4 - 1] = '\0'; + if (strlen(skins[players[consoleplayer].skin].supername) > 20) //too long, use generic + strcpy(data.spec.passed4, "their super form"); + else + strcpy(data.spec.passed4, skins[players[consoleplayer].skin].supername); } } else @@ -2044,7 +2043,7 @@ static void Y_AwardCoopBonuses(void) y_bonus_t localbonuses[4]; // set score/total first - data.coop.total = 0; + data.coop.total = players[consoleplayer].recordscore; data.coop.score = players[consoleplayer].score; data.coop.gotperfbonus = -1; memset(data.coop.bonuses, 0, sizeof(data.coop.bonuses)); @@ -2065,6 +2064,9 @@ static void Y_AwardCoopBonuses(void) players[i].score += localbonuses[j].points; if (players[i].score > MAXSCORE) players[i].score = MAXSCORE; + players[i].recordscore += localbonuses[j].points; + if (players[i].recordscore > MAXSCORE) + players[i].recordscore = MAXSCORE; } ptlives = min( @@ -2121,6 +2123,10 @@ static void Y_AwardSpecialStageBonus(void) players[i].score += localbonuses[1].points; if (players[i].score > MAXSCORE) players[i].score = MAXSCORE; + players[i].recordscore += localbonuses[0].points; + players[i].recordscore += localbonuses[1].points; + if (players[i].recordscore > MAXSCORE) + players[i].recordscore = MAXSCORE; // grant extra lives right away since tally is faked ptlives = min( diff --git a/src/z_zone.c b/src/z_zone.c index d23c43b7b586775d2aa9bb8e5f4686bdc1313053..5750f8ae016becd9c9548b690b0e7fd5b32ec7cb 100644 --- a/src/z_zone.c +++ b/src/z_zone.c @@ -51,27 +51,11 @@ static boolean Z_calloc = false; //#define ZDEBUG2 #endif -struct memblock_s; - -typedef struct -{ - struct memblock_s *block; // Describing this memory - UINT32 id; // Should be ZONEID -} ATTRPACK memhdr_t; - -// Some code might want aligned memory. Assume it wants memory n bytes -// aligned -- then we allocate n-1 extra bytes and return a pointer to -// the first byte aligned as requested. -// Thus, "real" is the pointer we get from malloc() and will free() -// later, but "hdr" is where the memhdr_t starts. -// For non-aligned allocations they will be the same. typedef struct memblock_s { - void *real; - memhdr_t *hdr; - void **user; INT32 tag; // purgelevel + UINT32 id; // Should be ZONEID size_t size; // including the header and blocks size_t realsize; // size of real data only @@ -82,7 +66,10 @@ typedef struct memblock_s #endif struct memblock_s *next, *prev; -} ATTRPACK memblock_t; +} memblock_t; + +#define MEMORY(x) (void *)((uintptr_t)(x) + sizeof(memblock_t)) +#define MEMBLOCK(x) (memblock_t *)((uintptr_t)(x) - sizeof(memblock_t)) // both the head and tail of the zone memory block list static memblock_t head; @@ -128,64 +115,6 @@ void Z_Init(void) // Zone memory allocation // ---------------------- -/** Returns the corresponding memblock_t for a given memory block. - * - * \param ptr A pointer to allocated memory, - * assumed to have been allocated with Z_Malloc/Z_Calloc. - * \param func A string containing the name of the function that called this, - * to be printed if the function I_Errors - * \return A pointer to the memblock_t for the given memory. - * \sa Z_Free, Z_ReallocAlign - */ -#ifdef ZDEBUG -#define Ptr2Memblock(s, f) Ptr2Memblock2(s, f, __FILE__, __LINE__) -static memblock_t *Ptr2Memblock2(void *ptr, const char* func, const char *file, INT32 line) -#else -static memblock_t *Ptr2Memblock(void *ptr, const char* func) -#endif -{ - memhdr_t *hdr; - memblock_t *block; - - if (ptr == NULL) - return NULL; - -#ifdef ZDEBUG2 - CONS_Printf("%s %s:%d\n", func, file, line); -#endif - - hdr = (memhdr_t *)((UINT8 *)ptr - sizeof *hdr); - -#ifdef VALGRIND_MAKE_MEM_DEFINED - VALGRIND_MAKE_MEM_DEFINED(hdr, sizeof *hdr); -#endif - -#ifdef VALGRIND_MEMPOOL_EXISTS - if (!VALGRIND_MEMPOOL_EXISTS(hdr->block)) - { -#ifdef ZDEBUG - I_Error("%s: bad memblock from %s:%d", func, file, line); -#else - I_Error("%s: bad memblock", func); -#endif - } -#endif - if (hdr->id != ZONEID) - { -#ifdef ZDEBUG - I_Error("%s: wrong id from %s:%d", func, file, line); -#else - I_Error("%s: wrong id", func); -#endif - } - block = hdr->block; -#ifdef VALGRIND_MAKE_MEM_NOACCESS - VALGRIND_MAKE_MEM_NOACCESS(hdr, sizeof *hdr); -#endif - return block; - -} - /** Frees allocated memory. * * \param ptr A pointer to allocated memory, @@ -207,10 +136,14 @@ void Z_Free(void *ptr) CONS_Debug(DBG_MEMORY, "Z_Free %s:%d\n", file, line); #endif + block = MEMBLOCK(ptr); +#ifdef PARANOIA + if (block->id != ZONEID) #ifdef ZDEBUG - block = Ptr2Memblock2(ptr, "Z_Free", file, line); + I_Error("Z_Free at %s:%d: wrong id", file, line); #else - block = Ptr2Memblock(ptr, "Z_Free"); + I_Error("Z_Free: wrong id"); +#endif #endif #ifdef ZDEBUG @@ -229,8 +162,6 @@ void Z_Free(void *ptr) if (block->user != NULL) *block->user = NULL; - // Free the memory and get rid of the block. - free(block->real); #ifdef VALGRIND_DESTROY_MEMPOOL VALGRIND_DESTROY_MEMPOOL(block); #endif @@ -287,35 +218,17 @@ void *Z_Malloc2(size_t size, INT32 tag, void *user, INT32 alignbits, void *Z_MallocAlign(size_t size, INT32 tag, void *user, INT32 alignbits) #endif { - I_Assert(alignbits >= 0 && alignbits < (INT32)(sizeof(size_t) * 8)); - size_t extrabytes = ((size_t)1<<alignbits) - 1; - size_t padsize = 0; memblock_t *block; void *ptr; - memhdr_t *hdr; - void *given; - size_t blocksize = extrabytes + sizeof *hdr + size; + (void)(alignbits); // no longer used, so silence warnings. #ifdef ZDEBUG2 CONS_Debug(DBG_MEMORY, "Z_Malloc %s:%d\n", file, line); #endif - if (blocksize < size)/* overflow check */ - I_Error("You are allocating memory too large!"); - - block = xm(sizeof *block); -#ifdef HAVE_VALGRIND - padsize += (1<<sizeof(size_t))*2; -#endif - ptr = xm(blocksize + padsize*2); - - // This horrible calculation makes sure that "given" is aligned - // properly. - given = (void *)((size_t)((UINT8 *)ptr + extrabytes + sizeof *hdr + padsize/2) - & ~extrabytes); - - // The mem header lives 'sizeof (memhdr_t)' bytes before given. - hdr = (memhdr_t *)((UINT8 *)given - sizeof *hdr); + block = xm(sizeof (memblock_t) + size); + ptr = MEMORY(block); + I_Assert((intptr_t)ptr % sizeof (void *) == 0); #ifdef HAVE_VALGRIND Z_calloc = false; @@ -326,41 +239,31 @@ void *Z_MallocAlign(size_t size, INT32 tag, void *user, INT32 alignbits) head.next = block; block->next->prev = block; - block->real = ptr; - block->hdr = hdr; block->tag = tag; block->user = NULL; #ifdef ZDEBUG block->ownerline = line; block->ownerfile = file; #endif - block->size = blocksize; + block->size = sizeof (memblock_t) + size; block->realsize = size; #ifdef VALGRIND_CREATE_MEMPOOL - VALGRIND_CREATE_MEMPOOL(block, padsize, Z_calloc); + VALGRIND_CREATE_MEMPOOL(block, size, Z_calloc); #endif -//#ifdef VALGRIND_MEMPOOL_ALLOC -// VALGRIND_MEMPOOL_ALLOC(block, hdr, size + sizeof *hdr); -//#endif - hdr->id = ZONEID; - hdr->block = block; - -#ifdef VALGRIND_MAKE_MEM_NOACCESS - VALGRIND_MAKE_MEM_NOACCESS(hdr, sizeof *hdr); -#endif + block->id = ZONEID; if (user != NULL) { block->user = user; - *(void **)user = given; + *(void **)user = ptr; } else if (tag >= PU_PURGELEVEL) I_Error("Z_Malloc: attempted to allocate purgable block " "(size %s) with no user", sizeu1(size)); - return given; + return ptr; } /** The Z_CallocAlign function. @@ -437,10 +340,14 @@ void *Z_ReallocAlign(void *ptr, size_t size, INT32 tag, void *user, INT32 alignb #endif } + block = MEMBLOCK(ptr); +#ifdef PARANOIA + if (block->id != ZONEID) #ifdef ZDEBUG - block = Ptr2Memblock2(ptr, "Z_Realloc", file, line); + I_Error("Z_ReallocAlign at %s:%d: wrong id", file, line); #else - block = Ptr2Memblock(ptr, "Z_Realloc"); + I_Error("Z_ReallocAlign: wrong id"); +#endif #endif if (block == NULL) @@ -491,9 +398,8 @@ void Z_FreeTags(INT32 lowtag, INT32 hightag) for (block = head.next; block != &head; block = next) { next = block->next; // get link before freeing - if (block->tag >= lowtag && block->tag <= hightag) - Z_Free((UINT8 *)block->hdr + sizeof *block->hdr); + Z_Free(MEMORY(block)); } } @@ -516,7 +422,7 @@ void Z_IterateTags(INT32 lowtag, INT32 hightag, boolean (*iterfunc)(void *)) if (block->tag >= lowtag && block->tag <= hightag) { - void *mem = (UINT8 *)block->hdr + sizeof *block->hdr; + void *mem = MEMORY(block); boolean free = iterfunc(mem); if (free) Z_Free(mem); @@ -561,15 +467,13 @@ void Z_CheckMemCleanup(void) void Z_CheckHeap(INT32 i) { memblock_t *block; - memhdr_t *hdr; UINT32 blocknumon = 0; void *given; for (block = head.next; block != &head; block = block->next) { blocknumon++; - hdr = block->hdr; - given = (UINT8 *)hdr + sizeof *hdr; + given = MEMORY(block); #ifdef ZDEBUG2 CONS_Debug(DBG_MEMORY, "block %u owned by %s:%d\n", blocknumon, block->ownerfile, block->ownerline); @@ -585,7 +489,7 @@ void Z_CheckHeap(INT32 i) #ifdef ZDEBUG , block->ownerfile, block->ownerline #endif - ); + ); } #endif if (block->user != NULL && *(block->user) != given) @@ -598,7 +502,7 @@ void Z_CheckHeap(INT32 i) #ifdef ZDEBUG , block->ownerfile, block->ownerline #endif - ); + ); } if (block->next->prev != block) { @@ -610,7 +514,7 @@ void Z_CheckHeap(INT32 i) #ifdef ZDEBUG , block->ownerfile, block->ownerline #endif - ); + ); } if (block->prev->next != block) { @@ -622,25 +526,9 @@ void Z_CheckHeap(INT32 i) #ifdef ZDEBUG , block->ownerfile, block->ownerline #endif - ); + ); } -#ifdef VALGRIND_MAKE_MEM_DEFINED - VALGRIND_MAKE_MEM_DEFINED(hdr, sizeof *hdr); -#endif - if (hdr->block != block) - { - I_Error("Z_CheckHeap %d: block %u" -#ifdef ZDEBUG - "(owned by %s:%d)" -#endif - " doesn't have linkback from allocated memory", - i, blocknumon -#ifdef ZDEBUG - , block->ownerfile, block->ownerline -#endif - ); - } - if (hdr->id != ZONEID) + if (block->id != ZONEID) { I_Error("Z_CheckHeap %d: block %u" #ifdef ZDEBUG @@ -650,11 +538,8 @@ void Z_CheckHeap(INT32 i) #ifdef ZDEBUG , block->ownerfile, block->ownerline #endif - ); + ); } -#ifdef VALGRIND_MAKE_MEM_NOACCESS - VALGRIND_MAKE_MEM_NOACCESS(hdr, sizeof *hdr); -#endif } } @@ -676,35 +561,14 @@ void Z_ChangeTag(void *ptr, INT32 tag) #endif { memblock_t *block; - memhdr_t *hdr; if (ptr == NULL) return; - hdr = (memhdr_t *)((UINT8 *)ptr - sizeof *hdr); - -#ifdef VALGRIND_MAKE_MEM_DEFINED - VALGRIND_MAKE_MEM_DEFINED(hdr, sizeof *hdr); -#endif + block = MEMBLOCK(ptr); -#ifdef VALGRIND_MEMPOOL_EXISTS - if (!VALGRIND_MEMPOOL_EXISTS(hdr->block)) - { -#ifdef PARANOIA - I_Error("Z_CT at %s:%d: bad memblock", file, line); -#else - I_Error("Z_CT: bad memblock"); -#endif - } -#endif #ifdef PARANOIA - if (hdr->id != ZONEID) I_Error("Z_CT at %s:%d: wrong id", file, line); -#endif - - block = hdr->block; - -#ifdef VALGRIND_MAKE_MEM_NOACCESS - VALGRIND_MAKE_MEM_NOACCESS(hdr, sizeof *hdr); + if (block->id != ZONEID) I_Error("Z_ChangeTag at %s:%d: wrong id", file, line); #endif if (tag >= PU_PURGELEVEL && block->user == NULL) @@ -728,25 +592,14 @@ void Z_SetUser(void *ptr, void **newuser) #endif { memblock_t *block; - memhdr_t *hdr; if (ptr == NULL) return; - hdr = (memhdr_t *)((UINT8 *)ptr - sizeof *hdr); - -#ifdef VALGRIND_MAKE_MEM_DEFINED - VALGRIND_MAKE_MEM_DEFINED(hdr, sizeof *hdr); -#endif + block = MEMBLOCK(ptr); #ifdef PARANOIA - if (hdr->id != ZONEID) I_Error("Z_CT at %s:%d: wrong id", file, line); -#endif - - block = hdr->block; - -#ifdef VALGRIND_MAKE_MEM_NOACCESS - VALGRIND_MAKE_MEM_NOACCESS(hdr, sizeof *hdr); + if (block->id != ZONEID) I_Error("Z_SetUser at %s:%d: wrong id", file, line); #endif if (block->tag >= PU_PURGELEVEL && newuser == NULL) diff --git a/src/z_zone.h b/src/z_zone.h index f00f57749407c053dabc119a81c5b9c4a8ed07e7..ce7af4a159555e3a6c2be83e8d0eadcf8a7a69eb 100644 --- a/src/z_zone.h +++ b/src/z_zone.h @@ -15,6 +15,7 @@ #define __Z_ZONE__ #include <stdio.h> +#include "doomdef.h" #include "doomtype.h" #ifdef __GNUC__ // __attribute__ ((X)) diff --git a/thirdparty/CMakeLists.txt b/thirdparty/CMakeLists.txt index 7aff16601efd49d71693a137a4aab7b98721e7fa..f33b3bf3f836b86b98fda8e78f73ec5be19758d8 100644 --- a/thirdparty/CMakeLists.txt +++ b/thirdparty/CMakeLists.txt @@ -9,521 +9,13 @@ else() set(NOT_SRB2_CONFIG_SHARED_INTERNAL_LIBRARIES ON) endif() - -if(NOT "${SRB2_CONFIG_SYSTEM_LIBRARIES}") - CPMAddPackage( - NAME SDL2 - VERSION 2.24.2 - URL "https://github.com/libsdl-org/SDL/archive/refs/tags/release-2.24.2.zip" - EXCLUDE_FROM_ALL ON - OPTIONS - "BUILD_SHARED_LIBS ${SRB2_CONFIG_SHARED_INTERNAL_LIBRARIES}" - "SDL_SHARED ${SRB2_CONFIG_SHARED_INTERNAL_LIBRARIES}" - "SDL_STATIC ${NOT_SRB2_CONFIG_SHARED_INTERNAL_LIBRARIES}" - "SDL_TEST OFF" - "SDL2_DISABLE_SDL2MAIN ON" - "SDL2_DISABLE_INSTALL ON" - ) -endif() - -if(NOT "${SRB2_CONFIG_SYSTEM_LIBRARIES}") - CPMAddPackage( - NAME SDL2_mixer - VERSION 2.6.2 - URL "https://github.com/libsdl-org/SDL_mixer/archive/refs/tags/release-2.6.2.zip" - EXCLUDE_FROM_ALL ON - OPTIONS - "BUILD_SHARED_LIBS ${SRB2_CONFIG_SHARED_INTERNAL_LIBRARIES}" - "SDL2MIXER_INSTALL OFF" - "SDL2MIXER_DEPS_SHARED OFF" - "SDL2MIXER_SAMPLES OFF" - "SDL2MIXER_VENDORED ON" - "SDL2MIXER_FLAC ON" - "SDL2MIXER_FLAC_LIBFLAC OFF" - "SDL2MIXER_FLAC_DRFLAC ON" - "SDL2MIXER_MOD OFF" - "SDL2MIXER_MP3 ON" - "SDL2MIXER_MP3_DRMP3 ON" - "SDL2MIXER_MIDI ON" - "SDL2MIXER_OPUS OFF" - "SDL2MIXER_VORBIS STB" - "SDL2MIXER_WAVE ON" - ) -endif() - -if(NOT "${SRB2_CONFIG_SYSTEM_LIBRARIES}") - CPMAddPackage( - NAME ZLIB - VERSION 1.2.13 - URL "https://github.com/madler/zlib/archive/refs/tags/v1.2.13.zip" - EXCLUDE_FROM_ALL - DOWNLOAD_ONLY YES - ) - if(ZLIB_ADDED) - set(ZLIB_SRCS - crc32.h - deflate.h - gzguts.h - inffast.h - inffixed.h - inflate.h - inftrees.h - trees.h - zutil.h - - adler32.c - compress.c - crc32.c - deflate.c - gzclose.c - gzlib.c - gzread.c - gzwrite.c - inflate.c - infback.c - inftrees.c - inffast.c - trees.c - uncompr.c - zutil.c - ) - list(TRANSFORM ZLIB_SRCS PREPEND "${ZLIB_SOURCE_DIR}/") - - configure_file("${ZLIB_SOURCE_DIR}/zlib.pc.cmakein" "${ZLIB_BINARY_DIR}/zlib.pc" @ONLY) - configure_file("${ZLIB_SOURCE_DIR}/zconf.h.cmakein" "${ZLIB_BINARY_DIR}/include/zconf.h" @ONLY) - configure_file("${ZLIB_SOURCE_DIR}/zlib.h" "${ZLIB_BINARY_DIR}/include/zlib.h" @ONLY) - - add_library(ZLIB ${SRB2_INTERNAL_LIBRARY_TYPE} ${ZLIB_SRCS}) - set_target_properties(ZLIB PROPERTIES - VERSION 1.2.13 - OUTPUT_NAME "z" - ) - target_include_directories(ZLIB PRIVATE "${ZLIB_SOURCE_DIR}") - target_include_directories(ZLIB PUBLIC "${ZLIB_BINARY_DIR}/include") - if(MSVC) - target_compile_definitions(ZLIB PRIVATE -D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE) - endif() - add_library(ZLIB::ZLIB ALIAS ZLIB) - endif() -endif() - if(NOT "${SRB2_CONFIG_SYSTEM_LIBRARIES}") - CPMAddPackage( - NAME png - VERSION 1.6.38 - URL "https://github.com/glennrp/libpng/archive/refs/tags/v1.6.38.zip" - # png cmake build is broken on msys/mingw32 - DOWNLOAD_ONLY YES - ) - - if(png_ADDED) - # Since png's cmake build is broken, we're going to create a target manually - set( - PNG_SOURCES - - png.h - pngconf.h - - pngpriv.h - pngdebug.h - pnginfo.h - pngstruct.h - - png.c - pngerror.c - pngget.c - pngmem.c - pngpread.c - pngread.c - pngrio.c - pngrtran.c - pngrutil.c - pngset.c - pngtrans.c - pngwio.c - pngwrite.c - pngwtran.c - pngwutil.c - ) - list(TRANSFORM PNG_SOURCES PREPEND "${png_SOURCE_DIR}/") - - add_custom_command( - OUTPUT "${png_BINARY_DIR}/include/png.h" "${png_BINARY_DIR}/include/pngconf.h" - COMMAND ${CMAKE_COMMAND} -E copy "${png_SOURCE_DIR}/png.h" "${png_SOURCE_DIR}/pngconf.h" "${png_BINARY_DIR}/include" - DEPENDS "${png_SOURCE_DIR}/png.h" "${png_SOURCE_DIR}/pngconf.h" - VERBATIM - ) - add_custom_command( - OUTPUT "${png_BINARY_DIR}/include/pnglibconf.h" - COMMAND ${CMAKE_COMMAND} -E copy "${png_SOURCE_DIR}/scripts/pnglibconf.h.prebuilt" "${png_BINARY_DIR}/include/pnglibconf.h" - DEPENDS "${png_SOURCE_DIR}/scripts/pnglibconf.h.prebuilt" - VERBATIM - ) - list( - APPEND PNG_SOURCES - "${png_BINARY_DIR}/include/png.h" - "${png_BINARY_DIR}/include/pngconf.h" - "${png_BINARY_DIR}/include/pnglibconf.h" - ) - add_library(png "${SRB2_INTERNAL_LIBRARY_TYPE}" ${PNG_SOURCES}) - - # Disable ARM NEON since having it automatic breaks libpng external build on clang for some reason - target_compile_definitions(png PRIVATE -DPNG_ARM_NEON_OPT=0) - - # The png includes need to be available to consumers - target_include_directories(png PUBLIC "${png_BINARY_DIR}/include") - - # ... and these also need to be present only for png build - target_include_directories(png PRIVATE "${ZLIB_SOURCE_DIR}") - target_include_directories(png PRIVATE "${ZLIB_BINARY_DIR}") - target_include_directories(png PRIVATE "${png_BINARY_DIR}") - - target_link_libraries(png PRIVATE ZLIB::ZLIB) - add_library(PNG::PNG ALIAS png) - endif() + include("cpm-sdl2.cmake") + include("cpm-sdl2-mixer.cmake") + include("cpm-zlib.cmake") + include("cpm-png.cmake") + include("cpm-curl.cmake") + include("cpm-openmpt.cmake") endif() -if(NOT "${SRB2_CONFIG_SYSTEM_LIBRARIES}") - set( - internal_curl_options - - "BUILD_CURL_EXE OFF" - "BUILD_SHARED_LIBS ${SRB2_CONFIG_SHARED_INTERNAL_LIBRARIES}" - "CURL_DISABLE_TESTS ON" - "HTTP_ONLY ON" - "CURL_DISABLE_CRYPTO_AUTH ON" - "CURL_DISABLE_NTLM ON" - "ENABLE_MANUAL OFF" - "ENABLE_THREADED_RESOLVER OFF" - "CURL_USE_LIBPSL OFF" - "CURL_USE_LIBSSH2 OFF" - "USE_LIBIDN2 OFF" - "CURL_ENABLE_EXPORT_TARGET OFF" - ) - if(${CMAKE_SYSTEM} MATCHES Windows) - list(APPEND internal_curl_options "CURL_USE_OPENSSL OFF") - list(APPEND internal_curl_options "CURL_USE_SCHANNEL ON") - endif() - if(${CMAKE_SYSTEM} MATCHES Darwin) - list(APPEND internal_curl_options "CURL_USE_OPENSSL OFF") - list(APPEND internal_curl_options "CURL_USE_SECTRANSP ON") - endif() - if(${CMAKE_SYSTEM} MATCHES Linux) - list(APPEND internal_curl_options "CURL_USE_OPENSSL ON") - endif() - - CPMAddPackage( - NAME curl - VERSION 7.86.0 - URL "https://github.com/curl/curl/archive/refs/tags/curl-7_86_0.zip" - EXCLUDE_FROM_ALL ON - OPTIONS ${internal_curl_options} - ) -endif() - -if(NOT "${SRB2_CONFIG_SYSTEM_LIBRARIES}") - CPMAddPackage( - NAME openmpt - VERSION 0.4.30 - URL "https://github.com/OpenMPT/openmpt/archive/refs/tags/libopenmpt-0.4.30.zip" - DOWNLOAD_ONLY ON - ) - - if(openmpt_ADDED) - set( - openmpt_SOURCES - - # minimp3 - # -DMPT_WITH_MINIMP3 - include/minimp3/minimp3.c - - common/mptStringParse.cpp - common/mptLibrary.cpp - common/Logging.cpp - common/Profiler.cpp - common/version.cpp - common/mptCPU.cpp - common/ComponentManager.cpp - common/mptOS.cpp - common/serialization_utils.cpp - common/mptStringFormat.cpp - common/FileReader.cpp - common/mptWine.cpp - common/mptPathString.cpp - common/mptAlloc.cpp - common/mptUUID.cpp - common/mptTime.cpp - common/mptString.cpp - common/mptFileIO.cpp - common/mptStringBuffer.cpp - common/mptRandom.cpp - common/mptIO.cpp - common/misc_util.cpp - - common/mptCRC.h - common/mptLibrary.h - common/mptIO.h - common/version.h - common/stdafx.h - common/ComponentManager.h - common/Endianness.h - common/mptStringFormat.h - common/mptMutex.h - common/mptUUID.h - common/mptExceptionText.h - common/BuildSettings.h - common/mptAlloc.h - common/mptTime.h - common/FileReaderFwd.h - common/Logging.h - common/mptException.h - common/mptWine.h - common/mptStringBuffer.h - common/misc_util.h - common/mptBaseMacros.h - common/mptMemory.h - common/mptFileIO.h - common/serialization_utils.h - common/mptSpan.h - common/mptThread.h - common/FlagSet.h - common/mptString.h - common/mptStringParse.h - common/mptBaseUtils.h - common/mptRandom.h - common/CompilerDetect.h - common/FileReader.h - common/mptAssert.h - common/mptPathString.h - common/Profiler.h - common/mptOS.h - common/mptBaseTypes.h - common/mptCPU.h - common/mptBufferIO.h - common/versionNumber.h - - soundlib/WAVTools.cpp - soundlib/ITTools.cpp - soundlib/AudioCriticalSection.cpp - soundlib/Load_stm.cpp - soundlib/MixerLoops.cpp - soundlib/Load_dbm.cpp - soundlib/ModChannel.cpp - soundlib/Load_gdm.cpp - soundlib/Snd_fx.cpp - soundlib/Load_mid.cpp - soundlib/mod_specifications.cpp - soundlib/Snd_flt.cpp - soundlib/Load_psm.cpp - soundlib/Load_far.cpp - soundlib/patternContainer.cpp - soundlib/Load_med.cpp - soundlib/Load_dmf.cpp - soundlib/Paula.cpp - soundlib/modcommand.cpp - soundlib/Message.cpp - soundlib/SoundFilePlayConfig.cpp - soundlib/Load_uax.cpp - soundlib/plugins/PlugInterface.cpp - soundlib/plugins/LFOPlugin.cpp - soundlib/plugins/PluginManager.cpp - soundlib/plugins/DigiBoosterEcho.cpp - soundlib/plugins/dmo/DMOPlugin.cpp - soundlib/plugins/dmo/Flanger.cpp - soundlib/plugins/dmo/Distortion.cpp - soundlib/plugins/dmo/ParamEq.cpp - soundlib/plugins/dmo/Gargle.cpp - soundlib/plugins/dmo/I3DL2Reverb.cpp - soundlib/plugins/dmo/Compressor.cpp - soundlib/plugins/dmo/WavesReverb.cpp - soundlib/plugins/dmo/Echo.cpp - soundlib/plugins/dmo/Chorus.cpp - soundlib/Load_ams.cpp - soundlib/tuningbase.cpp - soundlib/ContainerUMX.cpp - soundlib/Load_ptm.cpp - soundlib/ContainerXPK.cpp - soundlib/SampleFormatMP3.cpp - soundlib/tuning.cpp - soundlib/Sndfile.cpp - soundlib/ContainerMMCMP.cpp - soundlib/Load_amf.cpp - soundlib/Load_669.cpp - soundlib/modsmp_ctrl.cpp - soundlib/Load_mtm.cpp - soundlib/OggStream.cpp - soundlib/Load_plm.cpp - soundlib/Tables.cpp - soundlib/Load_c67.cpp - soundlib/Load_mod.cpp - soundlib/Load_sfx.cpp - soundlib/Sndmix.cpp - soundlib/load_j2b.cpp - soundlib/ModSequence.cpp - soundlib/SampleFormatFLAC.cpp - soundlib/ModInstrument.cpp - soundlib/Load_mo3.cpp - soundlib/ModSample.cpp - soundlib/Dlsbank.cpp - soundlib/Load_itp.cpp - soundlib/UpgradeModule.cpp - soundlib/MIDIMacros.cpp - soundlib/ContainerPP20.cpp - soundlib/RowVisitor.cpp - soundlib/Load_imf.cpp - soundlib/SampleFormatVorbis.cpp - soundlib/Load_dsm.cpp - soundlib/Load_mt2.cpp - soundlib/MixerSettings.cpp - soundlib/S3MTools.cpp - soundlib/Load_xm.cpp - soundlib/MIDIEvents.cpp - soundlib/pattern.cpp - soundlib/Load_digi.cpp - soundlib/Load_s3m.cpp - soundlib/tuningCollection.cpp - soundlib/SampleIO.cpp - soundlib/Dither.cpp - soundlib/Load_mdl.cpp - soundlib/OPL.cpp - soundlib/WindowedFIR.cpp - soundlib/SampleFormats.cpp - soundlib/Load_wav.cpp - soundlib/Load_it.cpp - soundlib/UMXTools.cpp - soundlib/Load_stp.cpp - soundlib/Load_okt.cpp - soundlib/Load_ult.cpp - soundlib/MixFuncTable.cpp - soundlib/SampleFormatOpus.cpp - soundlib/Fastmix.cpp - soundlib/Tagging.cpp - soundlib/ITCompression.cpp - soundlib/Load_dtm.cpp - soundlib/MPEGFrame.cpp - soundlib/XMTools.cpp - soundlib/SampleFormatMediaFoundation.cpp - soundlib/InstrumentExtensions.cpp - - soundlib/MixerInterface.h - soundlib/SoundFilePlayConfig.h - soundlib/ModSample.h - soundlib/MIDIEvents.h - soundlib/ModSampleCopy.h - soundlib/patternContainer.h - soundlib/ChunkReader.h - soundlib/ITCompression.h - soundlib/Dither.h - soundlib/S3MTools.h - soundlib/MPEGFrame.h - soundlib/WAVTools.h - soundlib/mod_specifications.h - soundlib/ITTools.h - soundlib/RowVisitor.h - soundlib/plugins/PluginMixBuffer.h - soundlib/plugins/PluginStructs.h - soundlib/plugins/LFOPlugin.h - soundlib/plugins/PlugInterface.h - soundlib/plugins/DigiBoosterEcho.h - soundlib/plugins/OpCodes.h - soundlib/plugins/dmo/Echo.h - soundlib/plugins/dmo/I3DL2Reverb.h - soundlib/plugins/dmo/WavesReverb.h - soundlib/plugins/dmo/ParamEq.h - soundlib/plugins/dmo/Gargle.h - soundlib/plugins/dmo/DMOPlugin.h - soundlib/plugins/dmo/Chorus.h - soundlib/plugins/dmo/Compressor.h - soundlib/plugins/dmo/Distortion.h - soundlib/plugins/dmo/Flanger.h - soundlib/plugins/PluginManager.h - soundlib/SampleIO.h - soundlib/Container.h - soundlib/ModSequence.h - soundlib/UMXTools.h - soundlib/Message.h - soundlib/modcommand.h - soundlib/XMTools.h - soundlib/Snd_defs.h - soundlib/MixFuncTable.h - soundlib/pattern.h - soundlib/modsmp_ctrl.h - soundlib/Tagging.h - soundlib/tuningcollection.h - soundlib/Mixer.h - soundlib/FloatMixer.h - soundlib/AudioCriticalSection.h - soundlib/Tables.h - soundlib/tuningbase.h - soundlib/WindowedFIR.h - soundlib/Sndfile.h - soundlib/Paula.h - soundlib/ModInstrument.h - soundlib/Dlsbank.h - soundlib/IntMixer.h - soundlib/OPL.h - soundlib/Resampler.h - soundlib/ModChannel.h - soundlib/MixerSettings.h - soundlib/AudioReadTarget.h - soundlib/MixerLoops.h - soundlib/tuning.h - soundlib/MIDIMacros.h - soundlib/OggStream.h - soundlib/Loaders.h - soundlib/BitReader.h - soundlib/opal.h - - sounddsp/AGC.cpp - sounddsp/EQ.cpp - sounddsp/DSP.cpp - sounddsp/Reverb.cpp - sounddsp/Reverb.h - sounddsp/EQ.h - sounddsp/DSP.h - sounddsp/AGC.h - - libopenmpt/libopenmpt_c.cpp - libopenmpt/libopenmpt_cxx.cpp - libopenmpt/libopenmpt_impl.cpp - libopenmpt/libopenmpt_ext_impl.cpp - ) - list(TRANSFORM openmpt_SOURCES PREPEND "${openmpt_SOURCE_DIR}/") - - # -DLIBOPENMPT_BUILD - configure_file("openmpt_svn_version.h" "svn_version.h") - add_library(openmpt "${SRB2_INTERNAL_LIBRARY_TYPE}" ${openmpt_SOURCES} ${CMAKE_CURRENT_BINARY_DIR}/svn_version.h) - if("${CMAKE_C_COMPILER_ID}" STREQUAL GNU OR "${CMAKE_C_COMPILER_ID}" STREQUAL Clang OR "${CMAKE_C_COMPILER_ID}" STREQUAL AppleClang) - target_compile_options(openmpt PRIVATE "-g0") - endif() - if("${CMAKE_SYSTEM_NAME}" STREQUAL Windows AND "${CMAKE_C_COMPILER_ID}" STREQUAL MSVC) - target_link_libraries(openmpt PRIVATE Rpcrt4) - endif() - target_compile_features(openmpt PRIVATE cxx_std_11) - target_compile_definitions(openmpt PRIVATE -DLIBOPENMPT_BUILD) - - target_include_directories(openmpt PRIVATE "${openmpt_SOURCE_DIR}/common") - target_include_directories(openmpt PRIVATE "${openmpt_SOURCE_DIR}/src") - target_include_directories(openmpt PRIVATE "${openmpt_SOURCE_DIR}/include") - target_include_directories(openmpt PRIVATE "${openmpt_SOURCE_DIR}") - target_include_directories(openmpt PRIVATE "${CMAKE_CURRENT_BINARY_DIR}") - - # I wish this wasn't necessary, but it is - target_include_directories(openmpt PUBLIC "${openmpt_SOURCE_DIR}") - endif() -endif() - -if(NOT "${SRB2_CONFIG_SYSTEM_LIBRARIES}") - CPMAddPackage( - NAME libgme - VERSION 0.6.3 - URL "https://bitbucket.org/mpyne/game-music-emu/get/e76bdc0cb916e79aa540290e6edd0c445879d3ba.zip" - EXCLUDE_FROM_ALL ON - OPTIONS - "BUILD_SHARED_LIBS ${SRB2_CONFIG_SHARED_INTERNAL_LIBRARIES}" - "ENABLE_UBSAN OFF" - "GME_YM2612_EMU MAME" - ) - target_compile_features(gme PRIVATE cxx_std_11) - target_link_libraries(gme PRIVATE ZLIB::ZLIB) -endif() +include("cpm-libgme.cmake") diff --git a/thirdparty/cpm-curl.cmake b/thirdparty/cpm-curl.cmake new file mode 100644 index 0000000000000000000000000000000000000000..3d8c6e61d46dee6f06f4e6d69beb09d1605f6584 --- /dev/null +++ b/thirdparty/cpm-curl.cmake @@ -0,0 +1,35 @@ +set( + internal_curl_options + + "BUILD_CURL_EXE OFF" + "BUILD_SHARED_LIBS ${SRB2_CONFIG_SHARED_INTERNAL_LIBRARIES}" + "CURL_DISABLE_TESTS ON" + "HTTP_ONLY ON" + "CURL_DISABLE_CRYPTO_AUTH ON" + "CURL_DISABLE_NTLM ON" + "ENABLE_MANUAL OFF" + "ENABLE_THREADED_RESOLVER OFF" + "CURL_USE_LIBPSL OFF" + "CURL_USE_LIBSSH2 OFF" + "USE_LIBIDN2 OFF" + "CURL_ENABLE_EXPORT_TARGET OFF" +) +if(${CMAKE_SYSTEM} MATCHES Windows) + list(APPEND internal_curl_options "CURL_USE_OPENSSL OFF") + list(APPEND internal_curl_options "CURL_USE_SCHANNEL ON") +endif() +if(${CMAKE_SYSTEM} MATCHES Darwin) + list(APPEND internal_curl_options "CURL_USE_OPENSSL OFF") + list(APPEND internal_curl_options "CURL_USE_SECTRANSP ON") +endif() +if(${CMAKE_SYSTEM} MATCHES Linux) + list(APPEND internal_curl_options "CURL_USE_OPENSSL ON") +endif() + +CPMAddPackage( + NAME curl + VERSION 7.86.0 + URL "https://github.com/curl/curl/archive/refs/tags/curl-7_86_0.zip" + EXCLUDE_FROM_ALL ON + OPTIONS ${internal_curl_options} +) diff --git a/thirdparty/cpm-libgme.cmake b/thirdparty/cpm-libgme.cmake new file mode 100644 index 0000000000000000000000000000000000000000..f15bc3b31cb23ed7663ed950c14c1d6a0dc36567 --- /dev/null +++ b/thirdparty/cpm-libgme.cmake @@ -0,0 +1,16 @@ +CPMAddPackage( + NAME libgme + VERSION 0.6.3 + URL "https://bitbucket.org/mpyne/game-music-emu/get/e76bdc0cb916e79aa540290e6edd0c445879d3ba.zip" + EXCLUDE_FROM_ALL ON + OPTIONS + "BUILD_SHARED_LIBS ${SRB2_CONFIG_SHARED_INTERNAL_LIBRARIES}" + "ENABLE_UBSAN OFF" + "GME_YM2612_EMU MAME" +) + +if(libgme_ADDED) + target_compile_features(gme PRIVATE cxx_std_11) + # libgme's CMakeLists.txt already links this + #target_link_libraries(gme PRIVATE ZLIB::ZLIB) +endif() diff --git a/thirdparty/cpm-openmpt.cmake b/thirdparty/cpm-openmpt.cmake new file mode 100644 index 0000000000000000000000000000000000000000..01f7ff75f64d915799e432f2923a2c7e8c344466 --- /dev/null +++ b/thirdparty/cpm-openmpt.cmake @@ -0,0 +1,289 @@ +CPMAddPackage( + NAME openmpt + VERSION 0.4.30 + URL "https://github.com/OpenMPT/openmpt/archive/refs/tags/libopenmpt-0.4.30.zip" + DOWNLOAD_ONLY ON +) + +if(openmpt_ADDED) + set( + openmpt_SOURCES + + # minimp3 + # -DMPT_WITH_MINIMP3 + include/minimp3/minimp3.c + + common/mptStringParse.cpp + common/mptLibrary.cpp + common/Logging.cpp + common/Profiler.cpp + common/version.cpp + common/mptCPU.cpp + common/ComponentManager.cpp + common/mptOS.cpp + common/serialization_utils.cpp + common/mptStringFormat.cpp + common/FileReader.cpp + common/mptWine.cpp + common/mptPathString.cpp + common/mptAlloc.cpp + common/mptUUID.cpp + common/mptTime.cpp + common/mptString.cpp + common/mptFileIO.cpp + common/mptStringBuffer.cpp + common/mptRandom.cpp + common/mptIO.cpp + common/misc_util.cpp + + common/mptCRC.h + common/mptLibrary.h + common/mptIO.h + common/version.h + common/stdafx.h + common/ComponentManager.h + common/Endianness.h + common/mptStringFormat.h + common/mptMutex.h + common/mptUUID.h + common/mptExceptionText.h + common/BuildSettings.h + common/mptAlloc.h + common/mptTime.h + common/FileReaderFwd.h + common/Logging.h + common/mptException.h + common/mptWine.h + common/mptStringBuffer.h + common/misc_util.h + common/mptBaseMacros.h + common/mptMemory.h + common/mptFileIO.h + common/serialization_utils.h + common/mptSpan.h + common/mptThread.h + common/FlagSet.h + common/mptString.h + common/mptStringParse.h + common/mptBaseUtils.h + common/mptRandom.h + common/CompilerDetect.h + common/FileReader.h + common/mptAssert.h + common/mptPathString.h + common/Profiler.h + common/mptOS.h + common/mptBaseTypes.h + common/mptCPU.h + common/mptBufferIO.h + common/versionNumber.h + + soundlib/WAVTools.cpp + soundlib/ITTools.cpp + soundlib/AudioCriticalSection.cpp + soundlib/Load_stm.cpp + soundlib/MixerLoops.cpp + soundlib/Load_dbm.cpp + soundlib/ModChannel.cpp + soundlib/Load_gdm.cpp + soundlib/Snd_fx.cpp + soundlib/Load_mid.cpp + soundlib/mod_specifications.cpp + soundlib/Snd_flt.cpp + soundlib/Load_psm.cpp + soundlib/Load_far.cpp + soundlib/patternContainer.cpp + soundlib/Load_med.cpp + soundlib/Load_dmf.cpp + soundlib/Paula.cpp + soundlib/modcommand.cpp + soundlib/Message.cpp + soundlib/SoundFilePlayConfig.cpp + soundlib/Load_uax.cpp + soundlib/plugins/PlugInterface.cpp + soundlib/plugins/LFOPlugin.cpp + soundlib/plugins/PluginManager.cpp + soundlib/plugins/DigiBoosterEcho.cpp + soundlib/plugins/dmo/DMOPlugin.cpp + soundlib/plugins/dmo/Flanger.cpp + soundlib/plugins/dmo/Distortion.cpp + soundlib/plugins/dmo/ParamEq.cpp + soundlib/plugins/dmo/Gargle.cpp + soundlib/plugins/dmo/I3DL2Reverb.cpp + soundlib/plugins/dmo/Compressor.cpp + soundlib/plugins/dmo/WavesReverb.cpp + soundlib/plugins/dmo/Echo.cpp + soundlib/plugins/dmo/Chorus.cpp + soundlib/Load_ams.cpp + soundlib/tuningbase.cpp + soundlib/ContainerUMX.cpp + soundlib/Load_ptm.cpp + soundlib/ContainerXPK.cpp + soundlib/SampleFormatMP3.cpp + soundlib/tuning.cpp + soundlib/Sndfile.cpp + soundlib/ContainerMMCMP.cpp + soundlib/Load_amf.cpp + soundlib/Load_669.cpp + soundlib/modsmp_ctrl.cpp + soundlib/Load_mtm.cpp + soundlib/OggStream.cpp + soundlib/Load_plm.cpp + soundlib/Tables.cpp + soundlib/Load_c67.cpp + soundlib/Load_mod.cpp + soundlib/Load_sfx.cpp + soundlib/Sndmix.cpp + soundlib/load_j2b.cpp + soundlib/ModSequence.cpp + soundlib/SampleFormatFLAC.cpp + soundlib/ModInstrument.cpp + soundlib/Load_mo3.cpp + soundlib/ModSample.cpp + soundlib/Dlsbank.cpp + soundlib/Load_itp.cpp + soundlib/UpgradeModule.cpp + soundlib/MIDIMacros.cpp + soundlib/ContainerPP20.cpp + soundlib/RowVisitor.cpp + soundlib/Load_imf.cpp + soundlib/SampleFormatVorbis.cpp + soundlib/Load_dsm.cpp + soundlib/Load_mt2.cpp + soundlib/MixerSettings.cpp + soundlib/S3MTools.cpp + soundlib/Load_xm.cpp + soundlib/MIDIEvents.cpp + soundlib/pattern.cpp + soundlib/Load_digi.cpp + soundlib/Load_s3m.cpp + soundlib/tuningCollection.cpp + soundlib/SampleIO.cpp + soundlib/Dither.cpp + soundlib/Load_mdl.cpp + soundlib/OPL.cpp + soundlib/WindowedFIR.cpp + soundlib/SampleFormats.cpp + soundlib/Load_wav.cpp + soundlib/Load_it.cpp + soundlib/UMXTools.cpp + soundlib/Load_stp.cpp + soundlib/Load_okt.cpp + soundlib/Load_ult.cpp + soundlib/MixFuncTable.cpp + soundlib/SampleFormatOpus.cpp + soundlib/Fastmix.cpp + soundlib/Tagging.cpp + soundlib/ITCompression.cpp + soundlib/Load_dtm.cpp + soundlib/MPEGFrame.cpp + soundlib/XMTools.cpp + soundlib/SampleFormatMediaFoundation.cpp + soundlib/InstrumentExtensions.cpp + + soundlib/MixerInterface.h + soundlib/SoundFilePlayConfig.h + soundlib/ModSample.h + soundlib/MIDIEvents.h + soundlib/ModSampleCopy.h + soundlib/patternContainer.h + soundlib/ChunkReader.h + soundlib/ITCompression.h + soundlib/Dither.h + soundlib/S3MTools.h + soundlib/MPEGFrame.h + soundlib/WAVTools.h + soundlib/mod_specifications.h + soundlib/ITTools.h + soundlib/RowVisitor.h + soundlib/plugins/PluginMixBuffer.h + soundlib/plugins/PluginStructs.h + soundlib/plugins/LFOPlugin.h + soundlib/plugins/PlugInterface.h + soundlib/plugins/DigiBoosterEcho.h + soundlib/plugins/OpCodes.h + soundlib/plugins/dmo/Echo.h + soundlib/plugins/dmo/I3DL2Reverb.h + soundlib/plugins/dmo/WavesReverb.h + soundlib/plugins/dmo/ParamEq.h + soundlib/plugins/dmo/Gargle.h + soundlib/plugins/dmo/DMOPlugin.h + soundlib/plugins/dmo/Chorus.h + soundlib/plugins/dmo/Compressor.h + soundlib/plugins/dmo/Distortion.h + soundlib/plugins/dmo/Flanger.h + soundlib/plugins/PluginManager.h + soundlib/SampleIO.h + soundlib/Container.h + soundlib/ModSequence.h + soundlib/UMXTools.h + soundlib/Message.h + soundlib/modcommand.h + soundlib/XMTools.h + soundlib/Snd_defs.h + soundlib/MixFuncTable.h + soundlib/pattern.h + soundlib/modsmp_ctrl.h + soundlib/Tagging.h + soundlib/tuningcollection.h + soundlib/Mixer.h + soundlib/FloatMixer.h + soundlib/AudioCriticalSection.h + soundlib/Tables.h + soundlib/tuningbase.h + soundlib/WindowedFIR.h + soundlib/Sndfile.h + soundlib/Paula.h + soundlib/ModInstrument.h + soundlib/Dlsbank.h + soundlib/IntMixer.h + soundlib/OPL.h + soundlib/Resampler.h + soundlib/ModChannel.h + soundlib/MixerSettings.h + soundlib/AudioReadTarget.h + soundlib/MixerLoops.h + soundlib/tuning.h + soundlib/MIDIMacros.h + soundlib/OggStream.h + soundlib/Loaders.h + soundlib/BitReader.h + soundlib/opal.h + + sounddsp/AGC.cpp + sounddsp/EQ.cpp + sounddsp/DSP.cpp + sounddsp/Reverb.cpp + sounddsp/Reverb.h + sounddsp/EQ.h + sounddsp/DSP.h + sounddsp/AGC.h + + libopenmpt/libopenmpt_c.cpp + libopenmpt/libopenmpt_cxx.cpp + libopenmpt/libopenmpt_impl.cpp + libopenmpt/libopenmpt_ext_impl.cpp + ) + list(TRANSFORM openmpt_SOURCES PREPEND "${openmpt_SOURCE_DIR}/") + + # -DLIBOPENMPT_BUILD + configure_file("openmpt_svn_version.h" "svn_version.h") + add_library(openmpt "${SRB2_INTERNAL_LIBRARY_TYPE}" ${openmpt_SOURCES} ${CMAKE_CURRENT_BINARY_DIR}/svn_version.h) + if("${CMAKE_C_COMPILER_ID}" STREQUAL GNU OR "${CMAKE_C_COMPILER_ID}" STREQUAL Clang OR "${CMAKE_C_COMPILER_ID}" STREQUAL AppleClang) + target_compile_options(openmpt PRIVATE "-g0") + endif() + if("${CMAKE_SYSTEM_NAME}" STREQUAL Windows AND "${CMAKE_C_COMPILER_ID}" STREQUAL MSVC) + target_link_libraries(openmpt PRIVATE Rpcrt4) + endif() + target_compile_features(openmpt PRIVATE cxx_std_11) + target_compile_definitions(openmpt PRIVATE -DLIBOPENMPT_BUILD) + + target_include_directories(openmpt PRIVATE "${openmpt_SOURCE_DIR}/common") + target_include_directories(openmpt PRIVATE "${openmpt_SOURCE_DIR}/src") + target_include_directories(openmpt PRIVATE "${openmpt_SOURCE_DIR}/include") + target_include_directories(openmpt PRIVATE "${openmpt_SOURCE_DIR}") + target_include_directories(openmpt PRIVATE "${CMAKE_CURRENT_BINARY_DIR}") + + # I wish this wasn't necessary, but it is + target_include_directories(openmpt PUBLIC "${openmpt_SOURCE_DIR}") +endif() diff --git a/thirdparty/cpm-png.cmake b/thirdparty/cpm-png.cmake new file mode 100644 index 0000000000000000000000000000000000000000..f16ac037b0cc9c077f3ef315b67b430e68cf9b40 --- /dev/null +++ b/thirdparty/cpm-png.cmake @@ -0,0 +1,69 @@ +CPMAddPackage( + NAME png + VERSION 1.6.38 + URL "https://github.com/glennrp/libpng/archive/refs/tags/v1.6.38.zip" + # png cmake build is broken on msys/mingw32 + DOWNLOAD_ONLY YES +) + +if(png_ADDED) + # Since png's cmake build is broken, we're going to create a target manually + set( + PNG_SOURCES + png.h + pngconf.h + pngpriv.h + pngdebug.h + pnginfo.h + pngstruct.h + png.c + pngerror.c + pngget.c + pngmem.c + pngpread.c + pngread.c + pngrio.c + pngrtran.c + pngrutil.c + pngset.c + pngtrans.c + pngwio.c + pngwrite.c + pngwtran.c + pngwutil.c + ) + list(TRANSFORM PNG_SOURCES PREPEND "${png_SOURCE_DIR}/") + + add_custom_command( + OUTPUT "${png_BINARY_DIR}/include/png.h" "${png_BINARY_DIR}/include/pngconf.h" + COMMAND ${CMAKE_COMMAND} -E copy "${png_SOURCE_DIR}/png.h" "${png_SOURCE_DIR}/pngconf.h" "${png_BINARY_DIR}/include" + DEPENDS "${png_SOURCE_DIR}/png.h" "${png_SOURCE_DIR}/pngconf.h" + VERBATIM + ) + add_custom_command( + OUTPUT "${png_BINARY_DIR}/include/pnglibconf.h" + COMMAND ${CMAKE_COMMAND} -E copy "${png_SOURCE_DIR}/scripts/pnglibconf.h.prebuilt" "${png_BINARY_DIR}/include/pnglibconf.h" + DEPENDS "${png_SOURCE_DIR}/scripts/pnglibconf.h.prebuilt" + VERBATIM + ) + list( + APPEND PNG_SOURCES + "${png_BINARY_DIR}/include/png.h" + "${png_BINARY_DIR}/include/pngconf.h" + "${png_BINARY_DIR}/include/pnglibconf.h" + ) + add_library(png "${SRB2_INTERNAL_LIBRARY_TYPE}" ${PNG_SOURCES}) + + # Disable ARM NEON since having it automatic breaks libpng external build on clang for some reason + target_compile_definitions(png PRIVATE -DPNG_ARM_NEON_OPT=0) + + # The png includes need to be available to consumers + target_include_directories(png PUBLIC "${png_BINARY_DIR}/include") + + # ... and these also need to be present only for png build + target_include_directories(png PRIVATE "${ZLIB_SOURCE_DIR}") + target_include_directories(png PRIVATE "${ZLIB_BINARY_DIR}") + target_include_directories(png PRIVATE "${png_BINARY_DIR}") + target_link_libraries(png PRIVATE ZLIB::ZLIB) + add_library(PNG::PNG ALIAS png) +endif() diff --git a/thirdparty/cpm-sdl2-mixer.cmake b/thirdparty/cpm-sdl2-mixer.cmake new file mode 100644 index 0000000000000000000000000000000000000000..b7dfeae0d3eab254651f0c5e6e69e7af0626012e --- /dev/null +++ b/thirdparty/cpm-sdl2-mixer.cmake @@ -0,0 +1,22 @@ +CPMAddPackage( + NAME SDL2_mixer + VERSION 2.6.2 + URL "https://github.com/libsdl-org/SDL_mixer/archive/refs/tags/release-2.6.2.zip" + EXCLUDE_FROM_ALL ON + OPTIONS + "BUILD_SHARED_LIBS ${SRB2_CONFIG_SHARED_INTERNAL_LIBRARIES}" + "SDL2MIXER_INSTALL OFF" + "SDL2MIXER_DEPS_SHARED OFF" + "SDL2MIXER_SAMPLES OFF" + "SDL2MIXER_VENDORED ON" + "SDL2MIXER_FLAC ON" + "SDL2MIXER_FLAC_LIBFLAC OFF" + "SDL2MIXER_FLAC_DRFLAC ON" + "SDL2MIXER_MOD OFF" + "SDL2MIXER_MP3 ON" + "SDL2MIXER_MP3_DRMP3 ON" + "SDL2MIXER_MIDI ON" + "SDL2MIXER_OPUS OFF" + "SDL2MIXER_VORBIS STB" + "SDL2MIXER_WAVE ON" +) diff --git a/thirdparty/cpm-sdl2.cmake b/thirdparty/cpm-sdl2.cmake new file mode 100644 index 0000000000000000000000000000000000000000..58cf9afc2a8c9f443379625049ebd28446382b84 --- /dev/null +++ b/thirdparty/cpm-sdl2.cmake @@ -0,0 +1,13 @@ +CPMAddPackage( + NAME SDL2 + VERSION 2.24.2 + URL "https://github.com/libsdl-org/SDL/archive/refs/tags/release-2.24.2.zip" + EXCLUDE_FROM_ALL ON + OPTIONS + "BUILD_SHARED_LIBS ${SRB2_CONFIG_SHARED_INTERNAL_LIBRARIES}" + "SDL_SHARED ${SRB2_CONFIG_SHARED_INTERNAL_LIBRARIES}" + "SDL_STATIC ${NOT_SRB2_CONFIG_SHARED_INTERNAL_LIBRARIES}" + "SDL_TEST OFF" + "SDL2_DISABLE_SDL2MAIN ON" + "SDL2_DISABLE_INSTALL ON" +) diff --git a/thirdparty/cpm-zlib.cmake b/thirdparty/cpm-zlib.cmake new file mode 100644 index 0000000000000000000000000000000000000000..5368366fd14a4246da476e48bb98ce708812646e --- /dev/null +++ b/thirdparty/cpm-zlib.cmake @@ -0,0 +1,53 @@ +CPMAddPackage( + NAME ZLIB + VERSION 1.2.13 + URL "https://github.com/madler/zlib/archive/refs/tags/v1.2.13.zip" + EXCLUDE_FROM_ALL + DOWNLOAD_ONLY YES +) + +if(ZLIB_ADDED) + set(ZLIB_SRCS + crc32.h + deflate.h + gzguts.h + inffast.h + inffixed.h + inflate.h + inftrees.h + trees.h + zutil.h + adler32.c + compress.c + crc32.c + deflate.c + gzclose.c + gzlib.c + gzread.c + gzwrite.c + inflate.c + infback.c + inftrees.c + inffast.c + trees.c + uncompr.c + zutil.c + ) + list(TRANSFORM ZLIB_SRCS PREPEND "${ZLIB_SOURCE_DIR}/") + + configure_file("${ZLIB_SOURCE_DIR}/zlib.pc.cmakein" "${ZLIB_BINARY_DIR}/zlib.pc" @ONLY) + configure_file("${ZLIB_SOURCE_DIR}/zconf.h.cmakein" "${ZLIB_BINARY_DIR}/include/zconf.h" @ONLY) + configure_file("${ZLIB_SOURCE_DIR}/zlib.h" "${ZLIB_BINARY_DIR}/include/zlib.h" @ONLY) + + add_library(ZLIB ${SRB2_INTERNAL_LIBRARY_TYPE} ${ZLIB_SRCS}) + set_target_properties(ZLIB PROPERTIES + VERSION 1.2.13 + OUTPUT_NAME "z" + ) + target_include_directories(ZLIB PRIVATE "${ZLIB_SOURCE_DIR}") + target_include_directories(ZLIB PUBLIC "${ZLIB_BINARY_DIR}/include") + if(MSVC) + target_compile_definitions(ZLIB PRIVATE -D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE) + endif() + add_library(ZLIB::ZLIB ALIAS ZLIB) +endif() diff --git a/tools/anglechk.c b/tools/anglechk.c index 4a67069bf744772082afeac5d8875991f2075903..7f56abff7e56336090af76e81335d76951dcec39 100644 --- a/tools/anglechk.c +++ b/tools/anglechk.c @@ -22,7 +22,6 @@ #ifdef _MSC_VER #include <assert.h> #endif -#define NOASM #include "../src/tables.h" #define NO_M #include "../src/m_fixed.c"